alloydbconn

package module
v1.18.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 24, 2026 License: Apache-2.0 Imports: 32 Imported by: 28

README

alloydb-go-connector image

AlloyDB Go Connector

CI Go Reference

The AlloyDB Go Connector is the recommended way to connect to AlloyDB from Go applications. It provides:

  • Secure connections — TLS 1.3 encryption and identity verification, independent of the database protocol
  • IAM-based authorization — controls who can connect to your AlloyDB instances using Google Cloud IAM
  • No certificate management — no SSL certificates, firewall rules, or IP allowlisting required
  • IAM database authentication — optional support for automatic IAM DB authentication

Quick Start

Install the module:

go get cloud.google.com/go/alloydbconn

Connect using the standard database/sql package:

package main

import (
    "database/sql"
    "fmt"
    "log"

    "cloud.google.com/go/alloydbconn/driver/pgxv5"
)

func main() {
    // Register the AlloyDB driver with the name "alloydb"
    // Uses Private IP by default. See Network Options below for details.
    cleanup, err := pgxv5.RegisterDriver("alloydb")
    if err != nil {
        log.Fatal(err)
    }
    defer cleanup()

    // Instance URI format:
    //   projects/PROJECT/locations/REGION/clusters/CLUSTER/instances/INSTANCE
    db, err := sql.Open("alloydb", fmt.Sprintf(
        "host=%s user=%s password=%s dbname=%s sslmode=disable",
        "projects/my-project/locations/us-central1/clusters/my-cluster/instances/my-instance",
        "my-user",
        "my-password",
        "my-db",
    ))
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    var greeting string
    if err := db.QueryRow("SELECT 'Hello, AlloyDB!'").Scan(&greeting); err != nil {
        log.Fatal(err)
    }
    fmt.Println(greeting)
}

The connector uses Application Default Credentials (ADC) automatically. For local development, run:

gcloud auth application-default login

Table of Contents

Prerequisites

IAM Permissions

The IAM principal (user or service account) making connections needs:

  • AlloyDB Client role (roles/alloydb.client)
  • Service Usage Consumer role (roles/serviceusage.serviceUsageConsumer)
Enable the AlloyDB API

Enable the AlloyDB API in your Google Cloud project.

Credentials

The connector uses Application Default Credentials (ADC)this is the recommended approach for most applications. ADC automatically finds credentials from the environment:

  • Local development: run gcloud auth application-default login once
  • Google Cloud (Compute Engine, Cloud Run, GKE, etc.): credentials are picked up automatically from the attached service account — no code changes needed
# One-time setup for local development
gcloud auth application-default login

If you need to supply credentials explicitly (e.g., in non-Google managed environments without Application Default Credentials), see the Configuring the Dialer section for less common alternatives.

Connecting with database/sql

The database/sql approach works with any library that accepts a *sql.DB.

import (
    "database/sql"
    "fmt"

    "cloud.google.com/go/alloydbconn"
    "cloud.google.com/go/alloydbconn/driver/pgxv5"
)

func connect(instURI, user, pass, dbname string) (*sql.DB, func() error, error) {
    // RegisterDriver registers the AlloyDB driver and returns a cleanup
    // function that stops background goroutines. Call cleanup when you are
    // done with the database connection to avoid a goroutine leak.
    cleanup, err := pgxv5.RegisterDriver("alloydb")
    if err != nil {
        return nil, nil, err
    }

    db, err := sql.Open("alloydb", fmt.Sprintf(
        // sslmode=disable is correct here: the connector handles TLS.
        "host=%s user=%s password=%s dbname=%s sslmode=disable",
        instURI, user, pass, dbname,
    ))
    if err != nil {
        return nil, cleanup, err
    }
    return db, cleanup, nil
}

Instance URI format: projects/PROJECT/locations/REGION/clusters/CLUSTER/instances/INSTANCE

Connecting with pgx

For direct control over connection pooling, use pgx with pgxpool:

