Skip to content
Latchkey

Google Artifact Registry "Token exchange failed" (Workload Identity) in CI

Workload Identity Federation swaps the GitHub OIDC token for a Google access token. "Token exchange failed" means the swap was rejected: the workload identity provider, the audience, or the attribute condition does not match the incoming OIDC claims. Fix the provider mapping, then auth and push succeed.

What this error means

google-github-actions/auth fails with "Token exchange failed" or "unable to generate Google Cloud federated token", and the later docker push to *.pkg.dev never gets credentials.

docker
failed to generate Google Cloud federated token for ...: (TokenExchange)
Token exchange failed: invalid_target / unauthorized_client

Common causes

Provider, audience, or attribute condition mismatch

The workload identity pool/provider, the configured audience, or the attribute condition does not accept the repository/branch claims in the OIDC token.

The service account is not bound to the pool

The principal lacks roles/iam.workloadIdentityUser for the external identity, so the exchange is unauthorized.

How to fix it

Align the provider and the auth step

  1. Set id-token: write permission so GitHub mints an OIDC token.
  2. Reference the exact workload_identity_provider resource and service_account.
  3. Ensure the provider attribute condition matches the repo/branch claims.
.github/workflows/ci.yml
permissions:
  id-token: write
  contents: read
- uses: google-github-actions/auth@v2
  with:
    workload_identity_provider: projects/123/locations/global/workloadIdentityPools/gh/providers/gh
    service_account: ci@my-proj.iam.gserviceaccount.com

Bind the SA to the external identity

Grant roles/iam.workloadIdentityUser to the GitHub principal so the exchange is allowed.

Terminal
gcloud iam service-accounts add-iam-policy-binding ci@my-proj.iam.gserviceaccount.com \
  --role="roles/iam.workloadIdentityUser" \
  --member="principalSet://iam.googleapis.com/projects/123/locations/global/workloadIdentityPools/gh/attribute.repository/org/repo"

How to prevent it

  • Grant id-token: write in workflows that use WIF.
  • Keep the provider audience and attribute mapping in sync with claims.
  • Bind the service account to the workload identity pool principal.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →