Add CI_JOB_JWT_V2 for use with additional additional OIDC Providers

Merged Brad Downey requested to merge bdowney-add-jwt-aud into master

What does this MR do and why?

The primary objective is to allow AWS OpenID to use the CI_JOB_JWT to authenticate. The MVC of the CI_JOB_JWT was targeted at Vault as an OICD Provider. Vault is more flexible and allows the configuration of multiple parameters. AWS however expects a few additional things.

Due to the breaking nature of the change needed to support AWS OIDC and others. We will implement a new second Predefined CI Variable.

Example implementation:

  1. No change to CI_JOB_JWT.
  2. Add CI_JOB_JWT_V1 which will have the same value as the current CI_JOB_JWT which can live as long as needed.
  3. Add CI_JOB_JWT_V2 which will add the aud field and the modification of iss are required for compatibility. Modification of iss needing to contain https:// and aud eq base_url.

A future iteration could be to change CI_JOB_JWT to equal the value of CI_JOB_JWT_V2 and the future depreciation of CI_JOB_JWT_V1.

Adding CI_JOB_JWT_V2 will allow for AWS OIDC and other providers to take advantage of GitLab's CI JWT Token to authenticate a pipeline job that needs access to resources based on that jobs origin (i.e. project and branch).

  1. Adding aud field to the Runner JWT token to accommodate OIDC clients that require a value (i.e. AWS)
  2. Update the iss field in the Runner JWT token to follow a know practice that uses ${iss}/.well-known/openid-configuration to discover jwks_uri (i.e. https://gitlab.example.com).
  3. Update the sub field in the Runner JWT token to allow for pattern matching (authentication) within the sub field. job_ID has little value as it is not a predictable or stable value.

The original MVC and testing of JWT was targeted to enable Hashicorp Vault integration.

In attempting to do an MVC to broaden support to AWS IAM, we have discovered the need for these changes.

These changes are also needed to embrace even more OpenID plans in future MVCs.

The demand validation for this change consists of:

Testing

The following tests need to be conducted to ensure both forward and backward compatibility, or documented breaking changes.

  • Vault integration based on this example with special attention to the format of bound_issuer in vault write auth/jwt/config step.
  • AWS OpenID authentication based on this example project.
  • GCP Workload identity federation based on this example project.
  • Hashicorp Terraform based on #216259 (closed)

Screenshots or screen recordings

These are strongly recommended to assist reviewers and reduce the time to merge your change.

How to set up and validate locally

Numbered steps to set up and validate the change are strongly suggested.

  1. Test using GDK on GitPod, just click the "Open in GitPod on this MR"
  2. To properly test is to change doorkeeper_openidconnect to use https. Change documented here.
  3. Restart GDK using gdk restart rails-web
  4. Run a pipeline to capture the CI_JOB_JWT_V2, example here
GitLab JWT for Reference
{
  "header": {
    "alg": "RS256",
    "kid": "fxxEhbdTY5ZWLM45-l8naD-0JJlFYux1ILCThCjwpEs",
    "typ": "JWT"
  },
  "payload": {
    "namespace_id": "24",
    "namespace_path": "Commit451",
    "project_id": "20",
    "project_path": "Commit451/aws-jwt-auth",
    "user_id": "1",
    "user_login": "root",
    "user_email": "admin@example.com",
    "pipeline_id": "189",
    "pipeline_source": "web",
    "job_id": "545",
    "ref": "main",
    "ref_type": "branch",
    "ref_protected": "true",
    "jti": "edc8c315-b42c-4f7d-8526-bca73e461980",
    "iss": "https://3000-orange-aphid-p1u63nx4.ws-us18.gitpod.io",
    "iat": 1637348605,
    "nbf": 1637348600,
    "exp": 1637352205,
    "sub": "project_path:Commit451/aws-jwt-auth:ref_type:branch:ref:main",
    "aud": "https://3000-orange-aphid-p1u63nx4.ws-us18.gitpod.io"
  },
  "signature": "A8JgCTUx5i_3lvDyJujLWu7o8cA_wNc3oOwzkVv8Iylajrnjgb7h0tMNCl1ZjiGM6IocJDYWaVyf87xF4t2lXPNj72YYCKlnGmGhY4b1UwytgNaNP1IOyzOa1tuLPgn-nlmsDcPV3nS17H_aBdMDt5g5dEBcwSXpYMsbn1-a9fzQGf3CuBe6UxwtjG9BE0JLP8r7GvB433lv940LuakFDyQfmgKHbfgYaMlXzlv-qga0_lgnVv45uQcY-_zKWXVQZ7uX-J6dBCY86uBE5ZMSIaf50E-yxgqS5Z5cl-t7xgOcnxH65r9UEq6OIl9JRNsw49N-eP_g54khy5bN12KdJA\n"
}
GitHub JWT for Reference Pulled from https://github.com/magic7s/jwt-test as of 2021-11-18
{
  "header": {
    "typ": "JWT",
    "alg": "RS256",
    "x5t": "uguWNAR3UVzyy6nI6B311w21UNg",
    "kid": "BA0B96340477515CF2CBA9C8E81DF5D70DB550D8"
  },
  "payload": {
    "jti": "d683815f-935c-4dfe-b491-11f9d4863077",
    "sub": "repo:magic7s/jwt-test:ref:refs/heads/main",
    "aud": "sts.amazonaws.com",
    "ref": "refs/heads/main",
    "sha": "75c7cd0fc8cb4eef0dcc40fe6e543738487eb49e",
    "repository": "magic7s/jwt-test",
    "repository_owner": "magic7s",
    "run_id": "1478099523",
    "run_number": "10",
    "run_attempt": "1",
    "actor": "magic7s",
    "workflow": "CI",
    "head_ref": "",
    "base_ref": "",
    "event_name": "push",
    "ref_type": "branch",
    "job_workflow_ref": "magic7s/jwt-test/.github/workflows/main.yml@refs/heads/main",
    "iss": "https://token.actions.githubusercontent.com",
    "nbf": 1637264532,
    "exp": 1637265432,
    "iat": 1637265132
  },
  "signature": "DimNuSjFJ5SyYgF8UyQD4Uf42GsgxGFoFK-rTh9xvTvhac0bAGGsUD0z62Izdys73m4PX5eWZ3DEmHdpxXBqLkaxCbfHU641vhDI-WOOHKfU3_IHA7yJ_sMzt9vEwdrl8TR2zKyzOGQQdL4yH_cT-Gd6h3q9o0gEtvQoCyEYwDXKZTJNr7aihcDTf7zV2MIbK74TXNeESlwkAkdsO-BaeRgjbsAxVQUEwn-JLtjSjb834Z6Noq5NT1-2iBuLW0WORnX3kukQuXg67wj4latgbMhMuj4f4ZWZaewI77LkLXMCwiN1voSVnrJyEPSuWGMENhnRkSBgxImER_LbD8iklg\n"
}

MR acceptance checklist

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

Edited by Brad Downey