DevOps Peach

GCP Basics · IAM & Security – Roles, Service Accounts, Federation, Org Policy and Secrets · Lesson 3 of 5

Workload Identity Federation for CI/CD

Let GitHub Actions, AWS or any OIDC/SAML identity get short-lived Google Cloud credentials without service account keys, filtered by attribute conditions.

Practice interactively →

Workload Identity Federation lets a workload outside Google Cloud exchange its own identity token for a short-lived Google Cloud token. GitHub Actions is the classic case: no JSON key in repository secrets.

flowchart LR
  GH["GitHub Actions job<br/>repo example-org/shop"] -- "OIDC token" --> STS["Security Token Service"]
  STS --> POOL["Workload identity pool<br/>github-pool + provider"]
  POOL -- "federated token" --> SA["Service account deployer-sa"]
  SA --> AR["Artifact Registry and Cloud Run"]
  %% step GH: The job asks GitHub for an OIDC token that names the repository, branch and workflow.
  %% step STS: Google’s Security Token Service checks the token against the provider configuration.
  %% step POOL: The provider maps claims to attributes and the attribute condition rejects other repositories.
  %% step SA: The federated principal impersonates deployer-sa (or is granted roles directly).
  %% step AR: The job pushes the image and deploys with tokens that expire within an hour.

Building blocks

Piece Purpose
Workload identity pool Container for external identities, per project
Provider Trust settings for one IdP: OIDC (GitHub, GitLab, Azure AD), SAML, or AWS
Attribute mapping Turns token claims into Google attributes, e.g. google.subject=assertion.sub, attribute.repository=assertion.repository
Attribute condition CEL expression that must be true, e.g. assertion.repository_owner=='example-org'
IAM binding Grants roles to principalSet://…/attribute.repository/example-org/shop

Always set an attribute condition for multi-tenant issuers such as GitHub; otherwise any GitHub repository could try to use your provider.

Setup in four commands

gcloud iam workload-identity-pools create github-pool --location=global
gcloud iam workload-identity-pools providers create-oidc github   --location=global --workload-identity-pool=github-pool   --issuer-uri="https://token.actions.githubusercontent.com"   --attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository"   --attribute-condition="assertion.repository_owner=='example-org'"
gcloud iam service-accounts add-iam-policy-binding deployer-sa@dl-lab-dev.iam.gserviceaccount.com   --role=roles/iam.workloadIdentityUser   --member="principalSet://iam.googleapis.com/projects/123456789/locations/global/workloadIdentityPools/github-pool/attribute.repository/example-org/shop"

In the workflow, google-github-actions/auth with workload_identity_provider and service_account does the exchange; the job also needs permissions: id-token: write.

Workforce vs workload

Workload Identity Federation Workforce Identity Federation
For Machines and pipelines People from an external IdP (Okta, Entra ID)
Configured in A project The organization
Command Meaning
gcloud iam workload-identity-pools list --location=global Pools in the project
gcloud iam workload-identity-pools providers describe github --workload-identity-pool=github-pool --location=global Provider settings

Traps: the IAM member uses the project number, not the project ID; forgetting id-token: write gives “unable to get ACTIONS_ID_TOKEN_REQUEST_URL”; without an attribute condition the trust is far too wide.

Practice interactively →