PATTERN Cited by 2 sources
Short-lived OIDC credentials in CI¶
Problem: CI workflows need credentials to talk to cloud providers (AWS, GCP, Azure), package registries (PyPI, npm), and even GitHub itself. Storing Personal Access Tokens, GitHub App private keys, or long-lived cloud API keys as repo secrets creates an arbitrary-blast-radius leak surface: anyone who exfiltrates the secret can use it from anywhere, for its full lifetime, as any identity.
Pattern: Use OIDC identity federation to exchange a short-lived JWT for a scoped, time-bounded credential per-job. No credential at rest; no credential after job exit.
Shape¶
- CI platform acts as an OIDC IdP (GitHub Actions exposes
ACTIONS_ID_TOKEN_REQUEST_*env vars). - Job obtains an OIDC token bearing claims like
sub,aud,repo,workflow,ref. - Token is presented to a broker that trusts the CI platform's IdP.
- Broker validates claims (via
StringLike/StringEqualstrust-policy matching), issues a scoped, short-lived credential. - Job uses the credential; it expires without rotation.
Canonical instantiations¶
GitHub Actions → AWS¶
aws-actions/configure-aws-credentials action calls
sts.AssumeRoleWithWebIdentity against an IAM Role whose
trust policy names the GitHub OIDC IdP and matches sub on
repo:ORG/REPO:ref:refs/heads/BRANCH.
patterns/oidc-role-assumption-for-cross-cloud-auth is the
dedicated pattern for the AWS side; this pattern is the CI
side.
GitHub Actions → GitHub¶
Long-lived PATs and GitHub App private keys stored in repo secrets are the legacy; octo-sts and dd-octo-sts-action are the OIDC-exchange replacements.
GitHub Actions → PyPI¶
PyPI Trusted Publishing accepts OIDC tokens from known IdPs (GitHub Actions, GitLab CI) and issues ephemeral publish tokens scoped to the workflow.
Fly.io Machines → AWS¶
Fly.io operates its own OIDC IdP (oidc.fly.io) that issues
JWTs to Fly Machines; AWS IAM trust policies scope role
assumption via sub prefix matching (see
sources/2024-06-19-flyio-aws-without-access-keys).
What it buys you¶
- No long-lived credential at rest in repo secrets.
- Per-job scope — different workflow = different identity = different trust policy match.
- Auto-rotation — every job gets a fresh token.
- Time bounds — typical ≤ 1 hour, often tighter.
- Fail-closed posture — if the IdP is unreachable, jobs fail rather than falling back to a long-lived secret.
What it doesn't buy you¶
- Protection against malicious workflows with legitimate
OIDC claims. If a malicious PR can get an OIDC token
whose claims match a trust policy, the token is usable.
Trust-policy design (
subprefix matching to match onlymainbranch, onlyref:refs/tags/*, etc.) is the control. - Protection against compromised dependencies. Third-party GitHub Actions pinned to floating tags can still exfiltrate OIDC tokens at runtime. patterns/org-wide-github-rulesets hardening + commit pinning + audit are needed here.
Seen in¶
- sources/2026-03-09-datadog-when-an-ai-agent-came-knocking — Datadog cites this pattern as one of its SDLC-security initiatives: "Building an adaptation of octo-sts by chainguard for the dd-octo-sts-action GitHub action, allowing our workflows to dynamically generate minimally scoped, short-lived GitHub credentials at runtime through Open ID Connect (OIDC) identity federation to deprecate long-lived and overscoped GitHub Personal Access Tokens (PATs) and GitHub Apps in workflows."
- sources/2024-06-19-flyio-aws-without-access-keys — Fly.io → AWS disclosure of the same pattern at a different substrate.
Related¶
- concepts/oidc-identity-federation — underlying mechanism.
- concepts/short-lived-credential-auth — downstream posture.
- systems/github-actions — canonical substrate.
- systems/octo-sts, systems/dd-octo-sts-action — GitHub-specific broker implementations.
- patterns/oidc-role-assumption-for-cross-cloud-auth — the AWS-side flavour.
- companies/datadog — operator of dd-octo-sts-action.