import (
    "context"
    "fmt"
    "net"

    "cloud.google.com/go/alloydbconn"
    "github.com/jackc/pgx/v5/pgxpool"
)

func connect(ctx context.Context, instURI, user, pass, dbname string) (*pgxpool.Pool, func() error, error) {
    d, err := alloydbconn.NewDialer(ctx)
    if err != nil {
        return nil, func() error { return nil }, fmt.Errorf("failed to init dialer: %v", err)
    }
    // cleanup stops the dialer's background goroutines.
    cleanup := func() error { return d.Close() }

    config, err := pgxpool.ParseConfig(fmt.Sprintf(
        "user=%s password=%s dbname=%s sslmode=disable",
        user, pass, dbname,
    ))
    if err != nil {
        return nil, cleanup, fmt.Errorf("failed to parse config: %v", err)
    }

    // Tell pgx to use the AlloyDB connector for all connections.
    config.ConnConfig.DialFunc = func(ctx context.Context, _, _ string) (net.Conn, error) {
        return d.Dial(ctx, instURI)
    }

    pool, err := pgxpool.NewWithConfig(ctx, config)
    if err != nil {
        return nil, cleanup, fmt.Errorf("failed to connect: %v", err)
    }
    return pool, cleanup, nil
}

Network Options

AlloyDB supports three connectivity modes. The connector defaults to private IP.

Private IP (default)

Private IP requires your application to run within a VPC Network connected to your AlloyDB instance. No extra configuration is needed — the default d.Dial(ctx, instURI) call will connect over private IP.

Public IP

Pass WithPublicIP() to connect over the instance's public IP address.

With database/sql:

cleanup, err := pgxv5.RegisterDriver("alloydb",
    alloydbconn.WithDefaultDialOptions(alloydbconn.WithPublicIP()),
)

With pgx:

config.ConnConfig.DialFunc = func(ctx context.Context, _, _ string) (net.Conn, error) {
    return d.Dial(ctx, instURI, alloydbconn.WithPublicIP())
}
Private Service Connect (PSC)

Pass WithPSC() to connect via Private Service Connect.

With database/sql:

cleanup, err := pgxv5.RegisterDriver("alloydb",
    alloydbconn.WithDefaultDialOptions(alloydbconn.WithPSC()),
)

With pgx:

config.ConnConfig.DialFunc = func(ctx context.Context, _, _ string) (net.Conn, error) {
    return d.Dial(ctx, instURI, alloydbconn.WithPSC())
}

IAM Database Authentication

The connector supports Automatic IAM database authentication. With IAM auth, your application's IAM identity is used in place of a static database password.

Before you begin:

  1. Enable IAM authentication on your AlloyDB instance
  2. Add an IAM database user

Connect with IAM authentication:

// Pass WithIAMAuthN() to enable automatic IAM authentication.
cleanup, err := pgxv5.RegisterDriver("alloydb", alloydbconn.WithIAMAuthN())

Set the user field in your DSN based on your IAM identity type:

Identity type Username format
IAM user account Full email: user@example.com
Service account Email without .gserviceaccount.com: my-sa@my-project.iam
db, err := sql.Open("alloydb", fmt.Sprintf(
    // Omit the password field when using IAM authentication.
    "host=%s user=%s dbname=%s sslmode=disable",
    instURI,
    "my-sa@my-project.iam",
    dbname,
))

Configuring the Dialer

Both pgxv5.RegisterDriver and alloydbconn.NewDialer accept options to customize connector behavior.

Explicit credentials (uncommon)

Most applications should rely on Application Default Credentials and won't need these options. Use them only when ADC isn't available in your environment.

From a service account key file:

cleanup, err := pgxv5.RegisterDriver("alloydb",
    alloydbconn.WithCredentialsFile("path/to/service-account-key.json"),
)

From a credentials JSON blob:

cleanup, err := pgxv5.RegisterDriver("alloydb",
    alloydbconn.WithCredentialsJSON([]byte(`{...}`)),
)
Set default dial options

