Accesso a un database con l'autenticazione IAM dei database

Questa pagina descrive come gli utenti e gli account di servizio possono accedere ai database Cloud SQL utilizzando l'autenticazione IAM del database Cloud SQL. Per ulteriori informazioni, consulta Autenticazione IAM.

Prima di iniziare

Accedi con l'autenticazione automatica del database IAM

Puoi configurare un connettore Cloud SQL per gestire automaticamente l'autenticazione dell'istanza Cloud SQL per conto di un utente o di un'applicazione. I connettori includono il proxy di autenticazione Cloud SQL, il connettore Go, il connettore Java e il connettore Python, che supportano tutti l'autenticazione automatica del database IAM. Se utilizzi un connettore Cloud SQL con autenticazione automatica del database IAM, l'account IAM utilizzato per avviare il connettore deve essere lo stesso che autentica il database.

Per accedere utilizzando l'autenticazione automatica del database IAM:

Proxy di autenticazione Cloud SQL

  1. Autenticazione in Google Cloud.

    User

    Esegui l'autenticazione in Google Cloud utilizzando le Credenziali predefinite dell'applicazione (ADC).

    Utilizza il comando gcloud auth application-default login. Per maggiori informazioni, consulta Configurare le credenziali predefinite dell'applicazione.

    Account di servizio

    Per eseguire l'autenticazione in Google Cloud utilizzando ADC con un account di servizio, puoi utilizzare la simulazione dell'identità degli account di servizio o una chiave dell'account di servizio. Per utilizzare la simulazione dell'identità degli account di servizio, sostituisci SERVICE_ACCOUNT_EMAIL_ADDRESS ed esegui questo comando:

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

    Per maggiori informazioni, consulta Configurare le credenziali predefinite dell'applicazione.

  2. Avvia il proxy di autenticazione Cloud SQL con il flag --auto-iam-authn.

    Sostituisci quanto segue:

    • INSTANCE_CONNECTION_NAME: la stringa di connessione per identificare un'istanza Cloud SQL. Se utilizzi una porta diversa da quella predefinita per PostgreSQL, specifica il numero di porta. Per maggiori informazioni su come trovare e creare questa stringa, consulta Opzioni per l'autenticazione del proxy di autenticazione Cloud SQL.
    ./cloud-sql-proxy --auto-iam-authn INSTANCE_CONNECTION_NAME
    

    Per ulteriori informazioni su come avviare il proxy, vedi Avviare il proxy di autenticazione Cloud SQL.

  3. Quando è tutto pronto per connetterti all'istanza utilizzando il proxy di autenticazione Cloud SQL, accedi con il client psql.

    Sostituisci quanto segue:

    • HOSTNAME: indirizzo IP utilizzato dal proxy di autenticazione Cloud SQL. Per impostazione predefinita, il proxy di autenticazione Cloud SQL utilizza l'indirizzo localhost di 127.0.0.1, ma puoi assegnare un indirizzo IP diverso quando avvii il proxy di autenticazione Cloud SQL.
    • USERNAME: per un account IAM, il nome utente è l'indirizzo email completo dell'utente. Per un account di servizio, si tratta dell'indirizzo email dell'account di servizio senza il suffisso di dominio .gserviceaccount.com.
    • PORT_NUMBER: facoltativo. Se hai specificato una porta diversa nella stringa di connessione dell'istanza, specifica quel numero di porta.
    • DATABASE_NAME: il nome del database a cui connettersi.

    Esegui questo comando:

    psql -h HOSTNAME \
     -U USERNAME \
     --port PORT_NUMBER \
     --dbname=DATABASE_NAME
     

    Per maggiori informazioni su come connettersi al proxy di autenticazione Cloud SQL, consulta Connessione al client psql.

Go

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

	"cloud.google.com/go/cloudsqlconn"
	"github.com/jackc/pgx/v5"
	"github.com/jackc/pgx/v5/stdlib"
)

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@project-id.iam'
		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())
	}

	dsn := fmt.Sprintf("user=%s database=%s", dbUser, dbName)
	config, err := pgx.ParseConfig(dsn)
	if err != nil {
		return nil, err
	}

	config.DialFunc = func(ctx context.Context, network, instance string) (net.Conn, error) {
		return d.Dial(ctx, instanceConnectionName, opts...)
	}
	dbURI := stdlib.RegisterConnConfig(config)
	dbPool, err := sql.Open("pgx", dbURI)
	if err != nil {
		return nil, fmt.Errorf("sql.Open: %w", err)
	}
	return dbPool, nil
}

