GitHub Actions

OIDC Trust Policies: Secure GitHub Actions Cloud Deploys

OpenID Connect can remove long-lived cloud secrets from GitHub Actions, but it shifts the critical review to the cloud role trust policy.

Key takeaways for GitHub Actions OIDC trust policies

  • GitHub describes OIDC as a way for workflows to request short-lived cloud tokens instead of storing long-lived cloud credentials as GitHub secrets. [1]
  • GitHub's OIDC reference says the sub claim is essential because it lets the cloud provider allocate access tokens in a predictable way. [2]
  • The OIDC reference documents subject examples for environment, pull-request, branch, and tag filters. [2]
  • GitHub's AWS, Azure, and Google Cloud OIDC guides all require a workflow or job permissions setting with id-token: write before a JWT can be requested. [3] [4] [5]
  • GitHub documents workflow-level and job-level controls for reducing default GITHUB_TOKEN access. [6]

OIDC hardening happens in the cloud trust rule

Bottom line: Treat the cloud trust policy as production access control. It should name the exact repository, branch, tag, environment, audience, and job posture that may receive credentials.

OIDC is often sold internally as "no more cloud secrets in GitHub." That part is real: GitHub's OIDC overview describes exchanging a GitHub-issued token for a short-lived cloud access token instead of storing long-lived cloud credentials as secrets. [1]

The mistake is assuming that removing the secret removes the deployment risk. A broad cloud trust policy can let the wrong workflow, branch, or environment request the same cloud role that a static secret used to unlock.

The issuer is fixed, but the trust decision is yours

GitHub's OIDC reference documents the issuer as https://token.actions.githubusercontent.com. [2] That tells the cloud provider where the identity token comes from, but it does not by itself prove that the right workflow should get production access.

The claims inside the token carry the workflow context. GitHub documents claims such as repository, repository_owner, ref, event_name, workflow_ref, workflow_sha, and environment. [2] Those values are the raw material for a narrow trust policy.

Clean verdict: A production cloud role should be reachable only from the deployment workflow and deployment context you would approve by hand.

The subject claim should not accept every repo run

GitHub says audience and subject claims are typically used together to scope cloud role access to GitHub workflows. [2] The subject claim is especially important because GitHub's reference says it defines what the cloud provider validates before allocating access tokens. [2]

Review the subject pattern before the workflow YAML. GitHub documents examples for environment-specific subjects, pull-request subjects, branch subjects, and tag subjects. [2] A deploy role tied to repo:ORG/REPO:* is easier to configure than a production-only subject, but it gives more workflow contexts a path to cloud credentials.

  • Repository: bind the trust rule to the one repository that owns the deployment.
  • Ref: prefer an exact release branch or tag pattern over every branch.
  • Environment: use an environment subject when production access should require a named environment.
  • Workflow: check whether workflow or reusable-workflow claims can separate deploy automation from general CI.

AWS, Azure, and Google Cloud expose the same footgun

GitHub's AWS OIDC guide shows a role trust policy with token.actions.githubusercontent.com:sub and token.actions.githubusercontent.com:aud conditions. [3] The sample is useful because it puts the risky decision in one visible place: which subjects may assume the role.

GitHub's Azure guide says teams must define at least one condition before proceeding so untrusted repositories cannot request access tokens for cloud resources. [4] The same guide recommends api://AzureADTokenExchange as the audience value for Azure. [4]

GitHub's Google Cloud guide says the provider setup includes creating an identity pool, configuring mapping and conditions, and connecting the pool to a service account. [5] It also lists https://token.actions.githubusercontent.com as the issuer URL to use. [5]

Avoid this posture: Any provider configuration that trusts all branches, all workflows, or every repository under an owner makes OIDC look safer than it is.

id-token: write should live only where OIDC is needed

The AWS, Azure, and Google Cloud guides each state that the workflow or job needs permissions with id-token: write to let GitHub's OIDC provider create a JWT. [3] [4] [5]

That permission should not be a repo-wide habit. Put it on the deploy job that exchanges the token, then keep unrelated build, test, and lint jobs without OIDC token minting authority.

Also narrow the rest of the token permissions. GitHub recommends granting the GITHUB_TOKEN the least required access and configuring permissions at workflow or job level. [6] A cloud deploy job that needs an OIDC token and repository read access should not inherit broad write scopes by default.

A fast audit starts with every cloud role subject

Inventory each cloud role that trusts GitHub's OIDC issuer. For each role, record the accepted audience, subject pattern, repository, ref, environment, service account or role permissions, and the workflow file that can request the token. [2]

Then trace the matching workflow job. Confirm it has id-token: write only where needed, uses narrow GITHUB_TOKEN permissions, and does not combine untrusted pull-request code or broad manual inputs with production cloud authority. [6]

For a local review queue, run gha-guard and review OIDC findings beside trigger, secret, token-permission, timeout, pinned-action, and shell-context findings.

This article is informational and is not a substitute for a security review of your own workflows, repositories, or cloud accounts.

CI Tripwire has not commissioned independent expert review of this article. Read more about the organization byline at contributors and the source posture at sourcing.

Corrections can be routed through the corrections note. Sources: 6 entries, primary platform documentation, last reviewed 2026-06-07.

Sources

  1. GitHub Docs, OpenID Connect.
  2. GitHub Docs, OpenID Connect reference.
  3. GitHub Docs, Configuring OpenID Connect in Amazon Web Services.
  4. GitHub Docs, Configuring OpenID Connect in Azure.
  5. GitHub Docs, Configuring OpenID Connect in Google Cloud Platform.
  6. GitHub Docs, Use GITHUB_TOKEN for authentication in workflows.