Embed dedicated JWT container user info in container registry JWT
What does this MR do and why?
In this MR, we add an encrypted user
field to the JWT claims. This new fields contains fields that Rails will need to identify which user or deploy token made the request and increment usage metrics. The registry, upon receiving this encrypted user
object, will simply pass it back to Rails as part of the event notification payload.
Background
As part of Container Registry GMAU: Track usage (&8213), we keep track of container registry usage by using webhook notifications emitted by the registry and consumed by GitLab Rails. In Container Registry: Process webhook notificatio... (#385497 - closed) we started tracking tag creation and deletion, followed by Container Registry: Process webhook notificatio... (#382568 - closed).
The event notification payload contains an actor: {}
object with a name
and a user_type
key in it as defined in the registry documentation. The registry populates this information, based on the JWT claims offered by the /jwt/auth
endpoint on a successful user authentication
With `name it is not enough to fetch which deploy token it is so we need more information which is added in this MR.
Current behavior
- Checkout the
master
branch (git checkout master
) - In your terminal, obtain a JWT token (i.e. with
pull
permissions for repositorygitlab-org/gitlab-test/foo
). Replacepassword
with your local password:
http -a root:'password' http://gdk.test:3000/jwt/auth client_id=="docker" service=="container_registry" scope=="repository:gitlab-org/gitlab-test/foo:pull" | jq -r '.token' | jwt decode -
Output (timestamps will vary):
Token header
------------
{
"typ": "JWT",
"alg": "RS256",
"kid": "MZ6P:4ZAC:TVCN:SJ7O:MP5A:OVMJ:KQL5:FC43:SBDR:6H2K:HBO2:IZ7M"
}
Token claims
------------
{
"access": [
{
"actions": [
"pull"
],
"meta": {
"project_path": "gitlab-org/gitlab-test"
},
"name": "gitlab-org/gitlab-test/foo",
"type": "repository"
}
],
"aud": "container_registry",
"auth_type": "gitlab_or_ldap",
"exp": 1690617690,
"iat": 1690617390,
"iss": "gitlab-issuer",
"jti": "db6b2f72-60f3-40d2-8259-4a2a6751468f",
"nbf": 1690617385,
"sub": "root"
}
New behavior
- Check out this MR's branch:
git checkout 394965-add-user-info-to-jwt
- Obtain a JWT, same as above, and observe the new
user
field
http -a root:'password' http://gdk.test:3000/jwt/auth client_id=="docker" service=="container_registry" scope=="repository:gitlab-org/gitlab-test/foo:pull" | jq -r '.token' | jwt decode -
Token header
------------
{
"typ": "JWT",
"alg": "RS256",
"kid": "MZ6P:4ZAC:TVCN:SJ7O:MP5A:OVMJ:KQL5:FC43:SBDR:6H2K:HBO2:IZ7M"
}
Token claims
------------
{
"access": [
{
"actions": [
"pull"
],
"meta": {
"project_path": "gitlab-org/gitlab-test"
},
"name": "gitlab-org/gitlab-test/foo",
"type": "repository"
}
],
"aud": "container_registry",
"auth_type": "gitlab_or_ldap",
"exp": 1690616353,
"iat": 1690616053,
"iss": "gitlab-issuer",
"jti": "436c0373-af8a-4efd-bf3a-abc7ce1e98ab",
"nbf": 1690616048,
"sub": "root",
"user": "eyJraWQiOiJNWjZQOjRaQUM6VFZDTjpTSjdPOk1QNUE6T1ZNSjpLUUw1OkZDNDM6U0JEUjo2SDJLOkhCTzI6SVo3TSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJ1c2VyX2luZm8iOnsidG9rZW5fdHlwZSI6ImdpdGxhYl9vcl9sZGFwIiwidXNlcm5hbWUiOiJyb290IiwidXNlcl9pZCI6MX0sImp0aSI6IjBhMjU5YzRhLTUwZjQtNDRlNS05ODlhLWE0MGE4M2E3ZDE4OCIsImlhdCI6MTY5MDYxNjA1MywibmJmIjoxNjkwNjE2MDQ4LCJleHAiOjE2OTA2MTYxMTN9.aSqUCvCUTvgmbbcSOA-FGYG2suRS1SOm6kreeaYWk7FEnq9ZV7p1bGXbH7EQyZxyk7n9i3vWk6gbThLQJlnb0GmFfhbVC1cU9ndSBz07PNXl-1qu5sNQDeEjM0mtyMNtyMXGFYeBXh6YF8ic6YISyLS-co9INy9neyu1Vqs00HbdACGKnHrio2tSfUgXPwLWFG-t6_sUal0xk0vbqKu77SkmWKsqrTb27sMXHnJFwkmfN2AaAaNuXkwF4GRO5XfTU2pkTz2M7N5XIljC4lA_GYqRSgjdaFB_-ZijE55mFM3DRbXKwxEDD-jQOOZLiztxzvsnZF4n6Bv6VEiunA3ukA"
}
- Copy the value of
user
and paste it into a JWT decoder like https://jwt.io or you can also use the command line:
jwt decode "eyJraWQiOiJNWjZQOjRaQUM6VFZDTjpTSjdPOk1QNUE6T1ZNSjpLUUw1OkZDNDM6U0JEUjo2SDJLOkhCTzI6SVo3TSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJ1c2VyX2luZm8iOnsidG9rZW5fdHlwZSI6ImdpdGxhYl9vcl9sZGFwIiwidXNlcm5hbWUiOiJyb290IiwidXNlcl9pZCI6MX0sImp0aSI6IjBhMjU5YzRhLTUwZjQtNDRlNS05ODlhLWE0MGE4M2E3ZDE4OCIsImlhdCI6MTY5MDYxNjA1MywibmJmIjoxNjkwNjE2MDQ4LCJleHAiOjE2OTA2MTYxMTN9.aSqUCvCUTvgmbbcSOA-FGYG2suRS1SOm6kreeaYWk7FEnq9ZV7p1bGXbH7EQyZxyk7n9i3vWk6gbThLQJlnb0GmFfhbVC1cU9ndSBz07PNXl-1qu5sNQDeEjM0mtyMNtyMXGFYeBXh6YF8ic6YISyLS-co9INy9neyu1Vqs00HbdACGKnHrio2tSfUgXPwLWFG-t6_sUal0xk0vbqKu77SkmWKsqrTb27sMXHnJFwkmfN2AaAaNuXkwF4GRO5XfTU2pkTz2M7N5XIljC4lA_GYqRSgjdaFB_-ZijE55mFM3DRbXKwxEDD-jQOOZLiztxzvsnZF4n6Bv6VEiunA3ukA"
Output:
Token header
------------
{
"typ": "JWT",
"alg": "RS256",
"kid": "MZ6P:4ZAC:TVCN:SJ7O:MP5A:OVMJ:KQL5:FC43:SBDR:6H2K:HBO2:IZ7M"
}
Token claims
------------
{
"exp": 1690616113,
"iat": 1690616053,
"jti": "0a259c4a-50f4-44e5-989a-a40a83a7d188",
"nbf": 1690616048,
"user_info": {
"token_type": "gitlab_or_ldap",
"user_id": 1,
"username": "root"
}
}
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Related to #394965 (closed)