Apply options to every connection made by the dialer:

d, err := alloydbconn.NewDialer(ctx,
    alloydbconn.WithDefaultDialOptions(
        alloydbconn.WithPublicIP(),
    ),
)

For all available options, see the alloydbconn.Option reference.

Observability

The connector exports metrics and traces via OpenCensus. Configure an exporter to send telemetry to your monitoring backend.

Metrics
Metric Description
alloydbconn/dial_latency Distribution of dialer latencies (ms)
alloydbconn/open_connections Current number of open AlloyDB connections
alloydbconn/dial_failure_count Number of failed dial attempts
alloydbconn/refresh_success_count Number of successful certificate refresh operations
alloydbconn/refresh_failure_count Number of failed refresh operations
alloydbconn/bytes_sent Bytes sent to an AlloyDB instance
alloydbconn/bytes_received Bytes received from an AlloyDB instance
Traces
  • cloud.google.com/go/alloydbconn.Dial — the full dial operation
  • cloud.google.com/go/alloydbconn/internal.InstanceInfo — instance metadata retrieval
  • cloud.google.com/go/alloydbconn/internal.Connect — connection attempt using the ephemeral certificate
  • AlloyDB API client operations
Example: Cloud Monitoring and Cloud Trace
import (
    "contrib.go.opencensus.io/exporter/stackdriver"
    "go.opencensus.io/trace"
)

func main() {
    sd, err := stackdriver.NewExporter(stackdriver.Options{
        ProjectID: "my-project",
    })
    if err != nil {
        log.Fatal(err)
    }
    defer sd.Flush()

    trace.RegisterExporter(sd)
    sd.StartMetricsExporter()
    defer sd.StopMetricsExporter()

    // Use alloydbconn as usual.
}

Debug Logging

Enable debug logging to diagnose issues with the background certificate refresh. Implement the debug.ContextLogger interface and pass it to the dialer:

import (
    "context"
    "log"

    "cloud.google.com/go/alloydbconn"
)

type myLogger struct{}

func (l *myLogger) Debugf(ctx context.Context, format string, args ...interface{}) {
    log.Printf("[DEBUG] "+format, args...)
}

func connect(ctx context.Context) {
    d, err := alloydbconn.NewDialer(ctx,
        alloydbconn.WithContextDebugLogger(&myLogger{}),
    )
    // use d as usual...
}

Support Policy

Major Version Lifecycle

This project uses semantic versioning:

Stage Description
Active Receives all new features and security fixes. New major versions are guaranteed active for a minimum of 1 year.
Deprecated Receives security and critical bug fixes only. Supported for 1 year after deprecation.
Unsupported Any major version deprecated for ≥ 1 year.
Supported Go Versions

We follow the Go Version Support Policy used by Google Cloud Libraries for Go.

Release Cadence

This project aims for a monthly release cadence. If no new features or fixes are available, a patch release with updated dependencies is published.

Documentation

Overview

Package alloydbconn provides functions for authorizing and encrypting connections. These functions can be used with a database driver to connect to an AlloyDB cluster.

Creating a Dialer

To start working with this package, create a Dialer. There are two ways of creating a Dialer, which one you use depends on your database driver.

Users have the option of using the database/sql interface or using pgx directly.

To use a dialer with pgx, we recommend using connection pooling with pgxpool. To create the dialer use the NewDialer func.

import (
    "context"
    "net"

    "cloud.google.com/go/alloydbconn"
    "github.com/jackc/pgx/v5/pgxpool"
)

