Connexion à l'aide de l'authentification IAM pour les bases de données

Cette page explique comment les utilisateurs et les comptes de service peuvent se connecter aux bases de données Cloud SQL à l'aide de l'authentification IAM pour les bases de données Cloud SQL. Pour en savoir plus, consultez la section Authentification IAM.

Avant de commencer

Se connecter à l'aide de l'authentification IAM automatique pour les bases de données

Vous pouvez configurer un connecteur Cloud SQL pour gérer automatiquement l'authentification auprès de l'instance Cloud SQL au nom d'un utilisateur ou d'une application. Les connecteurs incluent le proxy d'authentification Cloud SQL, le connecteur Go, le connecteur Java et le connecteur Python, qui sont tous compatibles avec l'authentification IAM automatique des bases de données. Lorsque vous utilisez un connecteur Cloud SQL avec l'authentification IAM automatique pour les bases de données, le compte IAM que vous utilisez pour démarrer le connecteur doit être le même que celui qui s'authentifie auprès de la base de données.

Pour vous connecter à l'aide de l'authentification IAM automatique pour les bases de données, procédez comme suit :

Proxy d'authentification Cloud SQL

  1. Authentifiez-vous sur Google Cloud.

    Utilisateur

    Authentifiez-vous sur Google Cloud à l'aide des identifiants par défaut de l'application (ADC).

    Exécutez la commande gcloud auth application-default login. Pour en savoir plus, consultez la page Configurer les identifiants par défaut de l'application.

    Compte de service

    Pour vous authentifier auprès de Google Cloud à l'aide des ADC avec un compte de service, vous pouvez emprunter l'identité d'un compte de service ou configurer une clé de compte de service. Si vous souhaitez vous authentifier avec l'identité de compte de service empruntée, remplacez SERVICE_ACCOUNT_EMAIL_ADDRESS et exécutez la commande suivante :

    gcloud auth application-default login --impersonate-service-account SERVICE_ACCOUNT_EMAIL_ADDRESS
    

    Pour en savoir plus, consultez la page Configurer les identifiants par défaut de l'application.

  2. Démarrez le proxy d'authentification Cloud SQL avec l'option --auto-iam-authn. Remplacez INSTANCE_CONNECTION_NAME par la chaîne de connexion utilisée pour identifier l'instance Cloud SQL. Si vous utilisez un port autre que le port MySQL par défaut, spécifiez le numéro de port. Pour savoir comment trouver et construire cette chaîne, consultez la section Options d'authentification du proxy d'authentification Cloud SQL.

    ./cloud-sql-proxy --auto-iam-authn INSTANCE_CONNECTION_NAME
    

    Pour en savoir plus sur le démarrage du proxy, consultez la section Démarrer le proxy d'authentification Cloud SQL.

  3. Lorsque vous êtes prêt à vous connecter à l'instance à l'aide du proxy d'authentification Cloud SQL, connectez-vous avec le client mysql. Remplacez les éléments suivants :

    • HOSTNAME : adresse IP utilisée par le proxy d'authentification Cloud SQL. Par défaut, le proxy d'authentification Cloud SQL utilise l'adresse localhost de 127.0.0.1, mais vous pouvez attribuer une adresse IP différente lorsque vous démarrez le proxy d'authentification Cloud SQL.
    • USERNAME : pour un compte utilisateur IAM, il s'agit de l'adresse e-mail de l'utilisateur, sans le symbole @ ni le nom de domaine. Par exemple, pour test-user@example.com, saisissez test-user. Pour un compte de service, il s'agit de l'adresse e-mail du compte de service sans le suffixe @project-id.iam.gserviceaccount.com.
    • PORT_NUMBER : facultatif. Si vous avez spécifié un autre port dans la chaîne de connexion de l'instance, spécifiez ce numéro de port.

    Exécutez la commande suivante :

    mysql --host=HOSTNAME \
    --user=USERNAME \
    --port=PORT_NUMBER
    

    Pour en savoir plus sur la connexion au proxy d'authentification Cloud SQL, consultez la section Se connecter à l'aide du client mysql.

Go

import (
	"context"
	"database/sql"
	"fmt"
	"log"
	"net"
	"os"

	"cloud.google.com/go/cloudsqlconn"
	"github.com/go-sql-driver/mysql"
)

