Commit 451b02f6 authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

feat(oidc): OIDC authentication support now requires explicit configuration (see doc)

Due to CI_JOB_JWT-* variables discontinued, TBC now switches
to ID tokens for OIDC authentication support.
Enabling OIDC authentication now requires using the OIDC variant (see doc).

BREAKING CHANGE: OIDC authentication support now requires  explicit configuration (see doc)
parent d825692e
Loading
Loading
Loading
Loading
+50 −50
Original line number Diff line number Diff line
@@ -91,28 +91,9 @@ scoped__AWS_SECRET_ACCESS_KEY__if__CI_ENVIRONMENT_NAME__equals__production: "<my

#### Federated authentication using OpenID Connect

If you wish to use this authentication mode, please follow carefully [the GitLab guide](https://docs.gitlab.com/ee/ci/cloud_services/aws/), 
then configure appropriately the related variables:

* `AWS_OIDC_ROLE_ARN` for any global/common access,
* `AWS_REVIEW_OIDC_ROLE_ARN` and/or `AWS_INTEG_OIDC_ROLE_ARN` and/or `AWS_STAGING_OIDC_ROLE_ARN` and/or `AWS_PROD_OIDC_ROLE_ARN` if you wish to use a separate role with any of your environments.

The template supports two ways to retrieve the JSON web token (JWT):

* using GitLab's `CI_JOB_JWT_V2` variable - _default_<br/>
  :warning: deprecated, scheduled to be removed in GitLab 16.5
* using an [ID token](https://docs.gitlab.com/ee/ci/yaml/index.html#id_tokens) named `AWS_JWT` - _configurable_
The AWS template supports [OpenID Connect to retrieve temporary credentials](https://docs.gitlab.com/ee/ci/cloud_services/aws/).

The ID token can be configured as follows in your `.gitlab-ci.yml` file:

```yaml
# enable AWS_JWT ID token for AWS jobs only
.aws-base:
  id_tokens:
    AWS_JWT:
      # use your own audience url here
      aud: https://gitlab.com
```
If you wish to use this authentication mode, please activate and configure the [OIDC variant](#oidc-variant). 

### Deployment context variables

@@ -242,7 +223,6 @@ The AWS template uses some global configuration used throughout all jobs and env
| `AWS_BASE_APP_NAME`      | Base application name                  | `$CI_PROJECT_NAME` ([see GitLab doc](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)) |
| `AWS_ENVIRONMENT_URL`    | Default environments url _(only define for static environment URLs declaration)_<br/>_supports late variable expansion (ex: `https://%{environment_name}.aws.acme.com`)_ | _none_ |
| `AWS_SCRIPTS_DIR`        | Directory where AWS scripts (deploy & cleanup) are located | `.` _(root project dir)_ |
| `AWS_OIDC_ROLE_ARN`    | Default IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) | _none_ (disabled) |

### Review environments configuration

@@ -256,7 +236,6 @@ Here are variables supported to configure review environments:
| Name                     | description                            | default value     |
| ------------------------ | -------------------------------------- | ----------------- |
| `AWS_REVIEW_ENABLED`     | AWS project ID for `review` env | _none_ (disabled) |
| `AWS_REVIEW_OIDC_ROLE_ARN`| IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `review` env _(only define if different from global)_ | _none_ (disabled) |
| `AWS_REVIEW_APP_NAME`    | Application name for `review` env      | `"${AWS_BASE_APP_NAME}-${CI_ENVIRONMENT_SLUG}"` (ex: `myproject-review-fix-bug-12`) |
| `AWS_REVIEW_ENVIRONMENT_URL`| The review environments url _(only define for static environment URLs declaration and if different from default)_ | `$AWS_ENVIRONMENT_URL` |

@@ -271,7 +250,6 @@ Here are variables supported to configure the integration environment:
| Name                     | description                            | default value     |
| ------------------------ | -------------------------------------- | ----------------- |
| `AWS_INTEG_ENABLED`      | AWS project ID for `integration` env | _none_ (disabled) |
| `AWS_INTEG_OIDC_ROLE_ARN`| IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `integration` env _(only define if different from global)_ | _none_ (disabled) |
| `AWS_INTEG_APP_NAME`     | Application name for `integration` env | `${AWS_BASE_APP_NAME}-integration` |
| `AWS_INTEG_ENVIRONMENT_URL`| The integration environment url _(only define for static environment URLs declaration and if different from default)_ | `$AWS_ENVIRONMENT_URL` |

@@ -287,7 +265,6 @@ Here are variables supported to configure the staging environment:
| Name                     | description                            | default value     |
| ------------------------ | -------------------------------------- | ----------------- |
| `AWS_STAGING_ENABLED`    | AWS project ID for `staging` env | _none_ (disabled) |
| `AWS_STAGING_OIDC_ROLE_ARN`| IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `staging` env _(only define if different from global)_ | _none_ (disabled) |
| `AWS_STAGING_APP_NAME`   | Application name for `staging` env     | `${AWS_BASE_APP_NAME}-staging` |
| `AWS_STAGING_ENVIRONMENT_URL`| The staging environment url _(only define for static environment URLs declaration and if different from default)_ | `$AWS_ENVIRONMENT_URL` |

@@ -302,7 +279,6 @@ Here are variables supported to configure the production environment:
| Name                      | description                            | default value     |
| ------------------------- | -------------------------------------- | ----------------- |
| `AWS_PROD_ENABLED`        | AWS project ID for `production` env | _none_ (disabled) |
| `AWS_PROD_OIDC_ROLE_ARN`| IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `production` env _(only define if different from global)_ | _none_ (disabled) |
| `AWS_PROD_APP_NAME`       | Application name for `production` env  | `$AWS_BASE_APP_NAME` |
| `AWS_PROD_ENVIRONMENT_URL`| The production environment url _(only define for static environment URLs declaration and if different from default)_ | `$AWS_ENVIRONMENT_URL` |
| `AWS_PROD_DEPLOY_STRATEGY`| Defines the deployment to production strategy. One of `manual` (i.e. _one-click_) or `auto`. | `manual` |
@@ -508,6 +484,51 @@ aws cloudformation delete-stack --stack-name "$environment_name"

The AWS template can be used in conjunction with template variants to cover specific cases.

### OIDC variant

This variant enables [OpenID Connect to retrieve temporary credentials](https://docs.gitlab.com/ee/ci/cloud_services/aws/).

If you wish to use this authentication mode, please follow carefully [the GitLab guide](https://docs.gitlab.com/ee/ci/cloud_services/aws/), 
then configure appropriately the related variables:

* `AWS_OIDC_ROLE_ARN` for any global/common access,
* `AWS_REVIEW_OIDC_ROLE_ARN` and/or `AWS_INTEG_OIDC_ROLE_ARN` and/or `AWS_STAGING_OIDC_ROLE_ARN` and/or `AWS_PROD_OIDC_ROLE_ARN` if you wish to use a separate role with any of your environments.

#### Configuration

The variant supports the following configuration:

| Name              | description                            | default value     |
| ----------------- | -------------------------------------- | ----------------- |
| `AWS_OIDC_AUD`    | The `aud` claim for the JWT | `$CI_SERVER_URL` |
| `AWS_OIDC_ROLE_ARN`    | Default IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) | _none_ (disabled) |
| `AWS_REVIEW_OIDC_ROLE_ARN`| IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `review` env _(only define if different from global)_ | _none_ (disabled) |
| `AWS_INTEG_OIDC_ROLE_ARN`| IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `integration` env _(only define if different from global)_ | _none_ (disabled) |
| `AWS_STAGING_OIDC_ROLE_ARN`| IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `staging` env _(only define if different from global)_ | _none_ (disabled) |
| `AWS_PROD_OIDC_ROLE_ARN`| IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `production` env _(only define if different from global)_ | _none_ (disabled) |

#### Example

```yaml
include:
  # main template
  - project: 'to-be-continuous/aws'
    ref: '3.1.0'
    file: '/templates/gitlab-ci-aws.yml'
  # Vault variant
  - project: 'to-be-continuous/aws'
    ref: '3.1.0'
    file: '/templates/gitlab-ci-aws-oidc.yml'

variables:
  # audience claim for JWT
  AWS_OIDC_AUD: "https://gitlab.acme.com"
  # common OIDC role ARN for non-prod envs
  AWS_OIDC_ROLE_ARN: "arn:aws:iam::111111111111:role/cicd-role"
  # specific OIDC role ARN for prod
  AWS_PROD_OIDC_ROLE_ARN: "arn:aws:iam::222222222222:role/cicd-role"
```

### Vault variant

This variant allows delegating your secrets management to a [Vault](https://www.vaultproject.io/) server.
@@ -520,6 +541,7 @@ In order to be able to communicate with the Vault server, the variant requires t
| ----------------- | -------------------------------------- | ----------------- |
| `TBC_VAULT_IMAGE` | The [Vault Secrets Provider](https://gitlab.com/to-be-continuous/tools/vault-secrets-provider) image to use (can be overridden) | `$CI_REGISTRY/to-be-continuous/tools/vault-secrets-provider:master` |
| `VAULT_BASE_URL`  | The Vault server base API url          | _none_ |
| `VAULT_OIDC_AUD`  | The `aud` claim for the JWT | `$CI_SERVER_URL` |
| :lock: `VAULT_ROLE_ID`   | The [AppRole](https://www.vaultproject.io/docs/auth/approle) RoleID | **must be defined** |
| :lock: `VAULT_SECRET_ID` | The [AppRole](https://www.vaultproject.io/docs/auth/approle) SecretID | **must be defined** |

@@ -538,23 +560,6 @@ With:
| `secret_path` (_path parameter_) | this is your secret location in the Vault server |
| `field` (_query parameter_)      | parameter to access a single basic field from the secret JSON payload |

The variant supports two ways to retrieve the JSON web token (JWT):

* using GitLab's `CI_JOB_JWT` variable - _default_<br/>
  :warning: deprecated, scheduled to be removed in GitLab 16.5
* using an [ID token](https://docs.gitlab.com/ee/ci/yaml/index.html#id_tokens) named `VAULT_JWT_TOKEN` - _configurable_

The ID token can be configured as follows in your `.gitlab-ci.yml` file:

```yaml
# enable VAULT_JWT_TOKEN ID token for AWS jobs only
.aws-base:
  id_tokens:
    VAULT_JWT_TOKEN:
      # use your own audience url here
      aud: https://gitlab.com
```

#### Example

```yaml
@@ -569,16 +574,11 @@ include:
    file: '/templates/gitlab-ci-aws-vault.yml'

variables:
    # audience claim for JWT
    VAULT_OIDC_AUD: "https://vault.acme.host"
    # Secrets managed by Vault
    AWS_ACCESS_KEY_ID: "@url@http://vault-secrets-provider/api/secrets/b7ecb6ebabc231/aws/prod/account?field=access_key_id"
    AWS_SECRET_ACCESS_KEY: "@url@http://vault-secrets-provider/api/secrets/b7ecb6ebabc231/aws/prod/account?field=secret_access_key"
    VAULT_BASE_URL: "https://vault.acme.host/v1"
    # $VAULT_ROLE_ID and $VAULT_SECRET_ID defined as a secret CI/CD variable

# enable VAULT_JWT_TOKEN ID token for AWS jobs only
.aws-base:
  id_tokens:
    VAULT_JWT_TOKEN:
      # use your own audience url here
      aud: https://gitlab.com
```
+44 −26
Original line number Diff line number Diff line
@@ -20,11 +20,6 @@
      "type": "url",
      "description": "The default environments url _(only define for static environment URLs declaration)_\n\n_supports late variable expansion (ex: `https://%{environment_name}.aws.acme.com`)_"
    },
    {
      "name": "AWS_OIDC_ROLE_ARN",
      "description": "Default IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/)",
      "advanced": true
    },
    {
      "name": "AWS_SCRIPTS_DIR",
      "description": "Directory where AWS scripts (deploy & cleanup) are located",
@@ -49,11 +44,6 @@
          "type": "url",
          "description": "The review environments url _(only define for static environment URLs declaration and if different from default)_",
          "advanced": true
        },
        {
          "name": "AWS_REVIEW_OIDC_ROLE_ARN",
          "description": "IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `review` env _(only define if different from global)_",
          "advanced": true
        }
      ]
    },
@@ -73,11 +63,6 @@
          "type": "url",
          "description": "The integration environment url _(only define for static environment URLs declaration and if different from default)_",
          "advanced": true
        },
        {
          "name": "AWS_INTEG_OIDC_ROLE_ARN",
          "description": "IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `integration` env _(only define if different from global)_",
          "advanced": true
        }
      ]
    },
@@ -97,11 +82,6 @@
          "type": "url",
          "description": "The staging environment url _(only define for static environment URLs declaration and if different from default)_",
          "advanced": true
        },
        {
          "name": "AWS_STAGING_OIDC_ROLE_ARN",
          "description": "IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `staging` env _(only define if different from global)_",
          "advanced": true
        }
      ]
    },