func connect() {
    // Configure the driver to connect to the database
    dsn := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable", pgUser, pgPass, pgDB)
    config, err := pgxpool.ParseConfig(dsn)
    if err != nil {
        log.Fatalf("failed to parse pgx config: %v", err)
    }

    // Create a new dialer with any options
    d, err := alloydbconn.NewDialer(ctx)
    if err != nil {
        log.Fatalf("failed to initialize dialer: %v", err)
    }
    defer d.Close()

    // Tell the driver to use the AlloyDB Go Connector to create connections
    config.ConnConfig.DialFunc = func(ctx context.Context, _ string, instance string) (net.Conn, error) {
        return d.Dial(ctx, "projects/<PROJECT>/locations/<REGION>/clusters/<CLUSTER>/instances/<INSTANCE>")
    }

    // Interact with the driver directly as you normally would
    conn, err := pgxpool.NewWithConfig(context.Background(), config)
    if err != nil {
        log.Fatalf("failed to connect: %v", connErr)
    }
    defer conn.Close()
}

To use database/sql, call pgxv5.RegisterDriver with any necessary Dialer configuration.

import (
    "database/sql"

    "cloud.google.com/go/alloydbconn"
    "cloud.google.com/go/alloydbconn/driver/pgxv5"
)

func connect() {
    // adjust options as needed
    cleanup, err := pgxv5.RegisterDriver("alloydb")
    if err != nil {
        // ... handle error
    }
    defer cleanup()

    db, err := sql.Open(
        "alloydb",
        "host=projects/<PROJECT>/locations/<REGION>/clusters/<CLUSTER>/instances/<INSTANCE> user=myuser password=mypass dbname=mydb sslmode=disable",
    )
    //... etc
}

Index

Constants

View Source
const (
	// CloudPlatformScope is the default OAuth2 scope set on the API client.
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
	// AlloyDBLoginScope is the OAuth2 scope used for IAM Authentication
	AlloyDBLoginScope = "https://www.googleapis.com/auth/alloydb.login"
)

Variables

View Source
var (
	// ErrDialerClosed is used when a caller invokes Dial after closing the
	// Dialer.
	ErrDialerClosed = errors.New("alloydbconn: dialer is closed")
)

Functions

This section is empty.

Types

type DialOption

type DialOption func(d *dialCfg)

A DialOption is an option for configuring how a Dialer's Dial call is executed.

func DialOptions

func DialOptions(opts ...DialOption) DialOption

DialOptions turns a list of DialOption instances into an DialOption.

func WithDialIAMAuthN added in v1.16.0

func WithDialIAMAuthN(enabled bool) DialOption

WithDialIAMAuthN allows calls to Dial to enable or disable IAM AuthN on a one-off basis, regardless whether the dialer itself is configured with IAM AuthN. There is no performance penalty to using this option.

func WithOneOffDialFunc added in v1.4.0

func WithOneOffDialFunc(dial func(ctx context.Context, network, addr string) (net.Conn, error)) DialOption

WithOneOffDialFunc configures the dial function on a one-off basis for an individual call to Dial. To configure a dial function across all invocations of Dial, use WithDialFunc.

func WithPSC added in v1.9.0

func WithPSC() DialOption

WithPSC returns a DialOption that specifies a PSC endpoint will be used to connect.

func WithPrivateIP added in v1.6.0

func WithPrivateIP() DialOption

WithPrivateIP returns a DialOption that specifies a private IP (VPC) will be used to connect.

func WithPublicIP added in v1.6.0

func WithPublicIP() DialOption

WithPublicIP returns a DialOption that specifies a public IP will be used to connect.

func WithTCPKeepAlive

func WithTCPKeepAlive(d time.Duration) DialOption

WithTCPKeepAlive returns a DialOption that specifies the tcp keep alive period for the connection returned by Dial.

type Dialer

type Dialer struct {
	// contains filtered or unexported fields
}

A Dialer is used to create connections to AlloyDB instance.

Use NewDialer to initialize a Dialer.

func NewDialer

func NewDialer(ctx context.Context, opts ...Option) (*Dialer, error)

NewDialer creates a new Dialer.

Initial calls to NewDialer make take longer than normal because generation of an RSA keypair is performed. Calls with a WithRSAKeyPair DialOption or after a default RSA keypair is generated will be faster.