func connectWithConnectorIAMAuthN() (*sql.DB, error) {
	mustGetenv := func(k string) string {
		v := os.Getenv(k)
		if v == "" {
			log.Fatalf("Warning: %s environment variable not set.", k)
		}
		return v
	}
	// Note: Saving credentials in environment variables is convenient, but not
	// secure - consider a more secure solution such as
	// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
	// keep secrets safe.
	var (
		dbUser                 = mustGetenv("DB_IAM_USER")              // e.g. 'service-account-name'
		dbName                 = mustGetenv("DB_NAME")                  // e.g. 'my-database'
		instanceConnectionName = mustGetenv("INSTANCE_CONNECTION_NAME") // e.g. 'project:region:instance'
		usePrivate             = os.Getenv("PRIVATE_IP")
	)

	d, err := cloudsqlconn.NewDialer(context.Background(), cloudsqlconn.WithIAMAuthN())
	if err != nil {
		return nil, fmt.Errorf("cloudsqlconn.NewDialer: %w", err)
	}
	var opts []cloudsqlconn.DialOption
	if usePrivate != "" {
		opts = append(opts, cloudsqlconn.WithPrivateIP())
	}
	mysql.RegisterDialContext("cloudsqlconn",
		func(ctx context.Context, addr string) (net.Conn, error) {
			return d.Dial(ctx, instanceConnectionName, opts...)
		})

	dbURI := fmt.Sprintf("%s:empty@cloudsqlconn(localhost:3306)/%s?parseTime=true",
		dbUser, dbName)

	dbPool, err := sql.Open("mysql", dbURI)
	if err != nil {
		return nil, fmt.Errorf("sql.Open: %w", err)
	}
	return dbPool, nil
}

Java JDBC

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;

public class ConnectorIamAuthnConnectionPoolFactory extends ConnectionPoolFactory {

  // Note: Saving credentials in environment variables is convenient, but not
  // secure - consider a more secure solution such as
  // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  // keep secrets safe.
  private static final String INSTANCE_CONNECTION_NAME =
      System.getenv("INSTANCE_CONNECTION_NAME");
  private static final String INSTANCE_UNIX_SOCKET = System.getenv("INSTANCE_UNIX_SOCKET");
  private static final String DB_IAM_USER = System.getenv("DB_IAM_USER");
  private static final String DB_NAME = System.getenv("DB_NAME");

  public static DataSource createConnectionPool() {
    // The configuration object specifies behaviors for the connection pool.
    HikariConfig config = new HikariConfig();

    // The following URL is equivalent to setting the config options below:
    // jdbc:mysql:///<DB_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&
    // socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=<DB_USER>&password=<DB_PASS>
    // See the link below for more info on building a JDBC URL for the Cloud SQL JDBC Socket Factory
    // https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#creating-the-jdbc-url

    // Configure which instance and what database user to connect with.
    config.setJdbcUrl(String.format("jdbc:mysql:///%s", DB_NAME));

    config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory");
    config.addDataSourceProperty("cloudSqlInstance", INSTANCE_CONNECTION_NAME);

    // If connecting using automatic database authentication, follow the instructions for
    // connecting using the connector, but set the DB_IAM_USER value to an IAM user or
    // service account that has been given access to the database.
    // See https://cloud.google.com/sql/docs/postgres/iam-logins for more details.
    config.addDataSourceProperty("enableIamAuth", "true");
    config.addDataSourceProperty("user", DB_IAM_USER);
    // Explicitly set sslmode to disable to prevent driver from hanging.
    // The Java Connector will handle SSL so it is unneccesary to enable it at the driver level.
    config.addDataSourceProperty("sslmode", "disable");

    // ... Specify additional connection properties here.
    // ...

    // Initialize the connection pool using the configuration object.
    return new HikariDataSource(config);
  }
}

Java R2DBC

// Set up ConnectionFactoryOptions
ConnectionFactoryOptions options =
    ConnectionFactoryOptions.builder()
        .option(DRIVER, "gcp")
        .option(PROTOCOL, "mysql")
        .option(USER, DB_USER)
        .option(DATABASE, DB_NAME)
        .option(HOST, CONNECTION_NAME)
        .option(ENABLE_IAM_AUTH, true)
        .build();

// Initialize connection pool
ConnectionFactory connectionFactory = ConnectionFactories.get(options);
ConnectionPoolConfiguration configuration =
    ConnectionPoolConfiguration.builder(connectionFactory).build();

this.connectionPool = new ConnectionPool(configuration);

Python

import os

from google.cloud.sql.connector import Connector, IPTypes
import pymysql

import sqlalchemy

