Deprecating long-lived credentials for container repositories
To improve the security of services running on the Cloud Platform, we are removing the ability to create and use long-lived credentials, such as IAM access keys, from our modules. These are being replaced by short-lived credentials.
For container repositories, this means utilising native OpenID Connect implementations for GitHub Actions and CircleCI.
You should start using short-lived credentials as soon as you can. Long-lived credentials will be entirely removed from the container repository on Monday, 4th September 2023.
Migrating to short-lived credentials for GitHub Actions
If you use GitHub Actions to push your Docker image to a container repository on the Cloud Platform, you need to update your namespace and your GitHub Actions workflow.
To use short-lived credentials in GitHub Actions, complete the following two steps:
Raise and merge a PR that adds the following attributes to your container repository, which is typically in
resources/ecr.tf
in your namespace:module "ecr" { ... # enable the oidc implementation for GitHub oidc_providers = ["github"] # specify which GitHub repository you're pushing from github_repositories = ["example-repository"] # set this if you use one GitHub repository to push to multiple container repositories # this ensures the variable key used in the workflow is unique github_actions_prefix = "production" ... }
As soon as this PR is merged, you will receive three new variables in GitHub Actions or in your GitHub Actions environments. These will be
ECR_REGION
,ECR_REPOSITORY
, andECR_ROLE_TO_ASSUME
. If you have provided a prefix, these variables will be prefixed.Update your GitHub Actions workflow to use short-lived credentials
As each team has a different GitHub Actions workflow, this example shows a full implementation of using short-lived credentials to push to your container repository. Inline comments tell you what each part of the workflow is for.
You should adapt your workflow to include the following permissions, and actions:
on: push: branches: [main] jobs: ecr: runs-on: ubuntu-latest permissions: id-token: write # This is required for requesting the JWT contents: read # This is required for actions/checkout steps: # Checkout GitHub repository - uses: actions/checkout@v3 # Assume role in Cloud Platform - uses: aws-actions/configure-aws-credentials@v2 with: role-to-assume: ${{ secrets.ECR_ROLE_TO_ASSUME }} aws-region: ${{ vars.ECR_REGION }} # Login to container repository - uses: aws-actions/amazon-ecr-login@v1 id: login-ecr # Build and push a Docker image to the container repository - run: | docker build -t $REGISTRY/$REPOSITORY:$IMAGE_TAG . docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} REPOSITORY: ${{ vars.ECR_REPOSITORY }} IMAGE_TAG: ${{ github.sha }}
Migrating to short-lived credentials for CircleCI
If you use CircleCI to push your Docker image to a container repository on the Cloud Platform, you need to update your namespace and your CircleCI job.
To use short-lived credentials in CircleCI, complete the following four steps:
Raise and merge a PR that adds the following attributes to your container repository, which is typically in
resources/ecr.tf
in your namespace:module "ecr" { ... # enable the oidc implementation for CircleCI oidc_providers = ["circleci"] # specify which GitHub repository your CircleCI job runs from github_repositories = ["example-repository"] # set your namespace name to create a ConfigMap # of credentials you need in CircleCI namespace = var.namespace ... }
As soon as this PR is merged, you will receive four new variables in a ConfigMap in your namespace. These will be
ecr_region
,ecr_registry_id
,ecr_repository
, andecr_role_to_assume
.Get the authentication variables from the Kubernetes ConfigMap in your namespace
The ConfigMap you need is suffixed with
-circleci
.List the ConfigMaps in your namespace, substituting
$namespace
with your namespace:$ kubectl get configmaps -n $namespace NAME DATA AGE ... repository-name-circleci 3 12m # this is the one you want
Get the value of this ConfigMap in your namespace, substituting
$repository
with the name of your ConfigMap, and$namespace
with your namespace.$ kubectl describe configmap $repository -n $namespace ... Data ==== ecr_region: ---- eu-west-2 ecr_registry_id: ---- 000000000000 ecr_repository: ---- repository-name ecr_role_to_assume: ---- arn:aws:iam::000000000000:role/cloud-platform-ecr-xyz-circleci ...
Update your CircleCI environment variables with values from the Kubernetes ConfigMap
In your Project in CircleCI, go to Project Settings -> Environment Variables.
Set the following names and the corresponding value for the above variables. For example:
name value ECR_REGION eu-west-2 # value of ecr_region ECR_REPOSITORY repository-name # value of ecr_repository ECR_ROLE_TO_ASSUME arn:aws:iam::00000000:role/cloud-platform-ecr-xyz-circleci # value of ecr_role_to_assume AWS_ECR_REGISTRY_ID 000000000000 # value of ecr_registry_id
You cannot change the name of the
AWS_ECR_REGISTRY_ID
environment variable as the CircleCI orb will not work.Update your CircleCI job to use short-lived credentials
As each team has a different CircleCI job, this example shows a full implementation of using short-lived credentials to push to your container repository. Inline comments tell you what each part of the job is for.
You should adapt your job to do the following:
version: 2.1 orbs: aws-cli: circleci/aws-cli@4.0.0 # use v4 of this orb aws-ecr: circleci/aws-ecr@8.2.1 # this orb doesn't support OIDC v2, so we use aws-cli to authenticate jobs: example: executor: aws-ecr/default # use the aws-ecr/default executor to start the docker daemon steps: # Checkout your repository - checkout # Authenticate to AWS using OIDC v2 with the AWS CLI - aws-cli/setup: role_arn: $ECR_ROLE_TO_ASSUME # this will use the env var region: $ECR_REGION # this will use the env var # Authenticate to the ECR repository using the standard command - run: | aws ecr get-login-password --region $ECR_REGION | docker login --username AWS --password-stdin ${AWS_ECR_REGISTRY_ID}.dkr.ecr.${ECR_REGION}.amazonaws.com # Build and push your Docker image - aws-ecr/build-image: push-image: true tag: ${CIRCLE_SHA1} region: $ECR_REGION # this will use the env var repo: $ECR_REPOSITORY # this will use the env var # You MUST configure a context for this workflow to work. workflows: example: jobs: - example: context: example-workflow
Remove the long-term credentials from your repo’s CircleCI Environment Variables.
- Locate your repo’s CircleCI project - browse to CircleCI/ministryofjustice and then select your repo
- Select “Project Settings” and then select in the sidebar “Environment Variables”
- Delete variables:
AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
- Navigate back to your CircleCI project and rerun a recent release workflow, to test it still works with the OIDC credentials