or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

auth-handlers.mdclient-credentials.mdcore-oauth2.mdendpoints.mdgoogle-auth.mdgoogle-downscope.mdgoogle-external-account.mdindex.mdjira-oauth.mdjwt-jws.md
tile.json

google-auth.mddocs/

Google Authentication

Comprehensive Google Cloud Platform authentication including Application Default Credentials, service accounts, Compute Engine tokens, and SDK integration.

Package

import "golang.org/x/oauth2/google"

Overview

The google package provides specialized OAuth2 support for Google Cloud Platform and Google APIs, including:

  • Application Default Credentials (ADC)
  • Service account authentication with JWT
  • Google Compute Engine metadata server tokens
  • Google Cloud SDK integration
  • Workload identity federation
  • Domain-wide delegation

Constants and Endpoints

const JWTTokenURL = "https://oauth2.googleapis.com/token"
const MTLSTokenURL = "https://oauth2.mtls.googleapis.com/token"

var Endpoint = oauth2.Endpoint{
	AuthURL:       "https://accounts.google.com/o/oauth2/auth",
	TokenURL:      "https://oauth2.googleapis.com/token",
	DeviceAuthURL: "https://oauth2.googleapis.com/device/code",
	AuthStyle:     oauth2.AuthStyleInParams,
}

Application Default Credentials

ADC automatically finds credentials in a standard sequence of locations.

Default Client

func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error)

Returns an HTTP client using Application Default Credentials.

Default Token Source

func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSource, error)

Returns the token source for Application Default Credentials. Shortcut for FindDefaultCredentials(ctx, scope...).TokenSource.

Finding Credentials

func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials, error)

Invokes FindDefaultCredentialsWithParams with the specified scopes.

func FindDefaultCredentialsWithParams(ctx context.Context, params CredentialsParams) (*Credentials, error)

Searches for Application Default Credentials in the following order:

  1. A JSON file specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable
  2. A JSON file in the gcloud command-line tool's known location:
    • Windows: %APPDATA%/gcloud/application_default_credentials.json
    • Other: $HOME/.config/gcloud/application_default_credentials.json
  3. Google Compute Engine, App Engine, or Cloud Run metadata server

Example:

import (
	"context"
	"log"

	"golang.org/x/oauth2/google"
)

func main() {
	ctx := context.Background()

	// Simple usage
	client, err := google.DefaultClient(ctx,
		"https://www.googleapis.com/auth/cloud-platform")
	if err != nil {
		log.Fatal(err)
	}

	// Use client for Google Cloud API requests
	resp, err := client.Get("https://cloudresourcemanager.googleapis.com/v1/projects")
	// ...
}

Credentials Type

type Credentials struct {
	// ProjectID may be empty
	ProjectID string

	// TokenSource for obtaining tokens
	TokenSource oauth2.TokenSource

	// JSON contains the raw bytes from a JSON credentials file
	// May be nil if authentication is from the environment
	JSON []byte

	// UniverseDomainProvider returns the default service domain
	// for a given Cloud universe. Optional.
	UniverseDomainProvider func() (string, error)
}

func (c *Credentials) GetUniverseDomain() (string, error)
func (c *Credentials) UniverseDomain() string // Deprecated: use GetUniverseDomain

Credentials Parameters

type CredentialsParams struct {
	// Scopes is the list of OAuth scopes (required)
	Scopes []string

	// Subject is the user email for domain wide delegation (optional)
	Subject string

	// AuthHandler for 3-legged OAuth flow (required for 3LO)
	AuthHandler authhandler.AuthorizationHandler

	// State is a unique string used with AuthHandler (required for 3LO)
	State string

	// PKCE supports PKCE flow (optional for 3LO)
	PKCE *authhandler.PKCEParams

	// TokenURL overrides the default TokenURL (optional)
	TokenURL string

	// EarlyTokenRefresh is time before expiry to fetch new token
	// Default: 10 seconds. Only for GCE metadata server tokens.
	EarlyTokenRefresh time.Duration

	// UniverseDomain is the default service domain (optional)
	// Takes precedence over config file or metadata server
	UniverseDomain string
}

Example:

params := google.CredentialsParams{
	Scopes:  []string{"https://www.googleapis.com/auth/cloud-platform"},
	Subject: "admin@example.com", // For domain-wide delegation
}

creds, err := google.FindDefaultCredentialsWithParams(ctx, params)
if err != nil {
	log.Fatal(err)
}