JDBC 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 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:postgresql:///<DB_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&
    // socketFactory=com.google.cloud.sql.postgres.SocketFactory&user=<DB_IAM_USER>&
    // password=password
    // 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 to connect with.
    config.setJdbcUrl(String.format("jdbc:postgresql:///%s", DB_NAME));

    config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.postgres.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);
    // Password must be set to a nonempty value to bypass driver validation errors.
    config.addDataSourceProperty("password", "password");
    // 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);
  }
}

R2DBC Java

private static final String CONNECTION_NAME = System.getenv("POSTGRES_IAM_CONNECTION_NAME");
private static final String DB_NAME = System.getenv("POSTGRES_DB");
private static final String DB_USER = System.getenv("POSTGRES_IAM_USER");
  // Set up ConnectionFactoryOptions
  ConnectionFactoryOptions options =
      ConnectionFactoryOptions.builder()
          .option(DRIVER, "gcp")
          .option(PROTOCOL, "postgresql")
          // Password must be set to a nonempty value to bypass driver validation errors
          .option(PASSWORD, "password")
          .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 pg8000

import sqlalchemy

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

    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. 'sa-name@project-id.iam'
    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() -> pg8000.dbapi.Connection:
        conn: pg8000.dbapi.Connection = connector.connect(
            instance_connection_name,
            "pg8000",
            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(
        "postgresql+pg8000://",
        creator=getconn,
        # ...
    )
    return pool

Accedi con l'autenticazione manuale del database IAM

Un utente o un'applicazione possono eseguire l'autenticazione nel database utilizzando IAM richiedendo manualmente un token di accesso a Google Cloud e presentandolo nel database. Con gcloud CLI, puoi richiedere esplicitamente un token OAuth 2.0 con l'ambito dell'API Cloud SQL Admin utilizzato per accedere al database. Quando accedi come utente del database con autenticazione manuale del database IAM, utilizzi il tuo indirizzo email come nome utente e il token di accesso come password. Puoi utilizzare questo metodo con una connessione diretta al database o con un connettore Cloud SQL.

In questa procedura, dovrai eseguire l'autenticazione su Google Cloud, richiedere un token di accesso e quindi connetterti al database passando il token come password per l'utente del database IAM. Segui questi passaggi per connetterti senza il proxy di autenticazione Cloud SQL.

Per eseguire questi passaggi, devi:

  • Se ti stai connettendo a un'istanza con IP pubblico, autorizza l'accesso esterno all'istanza. Per maggiori informazioni, consulta Autorizzare l'indirizzo IP della tua macchina per l'IP pubblico.
  • Se ti connetti a un'istanza con IP privato, esegui il comando all'interno della rete Virtual Private Cloud (VPC).
  • Utilizza il comando gcloud sql generate-login-token per generare il token di autenticazione.
  • Per accedere utilizzando l'autenticazione manuale del database IAM:

    gcloud

    1. Autenticazione in Google Cloud.

      User

      Esegui l'autenticazione in IAM utilizzando gcloud auth login. Per saperne di più, consulta Autorizzare un account utente.

      Account di servizio

      Esegui l'autenticazione in IAM utilizzando gcloud auth activate-service-account. Per maggiori informazioni, consulta Autorizzare con un account di servizio.

    2. Richiedi il token di accesso e accedi con un client.

      Sostituisci quanto segue:

      • HOSTNAME: l'indirizzo IP dell'istanza, ovvero l'indirizzo IP pubblico o l'indirizzo IP privato.
      • USERNAME: per un account IAM, il nome utente è l'indirizzo email completo dell'utente. Per un account di servizio, si tratta dell'indirizzo email dell'account di servizio senza il suffisso di dominio .gserviceaccount.com.
      • DATABASE_NAME: il nome del database a cui connettersi.

       PGPASSWORD=`gcloud sql generate-login-token` \
       psql "sslmode=require \
       hostaddr=HOSTNAME \
       user=USERNAME \
       dbname=DATABASE_NAME" \
       --no-password
       

      Se ssl_mode sulla tua istanza Cloud SQL è configurato su TRUSTED_CLIENT_CERTIFICATE_REQUIRED, ti consigliamo di accedere con l'autenticazione automatica del database IAM per applicare la convalida dell'identità client.

    Passaggi successivi