Skip to content
LearnOIDC subject claim

What is the OIDC subject (sub) claim?

Also known assub claim
Example. Kiteline is a fictional company.
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:

JobSubject
runs on a branchrepo:octo-org/octo-repo:ref:refs/heads/demo-branch
references an environmentrepo:octo-org/octo-repo:environment:Production
runs for a pull request, no environmentrepo:octo-org/octo-repo:pull_request
runs on a tagrepo: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 whose sub condition is missing or only a wildcard (AWS).
  • Prefix matches. A pattern like repo:kiteline/web-app* also matches kiteline/web-app-fork.
  • Matching sub alone where the provider offers more. Separate claims such as repository_id or ref can 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 sub claim."

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

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