client := oauth2.NewClient(ctx, creds.TokenSource)

Service Account Authentication

From JSON Key File

func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error)

Creates a JWT config from a Google Developers service account JSON key file. Download from https://console.developers.google.com under "Credentials".

func CredentialsFromJSON(ctx context.Context, jsonData []byte, scopes ...string) (*Credentials, error)

Invokes CredentialsFromJSONWithParams with the specified scopes.

func CredentialsFromJSONWithParams(ctx context.Context, jsonData []byte, params CredentialsParams) (*Credentials, error)

Creates credentials from JSON representing:

  • Google Developers Console client_credentials.json
  • Google Developers service account key file
  • gcloud user credentials file (refresh token)
  • Workload identity federation configuration

Important: Validate external credential configurations before use.

Example:

import (
	"context"
	"io/ioutil"
	"log"

	"golang.org/x/oauth2/google"
)

func main() {
	ctx := context.Background()

	// Read service account key
	data, err := ioutil.ReadFile("service-account-key.json")
	if err != nil {
		log.Fatal(err)
	}

	// Create credentials
	creds, err := google.CredentialsFromJSON(ctx, data,
		"https://www.googleapis.com/auth/cloud-platform")
	if err != nil {
		log.Fatal(err)
	}

	// Create client
	client := oauth2.NewClient(ctx, creds.TokenSource)

	// Use client...
}

JWT Access Tokens

func JWTAccessTokenSourceFromJSON(jsonKey []byte, audience string) (oauth2.TokenSource, error)

Creates a TokenSource using JWT access tokens (not standard OAuth2 flow). The JWT is sent as the access token. Supported by some Google services for optimization.

func JWTAccessTokenSourceWithScope(jsonKey []byte, scope ...string) (oauth2.TokenSource, error)

Similar to JWTAccessTokenSourceFromJSON but uses scopes instead of audience.

Example:

// JWT access token with audience
data, _ := ioutil.ReadFile("service-account.json")
ts, err := google.JWTAccessTokenSourceFromJSON(data,
	"https://pubsub.googleapis.com/")
if err != nil {
	log.Fatal(err)
}

client := oauth2.NewClient(ctx, ts)

Client Credentials JSON

From Web/Installed App Credentials

func ConfigFromJSON(jsonKey []byte, scope ...string) (*oauth2.Config, error)

Creates an oauth2.Config from a Google Developers Console client_credentials.json file (Web or Installed application credentials).

Download from https://console.developers.google.com under "Credentials".

Example:

data, _ := ioutil.ReadFile("client_credentials.json")
config, err := google.ConfigFromJSON(data,
	"https://www.googleapis.com/auth/drive")
if err != nil {
	log.Fatal(err)
}

// Use config for authorization code flow
url := config.AuthCodeURL("state")
// ... redirect user to url ...

token, err := config.Exchange(ctx, code)
client := config.Client(ctx, token)

Compute Engine Metadata

Compute Token Source

func ComputeTokenSource(account string, scope ...string) oauth2.TokenSource

Returns a token source that fetches access tokens from Google Compute Engine (GCE)'s metadata server. Only valid on GCE instances.

If no account is specified, "default" is used.

Example:

// Use default service account
ts := google.ComputeTokenSource("")

// Or specify service account
ts := google.ComputeTokenSource("my-service@project.iam.gserviceaccount.com",
	"https://www.googleapis.com/auth/cloud-platform")

client := oauth2.NewClient(ctx, ts)

App Engine Token Source

func AppEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource

Deprecated: On second generation runtimes (>= Go 1.11) and flexible environment, this delegates to ComputeTokenSource. Use DefaultTokenSource instead.

Returns a token source that fetches tokens from the current application's service account or metadata server.

Google Cloud SDK Integration

SDK Config

type SDKConfig struct {
	// Has unexported fields
}

func NewSDKConfig(account string) (*SDKConfig, error)

Creates an SDKConfig for the given Google Cloud SDK account. If account is empty, uses the currently active account.

Google Cloud SDK credentials must be created with gcloud auth before use.

func (c *SDKConfig) Client(ctx context.Context) *http.Client

Returns an HTTP client using Google Cloud SDK credentials. The token auto-refreshes as necessary.

func (c *SDKConfig) TokenSource(ctx context.Context) oauth2.TokenSource

Returns a TokenSource that retrieves tokens from Google Cloud SDK credentials. Does not update the credentials file with new access tokens.

func (c *SDKConfig) Scopes() []string