func (*Dialer) Close

func (d *Dialer) Close() error

Close closes the Dialer; it prevents the Dialer from refreshing the information needed to connect.

func (*Dialer) Dial

func (d *Dialer) Dial(ctx context.Context, instance string, opts ...DialOption) (conn net.Conn, err error)

Dial returns a net.Conn connected to the specified AlloyDB instance. The instance argument must be the instance's URI, which is in the format projects/<PROJECT>/locations/<REGION>/clusters/<CLUSTER>/instances/<INSTANCE>

type Option

type Option func(d *dialerConfig)

An Option is an option for configuring a Dialer.

func WithAdminAPIEndpoint

func WithAdminAPIEndpoint(url string) Option

WithAdminAPIEndpoint configures the underlying AlloyDB Admin API client to use the provided URL.

func WithContextLogger added in v1.10.0

func WithContextLogger(l debug.ContextLogger) Option

WithContextLogger configures a debug lgoger for reporting on internal operations. By default the debug logger is disabled.

func WithCredentials added in v1.17.0

func WithCredentials(c *auth.Credentials) Option

WithCredentials returns an option that specifies an auth.Credentials object to use for all AlloyDB API interactions.

func WithCredentialsFile

func WithCredentialsFile(filename string) Option

WithCredentialsFile returns an Option that specifies a service account or refresh token JSON credentials file to be used as the basis for authentication.

func WithCredentialsJSON

func WithCredentialsJSON(b []byte) Option

WithCredentialsJSON returns an Option that specifies a service account or refresh token JSON credentials to be used as the basis for authentication.

func WithDebugLogger added in v1.8.0

func WithDebugLogger(l debug.Logger) Option

WithDebugLogger configures a debug logger for reporting on internal operations. By default the debug logger is disabled. Prefer WithContextLogger.

func WithDefaultDialOptions

func WithDefaultDialOptions(opts ...DialOption) Option

WithDefaultDialOptions returns an Option that specifies the default DialOptions used.

func WithDialFunc

func WithDialFunc(dial func(ctx context.Context, network, addr string) (net.Conn, error)) Option

WithDialFunc configures the function used to connect to the address on the named network. This option is generally unnecessary except for advanced use-cases. The function is used for all invocations of Dial. To configure a dial function per individual calls to dial, use WithOneOffDialFunc.

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient configures the underlying AlloyDB Admin API client with the provided HTTP client. This option is generally unnecessary except for advanced use-cases.

func WithIAMAuthN added in v1.5.0

func WithIAMAuthN() Option

WithIAMAuthN enables automatic IAM Authentication. If no token source has been configured (such as with WithTokenSource, WithCredentialsFile, etc), the dialer will use the default token source as defined by https://pkg.go.dev/golang.org/x/oauth2/google#FindDefaultCredentialsWithParams.

func WithIAMAuthNCredentials added in v1.17.0

func WithIAMAuthNCredentials(c *auth.Credentials) Option

WithIAMAuthNCredentials configures the credentials used for IAM authentication. When this option isn't set, the connector will use the credentials configured with other options or Application Default Credentials for IAM authentication.

func WithIAMAuthNTokenSource added in v1.17.0

func WithIAMAuthNTokenSource(s oauth2.TokenSource) Option

WithIAMAuthNTokenSource sets the token use used for IAM Authentication. Any AlloyDB API interactions will not use this token source.

The IAM AuthN token source on the other hand should only have:

func WithLazyRefresh added in v1.10.0

func WithLazyRefresh() Option

WithLazyRefresh configures the dialer to refresh certificates on an as-needed basis. If a certificate is expired when a connection request occurs, the Go Connector will block the attempt and refresh the certificate immediately. This option is useful when running the Go Connector in environments where the CPU may be throttled, thus preventing a background goroutine from running consistently (e.g., in Cloud Run the CPU is throttled outside of a request context causing the background refresh to fail).

