Skip to content

Add auth_type to jwt controller token payload

What does this MR do and why?

The container registry authenticates through the GitLab rails project. Docker clients request JWTs from the rails-based jwt_controller, which are then used to make requests to the registry. This allows us to authenticate and authorize users for their projects and container repositories.

In this MR, we add an auth_type value to the JWT payload. This will be used to add the ability to filter by token type within the registry logs.

Screenshots or screen recordings

Requesting access with a personal access token:

~ curl -u "personal_access_token:$TOKEN" http://gdk.test:3000/jwt/auth/\?service\=container_registry | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   759  100   759    0     0   3885      0 --:--:-- --:--:-- --:--:--  3973
{
  "token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IkFTT006R09LRTo2UVJCOkNNRlQ6SEc3Wjo3VkM3Ok42Q006NVRNRDpNTVFPOkZaU0o6Q1RYNjo0REVZIiwidHlwIjoiSldUIn0.eyJhdXRoX3R5cGUiOiJwZXJzb25hbF9hY2Nlc3NfdG9rZW4iLCJhY2Nlc3MiOltdLCJqdGkiOiJkMGUwMGJkZS1lYzBkLTQ3YjMtODNlMi0zNjJhNzE2YzJjMDkiLCJhdWQiOiJjb250YWluZXJfcmVnaXN0cnkiLCJzdWIiOiJyb290IiwiaXNzIjoiZ2l0bGFiLWlzc3VlciIsImlhdCI6MTY2MzEzNDE5MiwibmJmIjoxNjYzMTM0MTg3LCJleHAiOjE2NjMxMzQ0OTJ9.lwT-IXgV-jFgXsO04g390Ya-QWhS94DrZ5ZX-ukjI2JeBoCRj2Ye8pSWBC0yPKqptS4__2Z8jKFQifBJbqqCwpAxb8XKoopu3myJcCk-lLg9CuKMj8uWpYGtt2BX9Rxe-E4z5TUHFxsciM0KfGewCL7XXvUwuzjwFhrrENXfxY-U2Snjl8E9D2_6ioV7YxSkTdgN8MRETU7ojrncdZ_yT49rlopttgQSOH-WCI6xdWSbtjHO9S9AxA-H2Vp7QXu__h3fGe1U-kSkf7yO9e-nc1EmncLhv2h0nBFQzSRVCLQFb7TfItFCvXlcXgm0QHnz1bKOBv5P_FCORA9GrDYKEg"
}

Checking the token payload - "auth_type"=>"personal_access_token" is present:

[26] pry(main)> token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6IkFTT006R09LRTo2UVJCOkNNRlQ6SEc3Wjo3VkM3Ok42Q006NVRNRDpNTVFPOkZaU0o6Q1RYNjo0REVZIiwidHlwIjoiSldUIn0.eyJhdXRoX3R5cGUiOiJwZXJzb25hbF9hY2Nlc3NfdG9rZW4iLCJhY2Nlc3MiOltdLCJqdGkiOiJkMGUwMGJkZS1lYzBkLTQ3YjMtODNlMi0zNjJhNzE2YzJjMDkiLCJhdWQiOiJjb250YWluZXJfcmVnaXN0cnkiLCJzdWIiOiJyb290IiwiaXNzIjoiZ2l0bGFiLWlzc3VlciIsImlhdCI6MTY2MzEzNDE5MiwibmJmIjoxNjYzMTM0MTg3LCJleHAiOjE2NjMxMzQ0OTJ9.lwT-IXgV-jFgXsO04g390Ya-QWhS94DrZ5ZX-ukjI2JeBoCRj2Ye8pSWBC0yPKqptS4__2Z8jKFQifBJbqqCwpAxb8XKoopu3myJcCk-lLg9CuKMj8uWpYGtt2BX9Rxe-E4z5TUHFxsciM0KfGewCL7XXvUwuzjwFhrrENXfxY-U2Snjl8E9D2_6ioV7YxSkTdgN8MRETU7ojrncdZ_yT49rlopttgQSOH-WCI6xdWSbtjHO9S9AxA-H2Vp7QXu__h3fGe1U-kSkf7yO9e-nc1EmncLhv2h0nBFQzSRVCLQFb7TfItFCvXlcXgm0QHnz1bKOBv5P_FCORA9GrDYKEg'
=> "eyJhbGciOiJSUzI1NiIsImtpZCI6IkFTT006R09LRTo2UVJCOkNNRlQ6SEc3Wjo3VkM3Ok42Q006NVRNRDpNTVFPOkZaU0o6Q1RYNjo0REVZIiwidHlwIjoiSldUIn0.eyJhdXRoX3R5cGUiOiJwZXJzb25hbF9hY2Nlc3NfdG9rZW4iLCJhY2Nlc3MiOltdLCJqdGkiOiJkMGUwMGJkZS1lYzBkLTQ3YjMtODNlMi0zNjJhNzE2YzJjMDkiLCJhdWQiOiJjb250YWluZXJfcmVnaXN0cnkiLCJzdWIiOiJyb290IiwiaXNzIjoiZ2l0bGFiLWlzc3VlciIsImlhdCI6MTY2MzEzNDE5MiwibmJmIjoxNjYzMTM0MTg3LCJleHAiOjE2NjMxMzQ0OTJ9.lwT-IXgV-jFgXsO04g390Ya-QWhS94DrZ5ZX-ukjI2JeBoCRj2Ye8pSWBC0yPKqptS4__2Z8jKFQifBJbqqCwpAxb8XKoopu3myJcCk-lLg9CuKMj8uWpYGtt2BX9Rxe-E4z5TUHFxsciM0KfGewCL7XXvUwuzjwFhrrENXfxY-U2Snjl8E9D2_6ioV7YxSkTdgN8MRETU7ojrncdZ_yT49rlopttgQSOH-WCI6xdWSbtjHO9S9AxA-H2Vp7QXu__h3fGe1U-kSkf7yO9e-nc1EmncLhv2h0nBFQzSRVCLQFb7TfItFCvXlcXgm0QHnz1bKOBv5P_FCORA9GrDYKEg"
[27] pry(main)> JWT.decode(token, nil, false)
=> [{"auth_type"=>"personal_access_token", "access"=>[], "jti"=>"d0e00bde-ec0d-47b3-83e2-362a716c2c09", "aud"=>"container_registry", "sub"=>"root", "iss"=>"gitlab-issuer", "iat"=>1663134192, "nbf"=>1663134187, "exp"=>1663134492},
 {"alg"=>"RS256", "kid"=>"ASOM:GOKE:6QRB:CMFT:HG7Z:7VC7:N6CM:5TMD:MMQO:FZSJ:CTX6:4DEY", "typ"=>"JWT"}]