Returns the OAuth 2.0 scopes the current account is authorized for.

Example:

// Use currently active gcloud account
sdkConfig, err := google.NewSDKConfig("")
if err != nil {
	log.Fatal(err)
}

// Check authorized scopes
scopes := sdkConfig.Scopes()
fmt.Printf("Authorized scopes: %v\n", scopes)

// Create client
client := sdkConfig.Client(ctx)

Error Handling

Authentication Error

type AuthenticationError struct {
	// Has unexported fields
}

func (e *AuthenticationError) Error() string
func (e *AuthenticationError) Temporary() bool
func (e *AuthenticationError) Unwrap() error

Indicates an error in the authentication flow. The Temporary() method returns true for retryable errors (status codes 500, 503, 408, 429).

Example:

creds, err := google.FindDefaultCredentials(ctx, scopes...)
if err != nil {
	if authErr, ok := err.(*google.AuthenticationError); ok {
		if authErr.Temporary() {
			// Retry the operation
			log.Println("Temporary auth error, retrying...")
		} else {
			log.Fatalf("Authentication error: %v", authErr)
		}
	}
	log.Fatal(err)
}

Complete Examples

Service Account with Domain-Wide Delegation

package main

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"

	"golang.org/x/oauth2/google"
)

func main() {
	ctx := context.Background()

	// Load service account key
	data, err := ioutil.ReadFile("service-account.json")
	if err != nil {
		log.Fatal(err)
	}

	// Configure with user impersonation
	params := google.CredentialsParams{
		Scopes: []string{
			"https://www.googleapis.com/auth/admin.directory.user",
		},
		Subject: "admin@example.com", // User to impersonate
	}

	creds, err := google.CredentialsFromJSONWithParams(ctx, data, params)
	if err != nil {
		log.Fatal(err)
	}

	client := oauth2.NewClient(ctx, creds.TokenSource)

	// Use client to access Google Workspace Admin SDK
	resp, err := client.Get("https://admin.googleapis.com/admin/directory/v1/users")
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Printf("Users: %s\n", body)
}

Multiple Credential Sources

package main

import (
	"context"
	"log"
	"os"

	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
)

func getCredentials(ctx context.Context) oauth2.TokenSource {
	scopes := []string{"https://www.googleapis.com/auth/cloud-platform"}

	// Try Application Default Credentials first
	ts, err := google.DefaultTokenSource(ctx, scopes...)
	if err == nil {
		log.Println("Using Application Default Credentials")
		return ts
	}

	// Try service account key file
	if keyFile := os.Getenv("SERVICE_ACCOUNT_KEY"); keyFile != "" {
		data, err := os.ReadFile(keyFile)
		if err == nil {
			creds, err := google.CredentialsFromJSON(ctx, data, scopes...)
			if err == nil {
				log.Println("Using service account key file")
				return creds.TokenSource
			}
		}
	}

	// Try Compute Engine metadata
	if metadata.OnGCE() {
		log.Println("Using Compute Engine metadata")
		return google.ComputeTokenSource("", scopes...)
	}

	log.Fatal("No valid credentials found")
	return nil
}

func main() {
	ctx := context.Background()
	ts := getCredentials(ctx)
	client := oauth2.NewClient(ctx, ts)
	// Use client...
}

Security Best Practices

  1. Protect Service Account Keys: Never commit keys to version control
  2. Use ADC: Prefer Application Default Credentials over hardcoded keys
  3. Minimal Scopes: Request only necessary OAuth scopes
  4. Key Rotation: Implement regular service account key rotation
  5. Workload Identity: Use Workload Identity on GKE instead of service account keys
  6. Domain-Wide Delegation: Limit to trusted service accounts only
  7. Monitor Usage: Enable audit logging for service account usage

Common Scopes

const (
	// Cloud Platform - full access
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"

	// Compute Engine
	ComputeScope = "https://www.googleapis.com/auth/compute"

	// Cloud Storage
	DevstorageFullControlScope = "https://www.googleapis.com/auth/devstorage.full_control"
	DevstorageReadOnlyScope    = "https://www.googleapis.com/auth/devstorage.read_only"

	// User Info
	UserinfoEmailScope   = "https://www.googleapis.com/auth/userinfo.email"
	UserinfoProfileScope = "https://www.googleapis.com/auth/userinfo.profile"
)

Deprecated Types

type DefaultCredentials = Credentials // Deprecated: use Credentials

Related Packages