func WithOptOutOfAdvancedConnectionCheck added in v1.13.0

func WithOptOutOfAdvancedConnectionCheck() Option

WithOptOutOfAdvancedConnectionCheck disables the dataplane permission check. It is intended only for clients who are running in an environment where the workload's IP address is otherwise unknown and cannot be allow-listed in a VPC Service Control security perimeter. This option is incompatible with IAM Authentication.

NOTE: This option is for internal usage only and is meant to ease the migration when the advanced check will be required on the server. In future versions this will revert to a no-op and should not be used. If you think you need this option, open an issue on https://github.com/GoogleCloudPlatform/alloydb-go-connector for design advice.

func WithOptOutOfBuiltInTelemetry added in v1.15.0

func WithOptOutOfBuiltInTelemetry() Option

WithOptOutOfBuiltInTelemetry disables the internal metric export. By default, the Dialer will report on its internal operations to the alloydb.googleapis.com system metric prefix. These metrics help AlloyDB improve performance and identify client connectivity problems. Presently, these metrics aren't public, but will be made public in the future. To disable this telemetry, provide this option when initializing a Dialer.

func WithOptions

func WithOptions(opts ...Option) Option

WithOptions turns a list of Option's into a single Option.

func WithRSAKey

func WithRSAKey(k *rsa.PrivateKey) Option

WithRSAKey returns an Option that specifies a rsa.PrivateKey used to represent the client.

func WithRefreshTimeout

func WithRefreshTimeout(t time.Duration) Option

WithRefreshTimeout returns an Option that sets a timeout on refresh operations. Defaults to 60s.

func WithStaticConnectionInfo added in v1.10.0

func WithStaticConnectionInfo(r io.Reader) Option

WithStaticConnectionInfo specifies an io.Reader from which to read static connection info. This is a *dev-only* option and should not be used in production as it will result in failed connections after the client certificate expires. It is also subject to breaking changes in the format. NOTE: The static connection info is not refreshed by the dialer. The JSON format supports multiple instances, regardless of cluster.

The reader should hold JSON with the following format:

{
    "publicKey": "<PEM Encoded public RSA key>",
    "privateKey": "<PEM Encoded private RSA key>",
    "projects/<PROJECT>/locations/<REGION>/clusters/<CLUSTER>/instances/<INSTANCE>": {
        "ipAddress": "<PSA-based private IP address>",
        "publicIpAddress": "<public IP address>",
        "pscInstanceConfig": {
            "pscDnsName": "<PSC DNS name>"
        },
        "pemCertificateChain": [
            "<client cert>", "<intermediate cert>", "<CA cert>"
        ],
        "caCert": "<CA cert>"
    }
}

func WithTokenSource

func WithTokenSource(s oauth2.TokenSource) Option

WithTokenSource returns an Option that specifies an OAuth2 token source to be used as the basis for authentication.

When Auth IAM AuthN is enabled, use WithIAMAuthNTokenSources or WithIAMAuthNCredentials to set the token source for login tokens separately from the API client token source.

You may only use one of the following options: WithIAMAuthNCredentials, WithIAMAuthNTokenSources, WithCredentials, WithTokenSource

func WithUserAgent

func WithUserAgent(ua string) Option

WithUserAgent returns an Option that sets the User-Agent.

Directories

Path Synopsis
driver
pgxv4
This package is deprecated.
This package is deprecated.
pgxv5
Package pgxv5 provides an AlloyDB driver that uses pgx v5 and works with the database/sql package.
Package pgxv5 provides an AlloyDB driver that uses pgx v5 and works with the database/sql package.
Package errtype provides a number of concrete types which are used by the alloydbconn package.
Package errtype provides a number of concrete types which are used by the alloydbconn package.
internal
tel
Package tel provides telemetry data on the connector's internal operations.
Package tel provides telemetry data on the connector's internal operations.
tel/v2
Package tel provides telemetry into the connector's internal operations.
Package tel provides telemetry into the connector's internal operations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL