Add session tags to ID Tokens
What does this MR do and why?
Attempts to address #462017. There has been some interest in expanding what claims can be included in the token payload. For AWS users, AWS only supports a small number of claims. It does appear possible that we could include utilise sts:TransitiveTagKeys. Created with discussion threads with Claude and GitLab Duo.
To-Dos
-
Confirm that the AWS STS side of things accepts our payload contents with the new tags -
Spec Tests -
Figure out if we can replace aws_tagswith the actual string "https://aws.amazon.com/tags" (see below) -
Documentation
Why are you using "aws_tags"?
I have been having trouble figuring out how you can validate a URL string like: "https://aws.amazon.com/tags", as validations seem to require a valid method name (so is this a Ruby-level problem?). I was able to define the string to use for the assembled JWT payload, which works for now.
Example
Within this environment, a project has been created with the following .gitlab-ci.yml file:
stages:
- build
job_with_tokens2:
stage: build
script:
- echo "Decoding JWT payload:"
- echo $GITLAB_OIDC_TOKEN | cut -d. -f2 | base64 -d
id_tokens:
GITLAB_OIDC_TOKEN:
aud: https://gitlab.com
aws_tags:
principal_tags:
"Project": ["$CI_PROJECT_PATH"]
"Environment": ["$AWS_ENVIRONMENT_NAME"]
"PipelineIID": ["$CI_PIPELINE_IID"]
transitive_tag_keys: [
"Project",
"Environment",
"PipelineIID"
]
when: manual
For troubleshooting purposes, the contents of the token GITLAB_OIDC_TOKEN are output to the pipeline job for review. Provided below is an example without formatting:
{"namespace_id":"33","namespace_path":"flightjs","project_id":"20","project_path":"flightjs/oidc-tokens","user_id":"1","user_login":"root","user_email":"gitlab_admin_a66f32@example.com","user_access_level":"owner","pipeline_id":"615","pipeline_source":"push","job_id":"523","ref":"main","ref_type":"branch","ref_path":"refs/heads/main","ref_protected":"false","runner_id":32,"runner_environment":"self-hosted","sha":"35522d0059c3467ea2b0833c21a398d98cfe39b2","project_visibility":"private","ci_config_ref_uri":"gdk.local:3000/flightjs/oidc-tokens//.gitlab-ci.yml@refs/heads/main","ci_config_sha":"35522d0059c3467ea2b0833c21a398d98cfe39b2","jti":"2513c147-2057-4d53-85df-79c9c6d3c83d","iat":1754281542,"nbf":1754281537,"exp":1754285142,"iss":"http://gdk.local:3000","sub":"project_path:flightjs/oidc-tokens:ref_type:branch:ref:main","aud":"https://gitlab.com","https://aws.amazon.com/tags":{"principal_tags":{"Project":["flightjs/oidc-tokens"],"Environment":[""],"PipelineIID":["47"]},"transitive_tag_keys":["Project","Environment","PipelineIID"]}}
Using proper JSON formatting:
{
"aud": "https://gitlab.com",
"ci_config_ref_uri": "gdk.local:3000/flightjs/oidc-tokens//.gitlab-ci.yml@refs/heads/main",
"ci_config_sha": "35522d0059c3467ea2b0833c21a398d98cfe39b2",
"exp": 1754285142,
"https://aws.amazon.com/tags": {
"principal_tags": {
"Environment": [
""
],
"PipelineIID": [
"47"
],
"Project": [
"flightjs/oidc-tokens"
]
},
"transitive_tag_keys": [
"Project",
"Environment",
"PipelineIID"
]
},
"iat": 1754281542,
"iss": "http://gdk.local:3000",
"job_id": "523",
"jti": "2513c147-2057-4d53-85df-79c9c6d3c83d",
"namespace_id": "33",
"namespace_path": "flightjs",
"nbf": 1754281537,
"pipeline_id": "615",
"pipeline_source": "push",
"project_id": "20",
"project_path": "flightjs/oidc-tokens",
"project_visibility": "private",
"ref": "main",
"ref_path": "refs/heads/main",
"ref_protected": "false",
"ref_type": "branch",
"runner_environment": "self-hosted",
"runner_id": 32,
"sha": "35522d0059c3467ea2b0833c21a398d98cfe39b2",
"sub": "project_path:flightjs/oidc-tokens:ref_type:branch:ref:main",
"user_access_level": "owner",
"user_email": "gitlab_admin_a66f32@example.com",
"user_id": "1",
"user_login": "root"
}
This implementation allows you to provide environment variables (as you would be able to do so with aud), which will get expanded as required. This permits dynamic use of $CI_PROJECT_PATH, if it needs to be validated on the AWS side.
How to set up and validate locally
- Create a new project, ensuring a Runner has access to run pipelines for this project.
- Copy the
.gitlab-ci.ymlcontents from above, and place this into your pipeline. Validations should confirm the format is acceptable. - Run the manual job.
- Confirm in the CI/CD job output it has returned a suitable payload
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.