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

  • Configure a instância para usar a autenticação do banco de dados do IAM. Para mais informações, consulte Configurar novas instâncias para a autenticação do banco de dados do IAM.
  • Adicione um usuário, uma conta de serviço ou um grupo do IAM ao banco de dados. Para mais informações, consulte Adicionar um usuário do IAM ou uma conta de serviço ao banco de dados e Adicionar um grupo ao banco de dados.
  • Adicione o papel roles/cloudsql.instanceUser do IAM ao usuário, à conta de serviço ou ao grupo do IAM. É um papel predefinido que contém a permissão IAM cloudsql.instances.login do Cloud SQL necessária. Você precisa dessa permissão para fazer login em uma instância de banco de dados com a autenticação de banco de dados do IAM. Para mais informações, consulte Papéis e permissões.
  • Se você estiver usando o Cloud SQL Auth Proxy, adicione o papel do IAM roles/cloudsql.client ao usuário, à conta de serviço ou ao grupo do IAM. É um papel predefinido que contém a permissão cloudsql.instances.connect do IAM do Cloud SQL necessária. Você precisa dessa permissão para fazer login em uma instância de banco de dados com o proxy de autenticação do Cloud SQL. Para mais informações, consulte Papéis e permissões.
  • Por padrão, quando um usuário do IAM é adicionado a um banco de dados, o novo usuário não tem privilégios para nenhum banco de dados. Use o comando GRANT para dar ao usuário do banco de dados do IAM as permissões necessárias. Para mais informações, consulte Conceder privilégios de banco de dados ao usuário do IAM e Conceder privilégios de banco de dados a um grupo.

  • Se você estiver usando a autenticação de grupo do IAM, o usuário ou a conta de serviço do IAM precisará ser membro de um grupo que recebeu permissões ou um papel do IAM para fazer login na instância do Cloud SQL. O Cloud SQL cria uma conta depois que o usuário ou a conta de serviço faz login na instância pela primeira vez.

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. Autentique-se em Google Cloud.

    User

    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 de 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")
	)

	// WithLazyRefresh() Option is used to perform refresh
	// when needed, rather than on a scheduled interval.
	// This is recommended for serverless environments to
	// avoid background refreshes from throttling CPU.
	d, err := cloudsqlconn.NewDialer(
		context.Background(),
		cloudsqlconn.WithIAMAuthN(),
		cloudsqlconn.WithLazyRefresh(),
	)
	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");

    // cloudSqlRefreshStrategy set to "lazy" is used to perform a
    // refresh when needed, rather than on a scheduled interval.
    // This is recommended for serverless environments to
    // avoid background refreshes from throttling CPU.
    config.addDataSourceProperty("cloudSqlRefreshStrategy", "lazy");


    // ... 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(IP_TYPES, IP_TYPE)
        .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(refresh_strategy="LAZY")

    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 de 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. Autentique-se em Google Cloud.

    User

    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. Por 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