19.1.3.4 Pull Registry Auth
A focused guide to Pull Registry Auth, connecting core concepts with practical Docker and container operations.
Pull registry auth covers the actual mechanics of how the Docker CLI authenticates to a registry before a pull, where those credentials are actually stored, and the specific practices that avoid leaking a credential through shell history or an insecure storage mechanism, distinct from the higher-level, Kubernetes-specific or general secrets-management content covered elsewhere.
Logging in and credential storage backends
docker login authenticates to a registry and stores the resulting credential according to whichever credential store the local Docker configuration is set up to use:
docker login registry.example.com
{
"auths": { "registry.example.com": {} },
"credsStore": "osxkeychain"
}
The credsStore (or credHelpers for a per-registry-specific helper) setting in ~/.docker/config.json determines whether credentials are delegated to a secure, native credential store, macOS Keychain, Windows Credential Manager, the Secret Service API on Linux, or, in the absence of any configured store, written directly and considerably less securely into the configuration file itself in plaintext.
Confirming whether a secure credential store is actually active
cat ~/.docker/config.json
"auths": {
"registry.example.com": {
"auth": "dXNlcjpwYXNzd29yZA=="
}
}
An auth field containing a base64-encoded value directly within the config file, rather than an empty object alongside a credsStore entry, indicates no secure credential helper is actually configured, meaning the credential is stored in this considerably weaker, directly-readable form; installing and configuring an appropriate credential helper for the current platform is the direct fix for this gap.
Avoiding shell history exposure during login
Passing a password directly as a command-line argument exposes it in shell history and process listings; the --password-stdin flag avoids this by reading the value from standard input instead:
echo "$REGISTRY_PASSWORD" | docker login registry.example.com --username myuser --password-stdin
docker login registry.example.com -u myuser -p mypassword
The first form never exposes the actual password value as a command-line argument at all; the second form does, leaving it recoverable from shell history and visible to anything inspecting the process list at the moment the command runs, which is precisely the same shell-history exposure concern covered for handling secrets generally.
Logging into multiple registries simultaneously
The Docker CLI maintains credentials for several distinct registries simultaneously, with each docker login invocation adding or updating the entry for whichever specific registry it targets, without affecting credentials already stored for any other:
docker login registry-a.example.com
docker login registry-b.example.com
docker pull registry-a.example.com/my-api:1.4.2
docker pull registry-b.example.com/my-other-api:2.0.0
This means a single Docker CLI installation can pull from several different, separately authenticated private registries without needing to log out and back in between each one.
Logging out and credential cleanup
docker logout registry.example.com
This removes the stored credential entry for that specific registry, which is worth doing explicitly when a credential's authorized use has genuinely ended, rather than leaving it indefinitely present in local storage long after it is actually still needed.
Token-based authentication as an alternative to username and password
Many registries support authenticating with a dedicated access token rather than an account's actual username and password, which is generally the preferable approach since a token can be scoped more narrowly and revoked independently without affecting the broader account credential:
echo "$ACCESS_TOKEN" | docker login registry.example.com --username token --password-stdin
Using a narrowly scoped, independently revocable token specifically for automated pull access, rather than a full account credential, limits the impact if that specific token is ever compromised, since revoking it does not require also rotating the underlying account's primary credential.
CI-specific authentication patterns
CI environments typically inject registry credentials as pipeline-level secret variables, and the login step within the pipeline script should consume them through stdin specifically, the same pattern as interactive use, rather than ever embedding them directly as a visible command-line argument within the pipeline configuration itself:
pull_image:
script:
- echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
- docker pull $CI_REGISTRY/my-api:1.4.2
Most CI platforms also mask known secret variable values in job log output automatically, but relying on --password-stdin regardless provides an additional, independent layer of protection rather than depending entirely on the CI platform's own masking behavior functioning correctly in every circumstance.
Common mistakes
- Not configuring a secure, native credential store, leaving registry credentials stored in plaintext directly within the Docker configuration file.
- Passing a password directly as a command-line argument to
docker login, exposing it in shell history and process listings rather than using--password-stdin. - Using a full account credential for automated pull access rather than a narrowly scoped, independently revocable access token.
- Never logging out of a registry once a credential's authorized use has genuinely ended, leaving it present in local storage indefinitely.
- Relying entirely on a CI platform's automatic secret masking rather than also using
--password-stdinas an additional, independent layer of protection.
Pull registry auth depends on confirming a secure credential store is actually configured rather than assuming one is, using --password-stdin consistently to avoid shell history exposure, and preferring narrowly scoped, independently revocable tokens over full account credentials for any automated pull access, all of which together keep the actual mechanics of registry authentication genuinely secure rather than only superficially convenient.