When a user runs a pipeline, then a secure token is generated and used to execute the pipeline
Why are we doing this work
Currently, before a Ci::Build starts, a CI_JOB_TOKEN is injected into the job’s environment variables, granting the job a broad range of access to GitLab APIs.
We aim to replace this static token with an ephemeral, scoped token that carries just enough context to make an authorization decision specific to each job.
This will allow us to minimize the scope of access for each job, aligning with the Principle of Least Privilege (PoLP).
By scoping down the token's access, we can limit each job's API permissions based on the requirements set by Pipeline Authors and Project Owners. This helps reduce security risks by preventing over-permissioned tokens.
Approach
We will generate a JWT that encodes the permissions currently granted to the CI_JOB_TOKEN.
The JWT will contain sufficient context to authorize API requests while restricting access to only the necessary permissions.
When generating the token, we will check if the user who triggered the build has the ability to perform these permissions on the source Ci::Build, Ci::Pipeline, and Ci::Project.
The CI_JOB_TOKEN will follow this JWT structure, based on the permission
models discussed:
{
"sub": "gid://gitlab/Ci/Build/1",
"exp": 1893456000,
"scope": {
"build_read_project": ["gid://gitlab/Project/13083"],
"update_pipeline": ["gid://gitlab/Project/13083", "gid://gitlab/Ci::Pipeline/1"]
}
}
-
sub: The subject of the token, represented as a Global ID. -
exp: Token expiration, usually tied to the maximum duration of the CI job. -
scope: Permissions associated with the token, bound to specific resources by Global ID.
A reference implementation of this can be found here and the list of permissions that we will limit Job Tokens to can be found here.
Relevant links
Implementation Plan
-
Replace the current static CI_JOB_TOKENwith a dynamically generated JWT that encodes job-specific permissions. -
Introduce a feature flag to control the rollout of JWT-based CI_JOB_TOKENfor selective users.
Verification Steps
-
Validate that the JWT is generated correctly with job-specific permissions. -
Test token expiry. -
Enable the feature flag and confirm that the new JWT system works without disrupting existing jobs.