Safeguard
Security Guides•

How do GitLab CI id_tokens work for cloud login?

GitLab CI id_tokens give a job a short signed token a cloud can verify. Learn aud, the sub format, ref_protected and why project_id beats names.

Safeguard Security Team
4 min read

GitLab CI lets a job declare id_tokens, each a short lived signed token with its own audience. A cloud provider that trusts GitLab can check the token's claims and issue temporary credentials, so you store no long term key. Your trust policy should rely on stable IDs and protected refs.

How the keyword works

In .gitlab-ci.yml you declare one or more named tokens under id_tokens in a job, each with its own settings. The tokens are then available as variables in script, before_script and after_script. GitLab's example defines two tokens with different audiences and passes each to a separate authentication script.

The audience is set per token. If you omit it, it defaults to the GitLab instance domain. Use a distinct one for every service you authenticate to.

The claims that matter

ClaimWhat it tells the cloud
subDefault format is the project path with ref type and ref, for example project_path:my-group/my-project:ref_type:branch:ref:feature-branch-1
ref_protectedAlways present. True if the Git ref is protected, false otherwise
project_id, namespace_idStable numeric identifiers
audThe audience you configured

GitLab documents that since version 18.7 the subject can also include ref_protected, plus environment_protected and deployment_tier when a job specifies an environment.

Writing a trust policy that survives renames

Project paths change when a project is renamed or moved. GitLab's guidance is to include stable identifiers alongside sub, noting that project_id is globally unique and remains the same for the life of the project. It also warns that if a project_path was previously used by another project, token issuance may be blocked until you switch to an ID based subject such as project_id:ID:ref_type:TYPE:ref:REF.

It cautions against using user_login or user_email as the sole condition, because users can change them.

Use ref_protected as a condition so only protected branches or tags can assume a deploy role. This matters because anyone who can push a branch can run a pipeline on it, but only maintainers control which branches are protected.

Provider differences to expect

GitLab says that on GitLab.com, AWS supports several additional condition keys for the gitlab.com provider, while on GitLab Self-Managed and GitLab Dedicated only sub is supported. If you self host, plan your conditions around sub and encode what you need into its format.

Token lifetime

Tokens are signed with RS256 using a dedicated private key. The expiry is set to the job's timeout if one is specified, or 5 minutes if not. That is short, but it still means a token printed in a job log is usable until it expires, so never echo it.

A setup you can copy in outline

  1. Declare an id_tokens entry with the audience your cloud expects.
  2. Create a role or federated identity in the cloud that trusts GitLab as an identity provider.
  3. In the trust condition, match aud, match project_id, and require ref_protected to be true for deploys.
  4. Use a second token with a different audience if the same job also talks to another service.
  5. Test on a protected branch and on an unprotected one, and confirm the second fails.

Quick check

How long does a GitLab id_token last?

GitLab sets expiry to the job's timeout if specified, or 5 minutes if no timeout is specified.

Why prefer project_id in a trust policy?

It is globally unique and unchanged for the life of the project, so renames and moves do not break or hijack the policy.

Safeguard does not manage your cloud accounts. It scans your code and dependencies, applies pull request policies and gates, and automates compliance evidence. Free scan: gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.