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 sign() capability #1443

@salrashid123

Description

@salrashid123

Impersonated client does not have any way to generate signedurl or to signbytes.

This credential type uses the IAM api to perform acquire various token types like generateAccessToken, generateIdToken (ref: #1318),

The ability to sign on behalf of the impersonated svc account through the iam api would use the signBlob API.

This feaure request is to surface a sign interface such that it can be used standalone or though a client such as storage and allow generation of signedURLs.

Essentially this flow will allow

  • user -> impersonate svc1 --> generate signedurl as svc1

if it helps, I have a sample working below but i had to make some edits

A) https://github.com/googleapis/google-auth-library-nodejs/blob/main/src/auth/googleauth.ts#L814

async getCredentialsAsync() {
    const client = await this.getClient();

    if (client instanceof impersonated_1.Impersonated) {
        // not really used.  Impersonated uses the service accounts email
        // it got initialized with
        return { client_email: client.targetPrincipal }
    }
  // ...
  // ...
}

B) https://github.com/googleapis/google-auth-library-nodejs/blob/main/src/auth/googleauth.ts#L946

async sign(data) {
    const client = await this.getClient();
    
    if (client instanceof impersonated_1.Impersonated) {
        return client.sign(data);
    }
  // ...
  // ...
}

C) https://github.com/googleapis/google-auth-library-nodejs/blob/main/src/auth/impersonated.ts

/**
 * Signs some bytes.
 * @param blobToSign Sign bytes.
 */
     async sign(blobToSign) {

        try {
            await this.sourceClient.getAccessToken();
            const name = `projects/-/serviceAccounts/${this.targetPrincipal}`;
            const u = `${this.endpoint}/v1/${name}:signBlob`;
            const body = {
                delegates: this.delegates,
                payload: Buffer.from(blobToSign).toString('base64')
            };
            const res = await this.sourceClient.request({
                url: u,
                data: body,
                method: 'POST',
            });
            const tokenResponse = res.data;
            return tokenResponse.signedBlob
        }
        catch (error) {

        }
    }    
Usage
const { GoogleAuth, Impersonated } = require('google-auth-library');
const { Storage } = require('@google-cloud/storage');

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

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

  // test sign
  //console.log(await targetClient.sign("foo"));

  let projectId = 'fabled-ray-104117'
  let bucketName = 'fabled-ray-104117-test'

  // use the impersonated creds to bootstrap a storage client
  const storageOptions = {
    projectId,
    authClient: targetClient,
  };
  const storage = new Storage(storageOptions);

  // ####### GCS SignedURL
  const signOptions = {
    version: 'v4',
    action: 'read',
    expires: Date.now() + 15 * 60 * 1000, // 15 minutes
  };

  const  su = await storage
    .bucket(bucketName)
    .file('foo.txt')
    .getSignedUrl(signOptions);
  console.log(su);
}
main().catch(console.error);

ref #1210
Google Cloud Storage SignedURL with Cloud Run, Cloud Functions and GCE VMs

@danielbankhead, @FrodoTheTrue, @m0ar

Metadata

Metadata

Assignees

Labels

priority: p3Desirable enhancement or 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