Stop storing long-lived cloud keys in CI
The traditional way to deploy to AWS from CI: store AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as secrets. They never expire, they are long-lived, and a single leak compromises everything they can reach. Don't do that anymore.
OpenID Connect (OIDC) lets GitHub Actions request a short-lived, scoped token directly from the cloud provider's IAM. The flow:
- Workflow declares
permissions: id-token: write. - Action requests an OIDC ID token from GitHub. The token says: 'this is a workflow from repo X, branch Y, run by Z'.
- The cloud provider (AWS / GCP / Azure / etc.) verifies the token's signature against GitHub's public keys.
- The cloud provider checks its trust policy: 'do I trust workflows from repo X to assume role R?'
- If yes, returns short-lived (1-hour-ish) credentials.
- The action uses those creds. They expire automatically.
Major cloud providers all support it
- AWS — IAM Identity Provider for token.actions.githubusercontent.com, then a role with trust policy keyed on
repo:my-org/my-repo:ref:refs/heads/main. - GCP — Workload Identity Federation, similar concept.
- Azure — Federated credentials on a service principal.
- Vault, AWS Cognito, others — same principle.