"category": "CI/CD federation" · job/gitlab-ci-oidc-trust
Scoping GitLab CI OIDC trust in AWS, Azure and Google Cloud
How GitLab ID tokens are matched by each cloud, which claims stay stable when a project moves, and worked trust configurations for a protected branch on GitLab.com.
- GitLab.com signs every customer's ID tokens with one issuer, so the sub claim is what keeps other groups out.
- The default sub is built from paths; project_id and namespace_id are the stable identifiers.
- On AWS, gitlab.com:namespace_id and gitlab.com:project_id work as condition keys only for the gitlab.com provider.
- Pick one audience value and use it in the job's id_tokens block and in the cloud's trust record.
A GitLab CI job asks for an OIDC token with the id_tokens keyword, then trades that token for cloud credentials. GitLab.com uses one issuer, https://gitlab.com, for every customer, so the cloud can only tell your jobs apart from anyone else’s by reading the token’s claims. AWS lists GitLab among the shared providers whose trust policies must check gitlab.com:sub.[AWS IAM User Guide]
What does a GitLab ID token contain?
The default subject is built from the project path and the ref:[GitLab Docs]
project_path:mygroup/myproject:ref_type:branch:ref:main
Alongside it, the token carries project_id, project_path, namespace_id, namespace_path, ref, ref_type, ref_protected and, when the job names one, environment. GitLab’s docs describe project_id as globally unique for the life of the project and namespace_id as stable while the project stays in its namespace. Paths change when a group or project is renamed or moved.[GitLab Docs]
A project can change the subject format with the ci_id_token_sub_claim_components setting. When it starts with project_id, the subject looks like project_id:67890:ref_type:branch:ref:main.[GitLab Docs] Every trust record for that project then has to use the new form.
The job requests the token and sets its audience:
deploy:
id_tokens:
GITLAB_OIDC_TOKEN:
aud: sts.amazonaws.com
AWS: sub plus the ID keys
GitLab’s own example trust policy for GitLab.com pins three things: the subject, the group ID and the project ID.[GitLab Docs]
"Condition": {
"StringEquals": {
"gitlab.com:aud": "sts.amazonaws.com",
"gitlab.com:sub": "project_path:mygroup/myproject:ref_type:branch:ref:main",
"gitlab.com:namespace_id": "12345",
"gitlab.com:project_id": "67890"
}
}
GitLab’s example leaves out aud; the version above adds it. GitLab says the audience is often sts.amazonaws.com or your GitLab URL, that it must match the IAM OIDC provider’s configuration, and that using the GitLab URL “might work” but is semantically misleading.[GitLab Docs]
GitLab’s troubleshooting section calls out StringEquals used with a wildcard. It never matches; use StringLike for patterns.[GitLab Docs]
Microsoft Entra: one credential per ref
GitLab’s Azure guide uses the GitLab URL as both the issuer and the audience:[GitLab Docs]
{
"name": "myproject-main",
"issuer": "https://gitlab.com",
"subject": "project_path:mygroup/myproject:ref_type:branch:ref:main",
"audiences": ["https://gitlab.com"]
}
The job’s id_tokens block must then request aud: https://gitlab.com. Entra matches the subject exactly, allows no wildcards and holds at most 20 credentials per app or user-assigned managed identity,[Microsoft Learn] so each branch or tag that deploys needs its own credential.
Google Cloud: a condition on the group
Google requires an attribute condition for GitLab.com providers that restricts tokens to your group:[Google Cloud documentation]
assertion.namespace_id == '12345'
Its example optionally adds && assertion.environment == 'production'. Because the condition reads IDs, it keeps working through renames and doesn’t depend on the subject format. Narrow it further to the project and ref if the IAM binding doesn’t:
assertion.namespace_id == '12345' &&
assertion.project_id == '67890' &&
assertion.ref == 'main'
Checklist
- The trust record names your group and project, never
project_path:*or a whole group with*. - On GitLab.com AWS roles,
gitlab.com:namespace_idandgitlab.com:project_idare checked. - The audience in
id_tokensmatches the cloud side. - Deploy roles trust protected branches or tags only.
- Trust records are removed when a project is archived, renamed or moved.
Test a policy with the GitLab preset in the OIDC trust checker. For why path-based trust is risky after a project is renamed or deleted, see subject recycling.
Questions people ask
- Does this apply to GitLab Self-Managed?
- The token format is the same, but the issuer is your instance URL. GitLab says that for Self-Managed and Dedicated, only sub and aud are supported as AWS condition keys, so scope AWS trust with sub.
- What happened to CI_JOB_JWT_V2?
- GitLab removed it in GitLab 17.0. Jobs request tokens through the id_tokens keyword instead.
- What does GitLab do if a project path is reused?
- If a project path in sub was previously used by a different project, GitLab blocks ID token issuance for the new project. The fix GitLab gives is to start sub with an ID component and update trust policies to match.
Sources
- OpenID Connect (OIDC) authentication using ID tokens — GitLab Docs.# official documentation (issuer) · checked November 10, 2026 (full page text)
- Configure OpenID Connect in AWS to retrieve temporary credentials — GitLab Docs.# official documentation (issuer) · checked November 10, 2026 (full page text)
- Configure OpenID Connect in Azure to retrieve temporary credentials — GitLab Docs.# official documentation (issuer) · checked November 10, 2026 (full page text)
- Identity-provider controls for shared OIDC providers — AWS IAM User Guide.# official documentation · checked November 10, 2026 (full page text)
- Configure Workload Identity Federation with deployment pipelines — Google Cloud documentation.# official documentation · checked November 10, 2026 (full page text)
- Create a trust relationship between an app and an external identity provider — Microsoft Learn.# official documentation · checked November 10, 2026 (full page text)
Update history
- — First published.
Related guides
3 jobs- job/github-oidc-trust-aws category CI/CD federation
One workflow, three clouds: how AWS, Azure and Google Cloud match GitHub OIDC tokens
The same GitHub Actions token is checked three different ways. A side-by-side comparison of where the trust lives, how claims are matched, wildcard support, limits and how failures show up.
· 7 min - job/oidc-subject-recycling category Risks
Subject recycling: when a deleted GitHub name still unlocks your cloud role
Trust rules that match names can be satisfied by whoever registers that name next. What the 2026 research found, what GitHub, GitLab and the clouds changed, and how to audit your own roles.
· 7 min - job/hcp-terraform-dynamic-credentials category CI/CD federation
Scoping HCP Terraform dynamic credentials: trust for plan and apply
How HCP Terraform workload identity tokens are built, why plan and apply deserve different roles, and the trust configuration each cloud needs.
· 7 min