@@ -122,11 +102,6 @@
          "description": "The production environment url _(only define for static environment URLs declaration and if different from default)_",
          "advanced": true
        },
        {
          "name": "AWS_PROD_OIDC_ROLE_ARN",
          "description": "IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `production` env _(only define if different from global)_",
          "advanced": true
        },
        {
          "name": "AWS_PROD_DEPLOY_STRATEGY",
          "description": "Defines the deployment to production strategy.",
@@ -138,6 +113,44 @@
    }
  ],
  "variants": [
    {
      "id": "oidc",
      "name": "OpenID Connect",
      "description": "Enables [federated authentication using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/)",
      "template_path": "templates/gitlab-ci-gcloud-oidc.yml",
      "variables": [
        {
          "name": "AWS_OIDC_AUD",
          "description": "The `aud` claim for the JWT",
          "default": "$CI_SERVER_URL"
        },
        {
          "name": "AWS_OIDC_ROLE_ARN",
          "description": "Default IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/)",
          "advanced": true
        },
        {
          "name": "AWS_REVIEW_OIDC_ROLE_ARN",
          "description": "IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `review` env _(only define if different from global)_",
          "advanced": true
        },
        {
          "name": "AWS_INTEG_OIDC_ROLE_ARN",
          "description": "IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `integration` env _(only define if different from global)_",
          "advanced": true
        },
        {
          "name": "AWS_STAGING_OIDC_ROLE_ARN",
          "description": "IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `staging` env _(only define if different from global)_",
          "advanced": true
        },
        {
          "name": "AWS_PROD_OIDC_ROLE_ARN",
          "description": "IAM Role ARN associated with GitLab to [authenticate using OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/aws/) on `production` env _(only define if different from global)_",
          "advanced": true
        }
      ]
    },
    {
      "id": "vault",
      "name": "Vault",
@@ -150,6 +163,11 @@
          "default": "$CI_REGISTRY/to-be-continuous/tools/vault-secrets-provider:master",
          "advanced": true
        },
        {
          "name": "VAULT_OIDC_AUD",
          "description": "The `aud` claim for the JWT",
          "default": "$CI_SERVER_URL"
        },
        {
          "name": "VAULT_BASE_URL",
          "description": "The Vault server base API url",
+10 −0
Original line number Diff line number Diff line
# =====================================================================================================================
# === OIDC authentication template variant
# =====================================================================================================================
variables:
  AWS_OIDC_AUD: "$CI_SERVER_URL"

.aws-base:
  id_tokens:
    AWS_JWT:
      aud: "$AWS_OIDC_AUD"
+6 −1
Original line number Diff line number Diff line
@@ -5,9 +5,9 @@ variables:
  # variabilized vault-secrets-provider image
  TBC_VAULT_IMAGE: "$CI_REGISTRY/to-be-continuous/tools/vault-secrets-provider:master"
  # variables have to be explicitly declared in the YAML to be exported to the service
  VAULT_JWT_TOKEN: "$VAULT_JWT_TOKEN"
  VAULT_ROLE_ID: "$VAULT_ROLE_ID"
  VAULT_SECRET_ID: "$VAULT_SECRET_ID"
  VAULT_OIDC_AUD: "$CI_SERVER_URL"

.aws-base:
  services:
@@ -15,3 +15,8 @@ variables:
      command: ["--service", "aws", "3.1.0" ]
    - name: "$TBC_VAULT_IMAGE"
      alias: "vault-secrets-provider"
  variables:
    VAULT_JWT_TOKEN: "$VAULT_JWT_TOKEN"
  id_tokens:
    VAULT_JWT_TOKEN:
      aud: "$VAULT_OIDC_AUD"