Fazer login usando a autenticação do banco de dados do IAM

Nesta página, descrevemos como usuários e contas de serviço podem fazer login nos bancos de dados do Cloud SQL usando a autenticação de banco de dados do Cloud SQL IAM. Para mais informações, consulte Autenticação do IAM.

Antes de começar

Fazer login com autenticação automática do banco de dados do IAM

É possível configurar um conector do Cloud SQL para processar automaticamente a autenticação na instância do Cloud SQL em nome de um usuário ou um aplicativo. Os conectores incluem o proxy do Cloud SQL Auth, o conector Go, o conector Java e o conector Python, todos compatíveis com a autenticação automática de banco de dados do IAM. Ao usar um conector do Cloud SQL com autenticação automática do banco de dados do IAM, a conta do IAM usada para iniciar o conector precisa ser a mesma autenticada no banco de dados.

Para fazer login com a autenticação automática de banco de dados do IAM, faça o seguinte:

Proxy de autenticação do Cloud SQL

  1. Faça a autenticação no Google Cloud.

    Usuário

    Faça a autenticação no Google Cloud usando o Application Default Credentials (ADC).

    Use o comando gcloud auth application-default login. Para mais informações, consulte Configurar o Application Default Credentials.

    Conta de serviço

    Para autenticar no Google Cloud usando o ADC com uma conta de serviço, use a identidade temporária uma conta de serviço ou configure uma chave de conta de serviço. Se você quiser autenticar com a representação de conta de serviço, substitua SERVICE_ACCOUNT_EMAIL_ADDRESS e execute o seguinte comando:

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

    Para mais informações, consulte Configurar o Application Default Credentials.

  2. Inicie o proxy do Cloud SQL Auth com a sinalização --auto-iam-authn. Substitua INSTANCE_CONNECTION_NAME pela string de conexão usada para identificar a instância do Cloud SQL. Se você estiver usando uma porta diferente da padrão do MySQL, especifique o número da porta. Para mais informações sobre como encontrar e construir essa string, consulte Opções para autenticar o proxy do Cloud SQL Auth.

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

    Para mais informações sobre como iniciar o proxy, consulte Iniciar o proxy do Cloud SQL Auth.

  3. Quando estiver tudo pronto para se conectar à instância usando o proxy do Cloud SQL Auth, faça login com o cliente mysql. Substitua:

    • HOSTNAME: endereço IP usado pelo proxy do Cloud SQL Auth. Por padrão, o proxy do Cloud SQL Auth usa o endereço localhost de 127.0.0.1, mas é possível atribuir um endereço IP diferente ao iniciar o proxy do Cloud SQL Auth.
    • USERNAME: para uma conta de usuário do IAM, este é o endereço de e-mail do usuário, sem o @ ou o nome de domínio. Por exemplo, para test-user@example.com, digite test-user. Para uma conta de serviço, esse é o endereço de e-mail da conta de serviço sem o sufixo @project-id.iam.gserviceaccount.com.
    • PORT_NUMBER: opcional. Se você especificou uma porta diferente na string de conexão da instância, especifique o número da porta.

    Execute este comando:

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

    Para mais informações sobre como se conectar ao proxy do Cloud SQL Auth, consulte Conectar-se com o cliente 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
}

JDBC do Java

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

Fazer login com autenticação do banco de dados do IAM

Um usuário ou aplicativo pode se autenticar no banco de dados usando o IAM solicitando manualmente um token de acesso do Google Cloud e apresentando-o ao banco de dados. Com a gcloud CLI, é possível solicitar explicitamente um token OAuth 2.0 com o escopo da API Cloud SQL Admin usado para fazer login no banco de dados. Ao fazer login como usuário do banco de dados com a autenticação do banco de dados do IAM, use o endereço de e-mail como nome de usuário e o token de acesso como senha. Use esse método com uma conexão direta com o banco de dados ou com um conector do Cloud SQL.

Nessas etapas, você faz a autenticação no Google Cloud, solicita um token de acesso e se conecta ao banco de dados passando o token como a senha do usuário do banco de dados do IAM. Use estas etapas para se conectar sem o proxy Auth do Cloud SQL.

Para essas etapas, você precisa:

Para fazer login com a autenticação automática de banco de dados do IAM, faça o seguinte:

gcloud

  1. Faça a autenticação no Google Cloud.

    Usuário

    Autentique-se no IAM usando gcloud auth login. Para mais informações, consulte Autorizar com uma conta de usuário.

    Conta de serviço

    Autentique-se no IAM usando gcloud auth activate-service-account. Para mais informações, consulte Autorizar com uma conta de serviço.

  2. Solicite o token de acesso e faça login com um cliente.

    Substitua:

    • HOSTNAME: o endereço IP da instância, o endereço IP público ou particular.
    • USERNAME: para uma conta de usuário do IAM, este é o endereço de e-mail do usuário, sem o símbolo @ ou o nome de domínio. Por exemplo, para test-user@example.com, digite test-user. Para uma conta de serviço, esse é o endereço de e-mail da conta de serviço sem o sufixo @project-id.iam.gserviceaccount.com.

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

    Se o ssl_mode na instância do Cloud SQL estiver configurado para TRUSTED_CLIENT_CERTIFICATE_REQUIRED, inclua um certificado e uma chave de cliente ao fazer login. Além disso, para permitir que o cliente verifique a identidade do servidor para autenticação mútua, especifique o certificado do servidor server-ca.pem. Exemplo:

     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
     

    Para mais informações sobre como criar uma chave e um certificado do cliente, consulte Certificados do cliente.

A seguir