Authenticating Amazon ECR Repositories for Docker CLI with Credential Helper

The default way to authen then talk with registry is through

docker login.

The user name is aws and password could be retrieve using

Aws ecr get-token

So far it’s pretty straightforward.

However, there is a caveat there. The token from aws CLI is valid for 12 hours only, this is aws’s approach to secure the access, in case the token is compromised, it’s to be expired then only authorised could retrieve the new token.

One possible approach to keep the docker CLI work is to refresh the

Docker login

Every 12 hours. Which is not difficult however is very ugly.

Instead, aws has this Credential helper. So with the Aws-ecr-Credential-helper installed, when we run docker CLI, it’s able to pick up the config from ~/.docker/config.json

"credHelpers": {
		"": "ecr-login"

That it would leverage on the helper to talk to the specific ecr instance. And the helper in turn would leverage on pre-configured ~/.aws/credential & ~/.aws/config to pick up the right access key and secret etc to talk with ecr.

This is a cool solution not only for Docker CLI but actually a lot serverless platform as well which relies on containers.

K8s client authentication

Have been working on some serverless framework recently, which i have put onto EKS.

most of the stuff worked, except the cli, which leveraged on k8s client-go library to authen is not able to do so with EKS. (working well with Azure AKS and GCP).

turns out the issue was with k8s client-go library, which doesn’t deal with aws-iam-authenticator. as a work around, the patch is to apply the service account as a bearer token.

//command to get the token
kubectl describe secret account -n namespace | grep -E '^token' | cut -f2 -d':' | tr -d " "

then in the client-go, patch the token into the bearer header:

//retrieve the token either from secret file or env var
//token, err := ioutil.ReadFile("~/secrets/" + v1.ServiceAccountTokenKey)
//token := os.Getenv("BEARER_TOKEN")

//add the header if its not yet there
r.headers.Set("Authorization", "Bearer xxx")

//before the real http call
resp, err := client.Do(req)

refer to: