Skip to main content

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:

  1. 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, and ECR_ROLE_TO_ASSUME. If you have provided a prefix, these variables will be prefixed.

  2. 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:gha-$IMAGE_TAG .
              docker push $REGISTRY/$REPOSITORY:gha-$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:

  1. 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, and ecr_role_to_assume.

  2. 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
    ...
    
  3. 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.

  4. 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
    
This page was last reviewed on 1 June 2023. It needs to be reviewed again on 1 September 2023 by the page owner #cloud-platform .
This page was set to be reviewed before 1 September 2023 by the page owner #cloud-platform. This might mean the content is out of date.