Testing with user login:

curl -u "root:5iveL\!fe" http://gdk.test:3000/jwt/auth/\?service\=container_registry | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   750  100   750    0     0   2026      0 --:--:-- --:--:-- --:--:--  2054
{
  "token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IkFTT006R09LRTo2UVJCOkNNRlQ6SEc3Wjo3VkM3Ok42Q006NVRNRDpNTVFPOkZaU0o6Q1RYNjo0REVZIiwidHlwIjoiSldUIn0.eyJhdXRoX3R5cGUiOiJnaXRsYWJfb3JfbGRhcCIsImFjY2VzcyI6W10sImp0aSI6IjM1MWRlMDI3LWQwNmItNDRhNy1hNTE5LTM4YmNiNTk2ZDMwOCIsImF1ZCI6ImNvbnRhaW5lcl9yZWdpc3RyeSIsInN1YiI6InJvb3QiLCJpc3MiOiJnaXRsYWItaXNzdWVyIiwiaWF0IjoxNjYzMTM0MzYzLCJuYmYiOjE2NjMxMzQzNTgsImV4cCI6MTY2MzEzNDY2M30.XgiuhCIXp2KM9WXU4nyo7uofk9klUp7PGw502DPauH3hPuJUaYyG_cKMwQE4v9yTXqCxhL-XFm3MGTCzhIh0xrNRIhTdJny-0g6-2rnXPRvfBMWr7QbuvWtT1DupOttPuFMkjeMiS2hKfyPUNsKjZJ081QJIQhpkjKrwb8Jb5Si1bmmq4sAG1c_s4ewuORFyI7JLDQF0oKEw8Bfw5EQJojjEY0QH72FriBlJ52Sg-LTkzEQ7lCTYgRLlH0wqEIpMSp5e6xJUFnSa8Mae_QhkaGLfq07hr0QhIEbdbOk69wBoHWPV-G0B-P3SRrmdRuW_aFNxYm99Jemju3ohw4LmGQ"
}

Checking the token payload - "auth_type"=>"gitlab_or_ldap" is present:

