AWS Compute Blog

Authenticating Amazon ECR Repositories for Docker CLI with Credential Helper

This is a guest post from my colleagues Ryosuke Iwanaga and Prahlad Rao.

————————

Developers building and managing microservices and containerized applications using Docker containers require a secure, scalable repository to store and manage Docker images. In order to securely access the repository, proper authentication from the Docker client to the repository is important, but re-authenticating or refreshing authentication token every few hours often can be cumbersome.

This post walks you through a quick overview of Amazon ECR and how deploying Amazon ECR Docker Credential Helper can automate authentication token refresh on Docker push/pull requests.

Overview of Amazon ECS and Amazon ECR
Amazon ECS is a highly scalable, fast container management service that makes it easy to run and manage Docker containers on a cluster of Amazon EC2 instances and eliminates the need to operate your own cluster management or worry about scaling management infrastructure.

In order to reliably store Docker images on AWS, ECR provides a managed Docker registry service that is secure, scalable, and reliable. ECR is a private Docker repository with resource-based permissions using IAM so that users or EC2 instances can access repositories and images through the Docker CLI to push, pull, and manage images.

Manual ECR authentication with the Docker CLI
Most commonly, developers use Docker CLI to push and pull images or automate as part of a CI/CD workflow. Because Docker CLI does not support standard AWS authentication methods, client authentication must be handled so that ECR knows who is requesting to push or pull an image.

This can be done with a docker login command to authenticate to an ECR registry that provides an authorization token valid for 12 hours. One of the reasons for the 12-hour validity and subsequent necessary token refresh is that the Docker credentials are stored in a plain-text file and can be accessed if the system is compromised, which essentially gives access to the images. Authenticating every 12 hours ensures appropriate token rotation to protect against misuse.

If you’re using the AWS CLI, you can use a simpler get-login command which retrieves the token, decodes it, and converts into a docker login command for you. An example for the default registry associated with the account is shown below:


$ aws ecr get-login
docker login –u AWS –p password –e none https://aws_account_id.dkr.ecr.us-east-1.amazonaws.com

To access other account registries, use the -registry-ids <aws_account_id> option.

As you can see, the resulting output is a docker login command that you can use to authenticate your Docker client to your ECR registry. The generated token is valid for 12 hours, which means developers running and managing container images have to re-authenticate every 12 hours manually, or script it to generate a new token, which can be somewhat cumbersome in a CI/CD environment. For example if you’re using Jenkins to build and push docker images to ECR, you have to set up Jenkins instances to re-authenticate using get-login to ECR every 12 hours.

If you want a programmatic approach, you can use GetAuthorizationToken from the AWS SDK to fetch credentials for Docker. GetAuthorizationToken returns an authorization token of a base64-encoded string that can be decoded into username and password with “AWS” as username and temporary token as password.

It’s important to note that when executing docker login commands, the command string can be visible by other users on the system in a process list, e.g., ps –e, meaning other users can view authentication credentials to gain push and pull access to repositories. To avoid this, you can interactively log in by omitting the –p password option and enter password only when prompted. Overall, this may add additional overhead in a continuous development environment where developers need to worry about re-authentication every few hours.

Amazon ECR Docker Credential Helper
This is where Amazon ECR Docker Credential Helper makes it easy for developers to use ECR without the need to use docker login or write logic to refresh tokens and provide transparent access to ECR repositories.

Credential Helper helps developers in a continuous development environment to automate the authentication process to ECR repositories without having to regenerate tokens every 12 hours. In addition, Credential Helper also provides token caching under the hood so you don’t have to worry about getting throttled or writing additional logic.

You can access Credential Helper in the amazon-ecr-credential-helper GitHub repository.

Using Credential Helper on Linux/Mac and Windows
The prerequisites include:

  • Docker 1.11 or above installed on your system
  • AWS credentials available in one of the standard locations:
    • ~/.aws/credentials file
    • AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables
    • IAM role for Amazon EC2

First, build a binary for your client machine. Although you can do it with your own Go environment, we also provide a way to build it inside a Docker container without installing Go by yourself. To build by container, just type make docker on the root directory of the repository. It will run a container FROM go image and build the binary on the mounted volume. After that, you can see it at ./bin/local/docker-credential-ecr-login.

Note: You need to run this with the local Docker engine as the remote Docker Engine can’t mount your local volume.

You can also build the binary cross compiled:

  • To build a Mac binary, use make docker TARGET_GOOS=darwin
  • To build a Windows binary, use make docker TARGET_GOOS=windows

With these commands, Go builds the binary for the target OS inside the Linux container.

The last thing you need to do is create a Docker configuration file for the helper. Put the file under ~/.docker/config.json or C:\Users\bob\.docker\config.json with the following content:


{
    "credsStore": "ecr-login"
}

Now, you can use the docker command to interact with ECR without docker login. When you type docker push/pull YOUR_ECR_IMAGE_ID, Credential Helper is called and communicates with the ECR endpoint to get the Docker credentials. Because it automatically detects the proper region from the image ID, you don’t have to worry about it.

Using Credential Helper with Jenkins
One of the common customer deployment patterns with ECS and ECR is integrating with existing CI/CD tools like Jenkins. Using Credential Helper, your Docker CI/CD setup with Jenkins is much simpler and more reliable.
To set up ECR as a Docker image repository for Jenkins and configure Credential Helper:

  • Ensure that your Jenkins instance has the proper AWS credentials to pull/push with your ECR repository. These can be in the form of environment variables, a shared credential file, or an instance profile.
  • Place docker-credential-ecr-login binary at one of directories in $PATH.
  • Write the Docker configuration file under the home directory of the Jenkins user, for example, /var/lib/jenkins/.docker/config.json.
  • Install the Docker Build and Publish plugin and make sure that the jenkins user can contact the Docker daemon.

Then, create a project with a build step, as in the following screenshot:

Jenkins Build Step

Now Jenkins can push/pull images to the ECR registry without needing to refresh tokens, just like your previous Docker CLI experience.

Conclusion
The Amazon ECR Docker Credential Helper provides a very efficient way to access ECR repositories. It is transparent so that you no longer need to recall this helper after setup. This tool is hosted on GitHub and we welcome your feedback and pull requests.

If you have any questions or suggestions, please comment below.