How does docker authentication with private registry work ? Lets find out
With code walk through !
TO pull or push images from or to a private registry with docker, authentication to the registry might be needed as the registry is private.Here we will just have a look at how docker authenticates with the registry.Yes the internal working !
Assume in this case the registry is dockerhub where you have your private images stored and which you want to pull.There are 2 authentication options for this assuming that the registry supports either of the below
Username/password
- Successful Login:
mymachine$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: myaccount123
Password:
WARNING! Your password will be stored unencrypted in /home/mymachine/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded
So now your credentials will be stored in ~/.docker/config.json as below
docker login will authenticate to the registry and then update the config.json file(lines 6–8) with the registry domain(dockerhub’s domain is index.docker.io) as key and and an auth entry.
So whenever you pull or push from dockerhub registry,as the registry domain is in the config.json, docker will retrieve the corresponding auth entry and use this as an authorization header to the registry for push or pull.
Auth entry though looks like some encrypted text its just base64 encoded string and if you decode the string it will be in the form username:password.
mymachine$ openssl enc --base64 -d <<< bXlhY2NvdW50MTIzOnBhc3N3b3JkCg==
myaccount123:password
So this is not secure and the warning is displayed when used like this.
- Failed Login
mymachine$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don’t have a Docker ID, head over to https://hub.docker.com to create one.
Username: myaccount123
Password:
Error response from daemon: Get https://registry-1.docker.io/v2/: unauthorized: incorrect username or password
Code flow
The runLogin function is the starting point.
call RegistryLogin -> cli.post( /auth route of docker daemon is invoked) -> call postAuth -> call AuthenticateToRegistry -> call auth -> call loginv2 -> loginv2
In loginv2 function, a get request is made to https://registry-1.docker.io/v2/ with the credentials in the request header.You can find the api docs here.
Credential Store/Credential Helpers
In the above config.json there is any entry as below
"credsStore": "customcredential-store"
When you execute docker login for a registry which is not configured and a default credsstore is configured, it will invoke the program docker-credential-customcredential-store and pass it the registry domain as input and expect the credentials in response.See how it add docker-credential as a prefix.
Suppose your private registry is ECR, you will add credsStore value as ecr-login and place the executable docker-credential-ecr-login in the PATH.Check this.The ecr login executable when invoked will use your AWS profile if configured to authenticate you against the ECR registry and provide the authentication credentials to docker.
This way docker will be able to pull or push from ECR repository as it now has the credentials for ECR which it retrieved in the previous step.If you would like to know more about the protocol, its here.Its pretty straightforward.
You don’t have to explicitly do a docker login if you follow this approach as docker will implicitly call the credential store binary before any push or pull.
Code Flow
You can find the code here
Additional Goodies
- The docker cli invokes the docker daemon
- If you are pushing or pulling from a private registry, docker needs to authenticate with the registry and which is what this post is about.
The docker client passes the auth info to docker daemon in a header named X-Registry-Auth and the daemon uses this to authenticate with the registry.Some references ref1, ref2, here, here - How the authentication is setup at the registry itself is mentioned here.