[28] pry(main)> token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6IkFTT006R09LRTo2UVJCOkNNRlQ6SEc3Wjo3VkM3Ok42Q006NVRNRDpNTVFPOkZaU0o6Q1RYNjo0REVZIiwidHlwIjoiSldUIn0.eyJhdXRoX3R5cGUiOiJnaXRsYWJfb3JfbGRhcCIsImFjY2VzcyI6W10sImp0aSI6IjM1MWRlMDI3LWQwNmItNDRhNy1hNTE5LTM4YmNiNTk2ZDMwOCIsImF1ZCI6ImNvbnRhaW5lcl9yZWdpc3RyeSIsInN1YiI6InJvb3QiLCJpc3MiOiJnaXRsYWItaXNzdWVyIiwiaWF0IjoxNjYzMTM0MzYzLCJuYmYiOjE2NjMxMzQzNTgsImV4cCI6MTY2MzEzNDY2M30.XgiuhCIXp2KM9WXU4nyo7uofk9klUp7PGw502DPauH3hPuJUaYyG_cKMwQE4v9yTXqCxhL-XFm3MGTCzhIh0xrNRIhTdJny-0g6-2rnXPRvfBMWr7QbuvWtT1DupOttPuFMkjeMiS2hKfyPUNsKjZJ081QJIQhpkjKrwb8Jb5Si1bmmq4sAG1c_s4ewuORFyI7JLDQF0oKEw8Bfw5EQJojjEY0QH72FriBlJ52Sg-LTkzEQ7lCTYgRLlH0wqEIpMSp5e6xJUFnSa8Mae_QhkaGLfq07hr0QhIEbdbOk69wBoHWPV-G0B-P3SRrmdRuW_aFNxYm99Jemju3ohw4LmGQ'
=> "eyJhbGciOiJSUzI1NiIsImtpZCI6IkFTT006R09LRTo2UVJCOkNNRlQ6SEc3Wjo3VkM3Ok42Q006NVRNRDpNTVFPOkZaU0o6Q1RYNjo0REVZIiwidHlwIjoiSldUIn0.eyJhdXRoX3R5cGUiOiJnaXRsYWJfb3JfbGRhcCIsImFjY2VzcyI6W10sImp0aSI6IjM1MWRlMDI3LWQwNmItNDRhNy1hNTE5LTM4YmNiNTk2ZDMwOCIsImF1ZCI6ImNvbnRhaW5lcl9yZWdpc3RyeSIsInN1YiI6InJvb3QiLCJpc3MiOiJnaXRsYWItaXNzdWVyIiwiaWF0IjoxNjYzMTM0MzYzLCJuYmYiOjE2NjMxMzQzNTgsImV4cCI6MTY2MzEzNDY2M30.XgiuhCIXp2KM9WXU4nyo7uofk9klUp7PGw502DPauH3hPuJUaYyG_cKMwQE4v9yTXqCxhL-XFm3MGTCzhIh0xrNRIhTdJny-0g6-2rnXPRvfBMWr7QbuvWtT1DupOttPuFMkjeMiS2hKfyPUNsKjZJ081QJIQhpkjKrwb8Jb5Si1bmmq4sAG1c_s4ewuORFyI7JLDQF0oKEw8Bfw5EQJojjEY0QH72FriBlJ52Sg-LTkzEQ7lCTYgRLlH0wqEIpMSp5e6xJUFnSa8Mae_QhkaGLfq07hr0QhIEbdbOk69wBoHWPV-G0B-P3SRrmdRuW_aFNxYm99Jemju3ohw4LmGQ"
[29] pry(main)> JWT.decode(token, nil, false)
=> [{"auth_type"=>"gitlab_or_ldap", "access"=>[], "jti"=>"351de027-d06b-44a7-a519-38bcb596d308", "aud"=>"container_registry", "sub"=>"root", "iss"=>"gitlab-issuer", "iat"=>1663134363, "nbf"=>1663134358, "exp"=>1663134663},
 {"alg"=>"RS256", "kid"=>"ASOM:GOKE:6QRB:CMFT:HG7Z:7VC7:N6CM:5TMD:MMQO:FZSJ:CTX6:4DEY", "typ"=>"JWT"}]

How to set up and validate locally

Normally a docker client would make a request for the token, but since we want to be able to inspect the token, we are going to just use curl to see the response output.

  1. Make sure the container registry is enabled in your GDK. This is the minimum update to gdk.yml needed followed by a gdk reconfigure and gdk restart
    registry:
      enabled: true
  2. Make a request to the JWT endpoint using curl (Note: you may need to escape the ! in the standard gdk password in the request as shown below):
    curl -u "root:5iveL\!fe" http://gdk.test:3000/jwt/auth/?service=container_registry
  3. Copy the token value from the payload. You can decode it using a tool like this https://jwt.io/ or you can do it in the rails console:
    token = '<paste_token>'
    JWT.decode(token, nil, false)
  4. The output should show "auth_type"=>"gitlab_or_ldap"
  5. Try this with other tokens like personal access tokens, deploy tokens, or ci job tokens to see the value reflected correctly.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #350880 (closed)

Edited by Steve Abrams

Merge request reports

Loading