Skip to content
This repository was archived by the owner on Nov 20, 2025. It is now read-only.
This repository was archived by the owner on Nov 20, 2025. It is now read-only.

Impersonated credentials should implement IdTokenProvider interface #1318

@salrashid123

Description

@salrashid123

Currently there is no easy way to acquire an id_token for a service account that was impersonated.

For example, if you run an application as SA1 but you would like to get an id_token for SA2, you would have to first use Impersonated module to get a raw access_token for SA2 and then use that in iamcredentials.generateIdToken() api call manually.

in another example, if you run running workload identity federation (WIF) in AWS and need an id_token to access Cloud Run, you would need to acquire the access_token for the service account for WIF on aws and then use that same generateIDToken() api call.

This FR is to allow the Impersonated module to acquire its own id_token


the workaround i tried was to edit the following

  • node_modules/google-auth-library/build/src/auth/impersonated.d.ts
export declare class Impersonated extends OAuth2Client implements IdTokenProvider {}

    /**
     * Fetches an ID token.
     * @param targetAudience the audience for the fetched ID token.
     */
    fetchIdToken(targetAudience: string): Promise<string>;    
  • node_modules/google-auth-library/build/src/auth/impersonated.js
     async fetchIdToken(targetAudience) {
        try {
            await this.sourceClient.getAccessToken();
            const name = 'projects/-/serviceAccounts/' + this.targetPrincipal;
            const u = `${this.endpoint}/v1/${name}:generateIdToken`;
            const body = {
                delegates: this.delegates,
                audience: targetAudience,
                includeEmail: true,
            };
            const res = await this.sourceClient.request({
                url: u,
                data: body,
                method: 'POST',
            });
            const tokenResponse = res.data;

            return tokenResponse.token
        }
        catch (error) {
     ...
        }
    } 

then the usage would be

    const scopes = 'https://www.googleapis.com/auth/cloud-platform'
    const auth =  new GoogleAuth({
        scopes: scopes
    });
    const client = await auth.getClient();

    // First impersonate
    let targetCredentials = 'target-serviceaccount@fabled-ray-104117.iam.gserviceaccount.com'
    let targetClient = new Impersonated({
        sourceClient: client,
        targetPrincipal: targetCredentials,
        lifetime: 30,
        delegates: [],
        targetScopes: [scopes]
    });

    // then get an ID Token
    let idClient = new IdTokenClient({
        targetAudience: 'https://foo.bar',
        idTokenProvider: targetClient
    })

    const res = await idClient.request({
        method: 'GET',
        url: 'https://httpbin.org/get',
      });
    console.log(res.data);

Finally, please note the following:

ref:

Metadata

Metadata

Labels

priority: p2Moderately-important priority. Fix may not be included in next release.type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions