Skip to content

fetchIdToken fails with a 400 error when using the Compute client on GKE with Workload Identity #7777

@sjaq

Description

@sjaq

Environment details

  • OS: Alpine Linux v3.11
  • Node.js version: v14.18.1
  • npm version: 6.14.15
  • google-auth-library version: 7.9.2

Steps to reproduce

  1. Run a container in GKE with Workload Identity configured
  2. Attempt to generate an ID token using the following code:
const google = require('google-auth-library');
const client = await new google.GoogleAuth().getClient()
console.log(await client.fetchIdToken('IAP_CLIENT_ID'))

Uncaught:
GaxiosError: Could not fetch ID token: Unsuccessful response status code. Request failed with status code 400
    at Gaxios._request (/app/node_modules/gaxios/build/src/gaxios.js:129:23)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async metadataAccessor (/app/node_modules/gcp-metadata/build/src/index.js:68:21)
    at async Compute.fetchIdToken (/app/node_modules/google-auth-library/build/src/auth/computeclient.js:80:23)
    at async REPL4:1:36 {
  response: {
    config: {
      url: 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/identity?format=full&[SNIP].apps.googleusercontent.com',
      headers: [Object],
      retryConfig: [Object],
      responseType: 'text',
      timeout: 3000,
      paramsSerializer: [Function: paramsSerializer],
      validateStatus: [Function: validateStatus],
      method: 'GET'
    },
    data: 'non-empty audience parameter required\n',
    headers: {
      connection: 'close',
      'content-length': '38',
      'content-type': 'text/plain; charset=utf-8',
      date: 'Tue, 19 Oct 2021 10:50:12 GMT',
      'x-content-type-options': 'nosniff'
    },
    status: 400,
    statusText: 'Bad Request',
    request: {
      responseURL: 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/identity?format=full&audience=[SNIP].apps.googleusercontent.com'
    }
  },
  config: {
    url: 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/identity?format=full&audience=[SNIP].apps.googleusercontent.com',
    headers: { 'Metadata-Flavor': 'Google' },
    retryConfig: {
      noResponseRetries: 3,
      currentRetryAttempt: 0,
      retry: 3,
      httpMethodsToRetry: [Array],
      statusCodesToRetry: [Array]
    },
    responseType: 'text',
    timeout: 3000,
    paramsSerializer: [Function: paramsSerializer],
    validateStatus: [Function: validateStatus],
    method: 'GET'
  },
  code: '400'
}

Cause of issue

After some debugging what is going wrong it seems the Workload Identity Metadata server only accepts the audience query parameter if it is the first argument.

# Returns a valid token
$ wget -qO- --header="Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/identity?audience=[snip].apps.googleusercontent.com&format=full
eyJhbGciOiJSUzI1NiIs[...snip...]

# Returns the same 400 error, note that only the order of the query params changed
$ wget -qO- --header="Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/identity?format=full&audience=[snip].apps.googleusercontent.com
wget: server returned error: HTTP/1.1 400 Bad Request

Metadata

Metadata

Assignees

No one assigned

    Labels

    library: google-cloud-node-coreIssues transferred from another repositorytype: 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