Login menggunakan autentikasi database IAM

Halaman ini menjelaskan cara pengguna dan akun layanan dapat login ke database Cloud SQL menggunakan autentikasi database IAM Cloud SQL. Untuk mengetahui informasi lebih lanjut, lihat autentikasi IAM.

Sebelum memulai

Login dengan autentikasi database IAM otomatis

Anda dapat mengonfigurasi konektor Cloud SQL agar secara otomatis menangani autentikasi ke instance Cloud SQL atas nama pengguna atau aplikasi. Konektor mencakup Proxy Auth Cloud SQL, konektor Go, konektor Java, dan konektor Python, yang semuanya mendukung autentikasi database IAM otomatis. Saat menggunakan konektor Cloud SQL dengan autentikasi database IAM otomatis, akun IAM yang Anda gunakan untuk memulai konektor harus akun yang sama saat mengautentikasi database.

Untuk login menggunakan autentikasi database IAM otomatis:

Proxy Auth Cloud SQL

  1. Lakukan autentikasi ke Google Cloud.

    User

    Melakukan autentikasi ke Google Cloud menggunakan Kredensial Default Aplikasi (ADC).

    Gunakan perintah gcloud auth application-default login. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan Kredensial Default Aplikasi.

    Service account

    Untuk melakukan autentikasi ke Google Cloud menggunakan ADC dengan akun layanan, Anda dapat menggunakan peniruan akun layanan atau menggunakan kunci akun layanan. Untuk menggunakan peniruan akun layanan, ganti SERVICE_ACCOUNT_EMAIL_ADDRESS, dan jalankan perintah berikut:

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

    Untuk mengetahui informasi selengkapnya, lihat Menyiapkan Kredensial Default Aplikasi.

  2. Mulai Proxy Auth Cloud SQL dengan flag --auto-iam-authn.

    Ganti kode berikut:

    • INSTANCE_CONNECTION_NAME: String koneksi untuk mengidentifikasi instance Cloud SQL. Jika Anda menggunakan port selain port PostgreSQL default, tentukan nomor port-nya. Untuk mengetahui informasi lebih lanjut mengenai cara menemukan dan membuat string ini, lihat Opsi untuk mengautentikasi Proxy Auth Cloud SQL.
    ./cloud-sql-proxy --auto-iam-authn INSTANCE_CONNECTION_NAME

    Untuk mengetahui informasi selengkapnya tentang cara memulai proxy, lihat Memulai Proxy Auth Cloud SQL.

  3. Setelah Anda siap untuk terhubung ke instance dengan menggunakan Proxy Auth Cloud SQL, login dengan klien psql.

    Ganti kode berikut:

    • HOSTNAME: Alamat IP yang digunakan oleh Auth Proxy Cloud SQL. Secara default, Proxy Auth Cloud SQL menggunakan alamat localhost 127.0.0.1, tetapi Anda dapat menetapkan alamat IP yang berbeda saat memulai Proxy Auth Cloud SQL.
    • USERNAME: Untuk IAM, nama pengguna adalah alamat email lengkap pengguna. Untuk akun layanan, ini adalah email akun layanan tanpa akhiran domain .gserviceaccount.com.
    • PORT_NUMBER: Opsional. Jika Anda menentukan port yang berbeda dalam string koneksi instance, tentukan nomor port tersebut.
    • DATABASE_NAME: Nama database yang akan dihubungkan.

    Jalankan perintah berikut:

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

    Untuk informasi selengkapnya tentang cara menghubungkan ke Proxy Auth Cloud SQL, lihat Menghubungkan dengan klien 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

Login dengan autentikasi database IAM manual

Pengguna atau aplikasi dapat melakukan autentikasi ke database menggunakan IAM dengan meminta token akses secara manual dari Google Cloud dan menyajikannya ke database. Dengan menggunakan gcloud CLI, Anda dapat secara eksplisit meminta token OAuth 2.0 dengan cakupan Cloud SQL Admin API yang digunakan untuk login ke database. Ketika Anda login sebagai pengguna database dengan autentikasi database IAM manual, Anda menggunakan alamat email Anda sebagai nama pengguna dan token akses sebagai sandinya. Anda dapat menggunakan metode ini dengan koneksi langsung ke database atau dengan konektor Cloud SQL.

Dalam prosedur ini, Anda melakukan autentikasi ke Google Cloud, meminta token akses, dan kemudian terhubung ke database dengan meneruskan token sebagai sandi untuk pengguna database IAM. Gunakan langkah-langkah ini untuk terhubung tanpa Proxy Auth Cloud SQL.

Untuk langkah-langkah ini, Anda harus:

  • Jika Anda terhubung ke instance dengan IP publik, izinkan akses eksternal ke instance tersebut. Untuk mengetahui informasi selengkapnya, lihat Mengotorisasi alamat IP komputer Anda untuk IP publik.
  • Jika Anda terhubung ke instance dengan IP pribadi, jalankan perintah dalam jaringan Virtual Private Cloud (VPC).
  • Gunakan perintah gcloud sql generate-login-token untuk membuat token autentikasi.
  • Untuk login menggunakan autentikasi database IAM manual:

    gcloud

    1. Lakukan autentikasi ke Google Cloud.

      Pengguna

      Lakukan autentikasi ke IAM menggunakan gcloud auth login. Untuk mengetahui informasi selengkapnya, lihat Memberikan otorisasi dengan akun pengguna.

      Service account

      Lakukan autentikasi ke IAM menggunakan gcloud auth activate-service-account. Untuk mengetahui informasi selengkapnya, lihat Memberikan otorisasi dengan akun layanan.

    2. Minta token akses, dan login dengan klien.

      Ganti kode berikut:

      • HOSTNAME: Alamat IP instance, baik alamat IP publik maupun alamat IP pribadi.
      • USERNAME: Untuk IAM, nama pengguna adalah alamat email lengkap pengguna. Untuk akun layanan, ini adalah email akun layanan tanpa akhiran domain .gserviceaccount.com.
      • DATABASE_NAME: Nama database yang akan dihubungkan.

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

      Jika ssl_mode pada instance Cloud SQL Anda dikonfigurasi ke TRUSTED_CLIENT_CERTIFICATE_REQUIRED, sebaiknya login dengan autentikasi database IAM otomatis untuk menerapkan validasi identitas klien.

    Langkah selanjutnya