CoursesAdvanced cloud securityIdentity & access at scale

Workload identity federation without static keys

OIDC to AWS/GCP/Azure and killing long-lived cloud keys.

Advanced35 min · lesson 2 of 15

The single most effective cloud-identity upgrade is deleting your long-lived access keys. A key stored in a CI secret, a config file, or an env var is a bearer credential that never expires — copy it once and you own it forever. Workload identity federation replaces it with a short-lived token minted on demand, scoped to the exact workload that asked, and impossible to reuse after it expires.

How OIDC federation works

The CI system (or Kubernetes, or another cloud) acts as an OpenID Connect identity provider. When a job runs, the platform issues it a signed JWT describing who it is — which repository, which branch, which workflow. The job hands that token to the cloud STS endpoint, which verifies the signature against the IdP, checks the claims against a trust policy you wrote, and returns short-lived cloud credentials. No secret is ever stored: the token is minted fresh, is valid for minutes, and its claims are cryptographically bound to the real workload.

GitHub Actions to AWS, zero stored keys
# Trust policy on the role the pipeline assumes. The condition pins the token
# to ONE repo and ONE branch — a fork or another repo cannot assume it.
{
"Effect": "Allow",
"Principal": { "Federated": "arn:aws:iam::222222222222:oidc-provider/token.actions.githubusercontent.com" },
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": { "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" },
"StringLike": { "token.actions.githubusercontent.com:sub": "repo:acme/api:ref:refs/heads/main" }
}
}
# The workflow — note there are NO aws-access-key secrets anywhere:
permissions:
id-token: write # allow the job to request an OIDC token
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::222222222222:role/gha-deploy
aws-region: eu-west-1

The same pattern on every platform

This is not an AWS-only trick. GCP calls it Workload Identity Federation, mapping an external OIDC/SAML identity to a service account with no downloaded key. Azure calls it Workload Identity federation for app registrations. Inside Kubernetes, IRSA (AWS) and Workload Identity (GKE/AKS) project a service-account token that pods exchange for cloud credentials. The mental model is identical everywhere: an attested identity is exchanged for a short-lived credential, and the static key ceases to exist.

Token exchange: no key at rest
1CI job / pod
has a platform identity
2IdP mints OIDC JWT
signed claims: repo, branch, sa
3cloud STS verifies
signature + trust-policy conditions
4short-lived creds
minutes-long, scoped, revocable
A captured token that already expired is worthless; there is no standing secret to steal in the first place.
A loose sub claim is a wide-open door
The security of federation lives entirely in the trust-policy conditions. A subject like repo:acme/api:* trusts every branch and every pull request — including a fork opening a malicious PR. Pin the sub to specific refs or environments, always assert the aud claim, and review these conditions like production code. Federation with a wildcard subject is worse than a stored key, because it looks safe.