def connect_with_connector_auto_iam_authn() -> sqlalchemy.engine.base.Engine:
    """
    Initializes a connection pool for a Cloud SQL instance of MySQL.

    Uses the Cloud SQL Python Connector with Automatic IAM Database Authentication.
    """
    # Note: Saving credentials in environment variables is convenient, but not
    # secure - consider a more secure solution such as
    # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
    # keep secrets safe.
    instance_connection_name = os.environ[
        "INSTANCE_CONNECTION_NAME"
    ]  # e.g. 'project:region:instance'
    db_iam_user = os.environ["DB_IAM_USER"]  # e.g. 'service-account-name'
    db_name = os.environ["DB_NAME"]  # e.g. 'my-database'

    ip_type = IPTypes.PRIVATE if os.environ.get("PRIVATE_IP") else IPTypes.PUBLIC

    # initialize Cloud SQL Python Connector object
    connector = Connector()

    def getconn() -> pymysql.connections.Connection:
        conn: pymysql.connections.Connection = connector.connect(
            instance_connection_name,
            "pymysql",
            user=db_iam_user,
            db=db_name,
            enable_iam_auth=True,
            ip_type=ip_type,
        )
        return conn

    # The Cloud SQL Python Connector can be used with SQLAlchemy
    # using the 'creator' argument to 'create_engine'
    pool = sqlalchemy.create_engine(
        "mysql+pymysql://",
        creator=getconn,
        # ...
    )
    return pool

Se connecter à l'aide de l'authentification IAM manuelle pour les bases de données

Un utilisateur ou une application peut s'authentifier auprès de la base de données à l'aide d'IAM en demandant manuellement un jeton d'accès à Google Cloud et en le présentant à la base de données. À l'aide de gcloud CLI, vous pouvez explicitement demander un jeton OAuth 2.0 avec le champ d'application de l'API Cloud SQL Admin servant à vous connecter à la base de données. Lorsque vous vous connectez en tant qu'utilisateur de la base de données avec l'authentification IAM manuelle pour les bases de données, vous utilisez votre adresse e-mail comme nom d'utilisateur et le jeton d'accès comme mot de passe. Vous pouvez utiliser cette méthode avec une connexion directe à la base de données ou à travers un connecteur Cloud SQL.

Dans ces étapes, vous vous authentifiez auprès de Google Cloud, demandez un jeton d'accès, puis vous vous connectez à la base de données en transmettant le jeton en tant que mot de passe pour l'utilisateur IAM de la base de données. Suivez ces étapes pour vous connecter sans le proxy d'authentification Cloud SQL.

Pour réaliser ces étapes, vous devez :

Pour vous connecter à l'aide de l'authentification IAM manuelle pour les bases de données, procédez comme suit :

gcloud

  1. Authentifiez-vous sur Google Cloud.

    Utilisateur

    Authentifiez-vous auprès d'IAM en utilisant gcloud auth login. Pour en savoir plus, consultez la section Autoriser avec un compte utilisateur.

    Compte de service

    Authentifiez-vous auprès d'IAM en utilisant gcloud auth activate-service-account. Pour en savoir plus, consultez la section Autoriser avec un compte de service.

  2. Demandez le jeton d'accès et connectez-vous avec un client.

    Remplacez les éléments suivants :

    • HOSTNAME : adresse IP de l'instance (soit l'adresse IP publique, soit l'adresse IP privée).
    • USERNAME : pour un compte utilisateur IAM, il s'agit de l'adresse e-mail de l'utilisateur, sans le symbole @ ni le nom de domaine. Par exemple, pour test-user@example.com, saisissez test-user. Pour un compte de service, il s'agit de l'adresse e-mail du compte de service sans le suffixe @project-id.iam.gserviceaccount.com.

     MYSQL_PWD=`gcloud sql generate-login-token` \
     mysql --enable-cleartext-plugin \
     --ssl-mode=REQUIRED \
     --host=HOSTNAME \
     --user=USERNAME
     

    Si ssl_mode sur votre instance Cloud SQL est configuré sur TRUSTED_CLIENT_CERTIFICATE_REQUIRED, incluez un certificat et une clé client lorsque vous vous connectez. En outre, pour permettre au client de valider l'identité du serveur pour l'authentification mutuelle, spécifiez le certificat de serveur server-ca.pem. Exemple :

     MYSQL_PWD=`gcloud sql generate-login-token` \
     mysql --enable-cleartext-plugin \
     --ssl-mode=VERIFY_CA \
     --ssl-ca=server-ca.pem \
     --ssl-cert=client-cert.pem \
     --ssl-key=client-key.pem \
     --host=HOSTNAME \
     --user=USERNAME
     

    Pour en savoir plus sur la création d'un certificat et d'une clé client, consultez la section Certificats clients.

Étapes suivantes