Utilities for token refresh, validation, credential management, downscoped tokens, and service account impersonation.
Client for refreshing user credentials using refresh tokens.
/**
* Client for refreshing user OAuth2 credentials
*/
class UserRefreshClient extends AuthClient {
constructor(options?: UserRefreshClientOptions);
/** Refresh access token using refresh token */
refreshAccessToken(): Promise<RefreshAccessTokenResponse>;
/** Get access token, refreshing if necessary */
getAccessToken(): Promise<{ token?: string | null; res?: GaxiosResponse }>;
/** Get request headers */
getRequestHeaders(): Promise<{ [key: string]: string }>;
/** Create scoped version of client */
createScoped(scopes: string | string[]): UserRefreshClient;
}
interface UserRefreshClientOptions {
/** Client ID */
clientId?: string;
/** Client secret */
clientSecret?: string;
/** Refresh token */
refreshToken?: string;
/** OAuth2 scopes */
scopes?: string | string[];
/** Eager refresh threshold in milliseconds */
eagerRefreshThresholdMillis?: number;
/** Force refresh on failure */
forceRefreshOnFailure?: boolean;
}
interface RefreshAccessTokenResponse {
/** New credentials */
credentials: Credentials;
/** HTTP response */
res: GaxiosResponse | null;
}Usage Examples:
import { UserRefreshClient } from "google-auth-library";
// Create refresh client
const refreshClient = new UserRefreshClient({
clientId: 'client-id.googleusercontent.com',
clientSecret: 'client-secret',
refreshToken: 'refresh-token-from-oauth-flow'
});
// Refresh and get new access token
const { credentials } = await refreshClient.refreshAccessToken();
console.log('New access token:', credentials.access_token);
// Make authenticated request
const response = await refreshClient.request({
url: 'https://www.googleapis.com/oauth2/v1/userinfo'
});Service account impersonation for accessing resources with different permissions.
/**
* Service account impersonation client
* Allows one service account to impersonate another
*/
class Impersonated extends AuthClient {
constructor(options: ImpersonatedOptions);
/** Get access token by impersonating service account */
getAccessToken(): Promise<{ token?: string | null; res?: GaxiosResponse }>;
/** Get request headers */
getRequestHeaders(): Promise<{ [key: string]: string }>;
/** Sign blob using impersonated service account */
sign(blobToSign: string): Promise<string>;
/** Get service account email */
getCredentials(): Promise<{ client_email: string }>;
}
interface ImpersonatedOptions {
/** Source credentials for impersonation */
sourceClient: AuthClient;
/** Service account email to impersonate */
targetPrincipal: string;
/** Delegates for impersonation chain */
delegates?: string[];
/** Target scopes */
targetScopes: string[];
/** Token lifetime in seconds (max 3600) */
lifetime?: number | string;
/** Quota project ID */
quotaProjectId?: string;
}Usage Examples:
import { GoogleAuth, Impersonated } from "google-auth-library";
// Create source client (your credentials)
const auth = new GoogleAuth();
const sourceClient = await auth.getClient();
// Create impersonated client
const impersonatedClient = new Impersonated({
sourceClient: sourceClient,
targetPrincipal: 'target-service-account@project.iam.gserviceaccount.com',
targetScopes: ['https://www.googleapis.com/auth/cloud-platform'],
lifetime: 3600 // 1 hour
});
// Get access token for impersonated service account
const { token } = await impersonatedClient.getAccessToken();
// Use impersonated client for requests
const response = await impersonatedClient.request({
url: 'https://storage.googleapis.com/storage/v1/b',
params: { project: 'target-project' }
});Client with downscoped access to resources using Credential Access Boundaries.
/**
* Downscoped client with restricted access to resources
* Uses Credential Access Boundaries to limit token scope
*/
class DownscopedClient extends AuthClient {
constructor(options: DownscopedClientOptions);
/** Get downscoped access token */
getAccessToken(): Promise<{ token?: string | null; res?: GaxiosResponse }>;
/** Get request headers */
getRequestHeaders(): Promise<{ [key: string]: string }>;
}
interface DownscopedClientOptions {
/** Source credentials for downscoping */
sourceClient: AuthClient;
/** Credential access boundary rules */
credentialAccessBoundary: CredentialAccessBoundary;
/** Quota project ID */
quotaProjectId?: string;
}
interface CredentialAccessBoundary {
/** Access boundary rules */
accessBoundaryRules: AccessBoundaryRule[];
}
interface AccessBoundaryRule {
/** Available resource (e.g., Cloud Storage bucket) */
availableResource: string;
/** Available permissions */
availablePermissions: string[];
/** Availability condition (CEL expression) */
availabilityCondition?: AvailabilityCondition;
}
interface AvailabilityCondition {
/** CEL expression for condition */
expression: string;
/** Condition title */
title?: string;
/** Condition description */
description?: string;
}Usage Examples:
import { GoogleAuth, DownscopedClient } from "google-auth-library";
// Create source client
const auth = new GoogleAuth();
const sourceClient = await auth.getClient();
// Define access boundary - restrict to specific bucket and objects
const credentialAccessBoundary = {
accessBoundaryRules: [
{
availableResource: '//storage.googleapis.com/projects/_/buckets/my-bucket',
availablePermissions: [
'inRole:roles/storage.objectViewer',
'inRole:roles/storage.objectCreator'
],
availabilityCondition: {
expression: 'request.time < timestamp("2024-01-01T00:00:00Z")'
}
}
]
};
// Create downscoped client
const downscopedClient = new DownscopedClient({
sourceClient: sourceClient,
credentialAccessBoundary: credentialAccessBoundary
});
// Get downscoped token (limited to specified resources)
const { token } = await downscopedClient.getAccessToken();
// Use downscoped client - only has access to my-bucket
const response = await downscopedClient.request({
url: 'https://storage.googleapis.com/storage/v1/b/my-bucket/o'
});Client for ID token operations and verification.
/**
* ID token client for OpenID Connect operations
*/
class IdTokenClient extends AuthClient {
constructor(options: IdTokenClientOptions);
/** Get ID token for target audience */
getIdToken(targetAudience: string): Promise<string>;
/** Get request headers with ID token */
getRequestHeaders(): Promise<{ [key: string]: string }>;
}
interface IdTokenClientOptions {
/** Target audience for ID token */
targetAudience: string;
/** ID token provider */
idTokenProvider: IdTokenProvider;
}
interface IdTokenProvider {
/** Fetch ID token for audience */
fetchIdToken(audience: string): Promise<string>;
}Utility for IAM-related authentication operations.
/**
* IAM authentication utility
*/
class IAMAuth extends AuthClient {
constructor(options?: { [key: string]: any });
/** Get request metadata for IAM operations */
getRequestMetadata(url?: string): Promise<RequestMetadata>;
}
interface RequestMetadata {
[key: string]: string | string[];
}Pass-through authentication client for testing and development.
/**
* Pass-through client that doesn't perform authentication
* Useful for anonymous access, local emulators, and testing environments
*/
class PassThroughClient extends AuthClient {
constructor();
/** Get access token (returns empty object) */
getAccessToken(): Promise<GetAccessTokenResponse>;
/** Get request headers (returns empty Headers object) */
getRequestHeaders(): Promise<Headers>;
/** Make request without authentication headers */
request<T>(opts: GaxiosOptions): Promise<GaxiosResponse<T>>;
}Usage Examples:
import { PassThroughClient } from "google-auth-library";
// Create pass-through client for testing
const passthroughClient = new PassThroughClient();
// Make unauthenticated request (useful for local emulators)
const response = await passthroughClient.request({
url: 'http://localhost:8080/api/data',
method: 'GET'
});
// Use with Google Cloud emulators
const emulatorResponse = await passthroughClient.request({
url: 'http://localhost:8080/storage/v1/b/test-bucket/o',
method: 'GET'
});Client for ID token operations and verification for OpenID Connect workflows.
/**
* ID token client for OpenID Connect operations
* Retrieves ID tokens from metadata servers or other providers
*/
class IdTokenClient extends OAuth2Client {
constructor(options: IdTokenOptions);
/** Get request metadata with ID token */
getRequestMetadata(): Promise<RequestMetadataResponse>;
}
interface IdTokenOptions extends OAuth2ClientOptions {
/** The client to make the request to fetch an ID token */
idTokenProvider: IdTokenProvider;
/** The audience to use when requesting an ID token */
targetAudience: string;
}
interface IdTokenProvider {
/** Fetch ID token for target audience */
fetchIdToken(targetAudience: string): Promise<string>;
}
interface RequestMetadataResponse {
headers?: Headers;
}Usage Examples:
import { IdTokenClient } from "google-auth-library";
// Custom ID token provider
const idTokenProvider = {
fetchIdToken: async (audience: string) => {
// Implement custom logic to fetch ID token
// e.g., from metadata server, external service, etc.
return await fetchFromCustomSource(audience);
}
};
// Create ID token client
const idTokenClient = new IdTokenClient({
targetAudience: 'https://my-service.example.com',
idTokenProvider: idTokenProvider
});
// Get authenticated request metadata
const metadata = await idTokenClient.getRequestMetadata();
// Use headers in requests
const response = await fetch('https://my-service.example.com/api', {
headers: metadata.headers
});interface Credentials {
/** OAuth2 access token */
access_token?: string | null;
/** OAuth2 refresh token */
refresh_token?: string | null;
/** Token scope */
scope?: string;
/** Token type (usually 'Bearer') */
token_type?: string;
/** OpenID Connect ID token */
id_token?: string | null;
/** Token expiry timestamp (milliseconds) */
expiry_date?: number | null;
}
interface RefreshOptions {
/** Eager refresh threshold in milliseconds */
eagerRefreshThresholdMillis?: number;
/** Force refresh on failure */
forceRefreshOnFailure?: boolean;
}/**
* Validate token expiry and refresh if needed
*/
function isTokenExpiring(credentials: Credentials, eagerRefreshThresholdMillis?: number): boolean;
/**
* Check if credentials need refresh
*/
function shouldRefreshToken(credentials: Credentials): boolean;Common token management errors:
try {
const { credentials } = await refreshClient.refreshAccessToken();
} catch (error) {
if (error.response?.data?.error === 'invalid_grant') {
console.error('Refresh token is invalid or expired');
// Re-authenticate user
} else if (error.response?.status === 403) {
console.error('Insufficient permissions for token refresh');
}
}
try {
const impersonatedClient = new Impersonated(options);
const { token } = await impersonatedClient.getAccessToken();
} catch (error) {
if (error.message.includes('Permission denied')) {
console.error('Source account cannot impersonate target service account');
console.error('Grant "Service Account Token Creator" role to source account');
}
}