On this page
The OIDC subject claim, sub, is the field in an OpenID Connect token that names the principal the token is about; in a CI job's token it is a string built from the repository and the branch, tag or deployment environment the job runs for, and it is the claim most trust rules match on.
What it looks like
RFC 7519 defines sub as the claim that "identifies the principal that is the subject of the JWT" (RFC 7519). Each CI provider decides how to fill it. GitHub's formats, from its OIDC reference:
| Job | Subject |
|---|---|
| runs on a branch | repo:octo-org/octo-repo:ref:refs/heads/demo-branch |
| references an environment | repo:octo-org/octo-repo:environment:Production |
| runs for a pull request, no environment | repo:octo-org/octo-repo:pull_request |
| runs on a tag | repo:octo-org/octo-repo:ref:refs/tags/demo-tag |
Two consequences surprise people. The environment wins: a job that deploys to Production from main gets the environment subject, not the branch one. And a pull request job without an environment gets a subject that names no branch at all.
The 2026 format change on GitHub
The old format names an owner and repository by name. GitHub explains the problem: "If a namespace was recycled, a different owner could create the same subject value." So "repositories created after July 15, 2026 now use an immutable default subject format" that "includes both the owner ID and repository ID", for example repo:octo-org@123456/octo-repo@456789:ref:refs/heads/main. Older repositories keep the previous format unless the organization or repository opts in; renames and transfers after that date also switch. GitHub Enterprise Server isn't part of the rollout.
A trust rule written for the old format silently stops matching a new repository. Check which format yours uses before writing rules. The details and migration path are in GitHub's OIDC subject claim format.
Common mistakes
- Wildcards.
repo:kiteline/*trusts every repository in the organization, including ones created later. AWS refuses to save a trust policy for GitHub whosesubcondition is missing or only a wildcard (AWS). - Prefix matches. A pattern like
repo:kiteline/web-app*also matcheskiteline/web-app-fork. - Matching
subalone where the provider offers more. Separate claims such asrepository_idorrefcan be pinned individually. - Customizing the template in the wrong order. GitHub advises creating the matching condition at your cloud provider first, because "customizing the claims results in a new format for the entire
subclaim."
How Crunu matches it
Crunu's CI binding (OIDC) on a service token doesn't ask you to write a subject string. Rules name the claims directly: for GitHub Actions the repository and audience are required, and ref, environment, workflow ref, repository ID and owner ID are optional; GitLab CI rules use project path, ref, ref type, protected ref and environment; Bitbucket rules use workspace and repository UUIDs and optionally the branch and deployment environment UUID. A rule for any other OIDC issuer must pin at least one claim for a repository, project or owner without a * pattern.
Pinning IDs where you can protects against the recycled-name problem regardless of the subject format. For the claims every provider issues, see CI/CD secrets with OIDC; to generate cloud policies in both GitHub formats, use the OIDC trust policy builder.
Sources
- RFC 7519: JSON Web Token (JWT), checked October 30, 2026.
- GitHub Docs: OpenID Connect reference, checked October 30, 2026.
- AWS IAM: Create a role for OpenID Connect federation, checked October 30, 2026.
From the blog
CI/CD
GitHub's new OIDC subject format: fixing AWS trust policies
Not authorized to perform sts:AssumeRoleWithWebIdentity on a new repo? GitHub added owner and repo IDs to the OIDC sub claim. How to check and fix the policy.
CI and OIDC guide
CI/CD
Bitbucket Pipelines OIDC: the step token explained
What oidc: true gives a Bitbucket step: the BITBUCKET_STEP_OIDC_TOKEN, the workspace issuer, audiences, the sub claim and how to pin a trust policy to it.
CI and OIDC guide
CI/CD
GitLab CI OIDC without Premium: id_tokens on the Free tier
The secrets keyword needs GitLab Premium, but id_tokens works on Free. How to exchange a job's ID token for AWS, Google Cloud, Azure or Crunu by hand.
CI and OIDC guide