Allow CI_JOB_TOKEN to AssumeRoleWithWebIdentity in AWS IAM
It should be technically possible to authenticate to AWS' IAM and assume a role using CI_JOB_TOKEN
. On AWS side, we just have to create an OIDC identity provider (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html) and a Role with and an sts:AssumeRoleWithWebIdentity policy.
I tried it but I found some issues:
aud
claim
JWT does not contain At first, I had this error message from AWS:
An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Missing a required claim: aud
.
I quickly found a workaround to this by adding an aud
claim containing ["https://#{Settings.gitlab.host}"]
in lib/gitlab/ci/jwt.rb
.
Indeed, the JWT does not contain an aud
claim.
iss
claim must start with https://
Second issue was that AWS requires that the iss
claim starts with https://
.
This one could also be easily worked around by modifying the same file as before.
Couldn’t retrieve verification key from your identity provider
Now the 3rd issue was a little bit more tricky to understand:
An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Couldn’t retrieve verification key from your identity provider, please reference AssumeRoleWithWebIdentity documentation for requirements
In current version of GitLab, there is actually 2 keys to sign JWT. One used when you create Applications and use its client_id and client_secret in your project. This key's informations are exposed in the jwks_uri declared in the discovery URL (/.well-known/openid-configuration
). The other one is used to sign CI_JOB_TOKEN
and its informations are exposed via /-/jwks/
which is not the jwks_uri
declared in the discovery URL.
To validate that this is the real issue, I modified nginx's configuration to make /.well-known/openid-configuration
point to a static file that contains a modified version with jwks_uri
pointing to /-/jwks
.
And now I can assume a role using CI_JOB_TOKEN
. First victory, but...
Not all claims are available for conditions
Now that I can assume a role, I'd like a set some conditions.
First condition is that the audience matches the audience set in CI_JOB_TOKEN
. That one works because IAM read this claim. The only other almost relevant claim that I can use is sub
, but it is not really useful as it contains job_<job-id>
.
What I'd really like to be able to do is set conditions towards the project_id
or project_name
, pipeline_source
, ref_protected
... But I couldn't figure out how to do it...
So for now I'm stuck...
I created a MR to fix at least the first 2 issues (#71657), I could try to figure out how to properly fix the 3rd one (wrong jwks URI), but I can't see how I could fix the 4th one.