Symptom: federation fails with audience/issuer mismatch, "attribute condition not met", or the mapped google.subject is empty.
Cause: the workload identity pool provider's config does not match what the external IdP actually issues: wrong issuer URL, wrong audience, or an attribute mapping referencing a claim the token does not carry.
Confirm:
1. Decode the external token (it is a JWT; decode without verifying to inspect claims). Note iss, aud, sub, and any custom claims.
2. `gcloud iam workload-identity-pools providers describe` - compare issuer-uri and the OIDC audience expectation against the token's iss/aud.
3. Read the attribute mapping: google.subject=assertion.sub and any attribute.condition. If the condition references assertion.repository but the token has no repository claim, it never matches.
Fix:
- Issuer mismatch: the provider's issuer-uri must exactly match the token's iss, including trailing slashes.
- Audience: for GitHub Actions the audience is typically the pool provider resource name; the credential config file must reference the right provider.
- Attribute mapping: map only claims that exist. Test the condition logic against a real decoded token before deploying.
GitHub-specific: the repository attribute comes from the job's claims. A condition limiting to repo:org/name fails for forks or renamed repos; keep conditions as tight as needed but no tighter, and log the actual claim values on failure.
Verify: exchange a real token via the credential config and confirm google.subject populates, then call an API as the federated identity.