Goal: GitHub Actions deploys to GCP with zero long-lived keys.

Steps:
1. Create a workload identity pool:
```
gcloud iam workload-identity-pools create [POOL] --location global --display-name "[NAME]"
```
2. Create an OIDC provider for GitHub in the pool. Issuer is the GitHub OIDC issuer; set attribute mapping (google.subject from assertion.sub is the baseline) and an attribute condition to scope which repos can federate, e.g. assertion.repository == '[ORG]/[REPO]'.
3. Allow the federated identity to impersonate the target SA:
```
gcloud iam service-accounts add-iam-policy-binding [SA-EMAIL]   --role roles/iam.workloadIdentityUser   --member "principalSet://iam.googleapis.com/projects/[NUM]/locations/global/workloadIdentityPools/[POOL]/attribute.repository/[ORG]/[REPO]"
```
4. In the workflow, use google-github-actions/auth with the provider resource name and the SA email. No secrets needed.

Traps:
- Attribute condition too tight (or referencing a claim the token lacks) fails closed with unhelpful errors. Decode a real token and test the condition logic.
- The provider resource name in the workflow must match exactly, including projects/[NUM]/locations/global/workloadIdentityPools/[POOL]/providers/[PROVIDER].
- The federated identity still needs the workload's roles (storage.admin etc) via the SA it impersonates. Federation is auth, not authorization.
- Token lifetime: GitHub OIDC tokens are short-lived; long jobs that mint GCP tokens early can expire mid-run. Mint close to use.

Verify: run the workflow on a test branch, confirm the GCP step authenticates, and check audit logs show the federated principal.