OpenID Connect (OIDC) Authentication Using ID Tokens

You can authenticate with third party services using GitLab CI/CD’s ID tokens.

ID Tokens

ID tokens are JSON Web Tokens (JWTs) that can be added to a GitLab CI/CD job. They can be used for OIDC authentication with third-party services, and are used by the secrets keyword to authenticate with HashiCorp Vault.

ID tokens are configured in the .gitlab-ci.yml. For example:

job_with_id_tokens:
  id_tokens:
    FIRST_ID_TOKEN:
      aud: https://first.service.com
    SECOND_ID_TOKEN:
      aud: https://second.service.com
  script:
    - first-service-authentication-script.sh $FIRST_ID_TOKEN
    - second-service-authentication-script.sh $SECOND_ID_TOKEN

In this example, the two tokens have different aud claims. Third party services can be configured to reject tokens that do not have an aud claim matching their bound audience. Use this functionality to reduce the number of services with which a token can authenticate. This reduces the severity of having a token compromised.

Token payload

The following fields are included in each ID token:

FieldWhenDescription
audAlwaysIntended audience for the token (“audience” claim). Configured in GitLab the CI/CD configuration. The domain of the GitLab instance by default.
expAlwaysThe expiration time (“expiration time” claim).
iatAlwaysThe time the JWT was issued (“issued at” claim).
issAlwaysIssuer of the token, which is the domain of the GitLab instance (“issuer” claim).
jtiAlwaysUnique identifier for the token (“JWT ID” claim).
nbfAlwaysThe time after which the token becomes valid (“not before” claim).
subAlwaysThe job ID (“subject” claim).
deployment_tierJob specifies an environment Deployment tier of the environment the job specifies. Introduced in GitLab 15.2.
environment_protectedJob specifies an environment true if specified environment is protected, false otherwise. Introduced in GitLab 13.9.
environmentJob specifies an environmentEnvironment the job specifies. Introduced in GitLab 13.9.
job_idAlwaysID of the job.
namespace_idAlwaysUse to scope to group or user level namespace by ID.
namespace_pathAlwaysUse to scope to group or user level namespace by path.
pipeline_idAlwaysID of the pipeline.
pipeline_sourceAlways Pipeline source.
project_idAlwaysUse to scope to project by ID.
project_pathAlwaysUse to scope to project by path.
ref_protectedAlways true if the Git ref is protected, false otherwise.
ref_typeAlwaysGit ref type, either branch or tag.
refAlwaysGit ref for the job.
user_emailAlwaysEmail of the user executing the job.
user_idAlwaysID of the user executing the job.
user_loginAlwaysUsername of the user executing the job.

Example ID token payload:

{
  "jti": "c82eeb0c-5c6f-4a33-abf5-4c474b92b558",
  "aud": "hashicorp.example.com",
  "iss": "gitlab.example.com",
  "iat": 1585710286,
  "nbf": 1585798372,
  "exp": 1585713886,
  "sub": "job_1212",
  "namespace_id": "1",
  "namespace_path": "mygroup",
  "project_id": "22",
  "project_path": "mygroup/myproject",
  "user_id": "42",
  "user_login": "myuser",
  "user_email": "myuser@example.com",
  "pipeline_id": "1212",
  "pipeline_source": "web",
  "job_id": "1212",
  "ref": "auto-deploy-2020-04-01",
  "ref_type": "branch",
  "ref_protected": "true",
  "environment": "production",
  "environment_protected": "true"
}

The ID token is encoded by using RS256 and signed with a dedicated private key. The expiry time for the token is set to the job’s timeout if specified, or 5 minutes if no timeout is specified.

Manual ID Token authentication

You can use ID tokens for OIDC authentication with a third party service. For example:

manual_authentication:
  variables:
    VAULT_ADDR: http://vault.example.com:8200
  image: vault:latest
  id_tokens:
    VAULT_ID_TOKEN:
      aud: http://vault.example.com:8200
  script:
    - export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=myproject-example jwt=$VAULT_ID_TOKEN)"
    - export PASSWORD="$(vault kv get -field=password secret/myproject/example/db)"
    - my-authentication-script.sh $VAULT_TOKEN $PASSWORD

Automatic ID Token authentication with HashiCorp Vault

You can use ID tokens to automatically fetch secrets from HashiCorp Vault with the secrets keyword.

Enable automatic ID token authentication

To enable automatic ID token authentication:

  1. On the top bar, select Main menu > Projects and find your project.
  2. On the left sidebar, select Settings > CI/CD.
  3. Expand Token Access.
  4. Toggle Limit JSON Web Token (JWT) access to enabled.

Configure automatic ID Token authentication

If one ID token is defined, the secrets keyword automatically uses it to authenticate with Vault. For example:

job_with_secrets:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://example.vault.com
  secrets:
    PROD_DB_PASSWORD:
      vault: example/db/password # authenticates using $VAULT_ID_TOKEN
  script:
    - access-prod-db.sh --token $PROD_DB_PASSWORD

If more than one ID token is defined, use the token keyword to specify which token should be used. For example:

job_with_secrets:
  id_tokens:
    FIRST_ID_TOKEN:
      aud: https://first.service.com
    SECOND_ID_TOKEN:
      aud: https://second.service.com
  secrets:
    FIRST_DB_PASSWORD:
      vault: first/db/password
      token: $FIRST_ID_TOKEN
    SECOND_DB_PASSWORD:
      vault: second/db/password
      token: $SECOND_ID_TOKEN
  script:
    - access-first-db.sh --token $FIRST_DB_PASSWORD
    - access-second-db.sh --token $SECOND_DB_PASSWORD