Set up the Docker credential helper
TODO: Verify docker login and docker stack deploy --with-registry-auth with the credential helper against the Netwrix registry.
By default, docker login writes the registry credential to ~/.docker/config.json as base64-encoded text. This page describes how to install the official Docker docker-credential-pass helper with gopass as the back end. GNU Privacy Guard (GPG) encrypts the credential, and Docker keeps no readable credential in its configuration file.
Use the helper on each Ubuntu node that pulls Netwrix Privilege Secure for Discovery images from the Netwrix container registry. The setup is optional. You can use the plain docker login procedure in Configure registry access instead.
How the helper works
Docker calls the docker-credential-pass binary to store and retrieve credentials. That binary calls the pass command and reads the store in ~/.password-store. The gopass tool uses the same GPG-encrypted file format as pass, so two links connect them:
- A
passsymbolic link points to thegopassbinary. - A
~/.password-storesymbolic link points to thegopassstore.
Prerequisites
- Ubuntu Server 24.04 LTS on x86-64, with the packages from Install host prerequisites, including Docker Engine and the AWS CLI.
- AWS credentials configured as described in Configure registry access. Netwrix Support provides the credentials.
- Internet access to the Ubuntu and
gopasspackage repositories and to GitHub, which hosts the helper binary.
Choose the user
The deployment script runs as sudo -E bash secureone.sh. The -E option keeps your home directory, so Docker reads ~/.docker/config.json, ~/.password-store, and ~/.gnupg from your user, not from /root. Complete this procedure as the user that runs the script, and use sudo only where a command shows it. Don't open a root shell with sudo -i, because its home directory is /root.
If you set up the helper for a different user than the one that runs secureone.sh, Docker can't find the credential, and the image pull fails.
Install the helper
-
Install the prerequisite packages.
sudo apt-get updatesudo apt-get install -y ca-certificates curl gnupg git -
Add the
gopassrepository signing key.curl -fsSL https://packages.gopass.pw/repos/gopass/gopass-archive-keyring.gpg \| sudo tee /usr/share/keyrings/gopass-archive-keyring.gpg >/dev/null -
Add the
gopassrepository.cat <<'EOF' | sudo tee /etc/apt/sources.list.d/gopass.sources >/dev/nullTypes: debURIs: https://packages.gopass.pw/repos/gopassSuites: stableArchitectures: amd64Components: mainSigned-By: /usr/share/keyrings/gopass-archive-keyring.gpgEOF -
Install
gopass.sudo apt-get updatesudo apt-get install -y gopass gopass-archive-keyring -
Download the
docker-credential-passbinary and the checksum list from the Docker credential helpers releases.cd "$(mktemp -d)"VERSION="v0.9.5"BASE="https://github.com/docker/docker-credential-helpers/releases/download/${VERSION}"curl -fsSLO "${BASE}/docker-credential-pass-${VERSION}.linux-amd64"curl -fsSLO "${BASE}/checksums.txt" -
Verify the checksum.
grep "docker-credential-pass-${VERSION}.linux-amd64" checksums.txt | sha256sum -c -The output is
docker-credential-pass-v0.9.5.linux-amd64: OK. -
Install the binary in
/usr/local/bin, which is on thesudosecure path.sudo install -m 0755 "docker-credential-pass-${VERSION}.linux-amd64" /usr/local/bin/docker-credential-pass -
Link
passtogopass.sudo ln -sf "$(which gopass)" /usr/local/bin/pass
To use a newer helper release, change VERSION to the release tag on the Docker credential helpers releases page.
Create the encryption key and the store
-
Set the identity that
gopassuses for its local store. The store needs no remote repository.git config --global user.name "<name>"git config --global user.email "<name>@example.com" -
Create a GPG key without a passphrase.
cat > "$HOME/gpg-batch" <<'EOF'Key-Type: RSAKey-Length: 3072Subkey-Type: RSASubkey-Length: 3072Name-Real: <name>Name-Email: <name>@example.comExpire-Date: 0%no-protection%commitEOFgpg --batch --generate-key "$HOME/gpg-batch"rm "$HOME/gpg-batch"noteA key without a passphrase lets Docker read the credential during unattended deployments. Anyone who can read the
~/.gnupgdirectory can decrypt the store, so restrict access to the node. To use a passphrase instead, remove the%no-protectionline and configure a workingpinentryprogram andgpg-agentso thatgopasscan decrypt duringdocker login. -
Get the key ID.
KEYID="$(gpg --list-secret-keys --with-colons <name>@example.com | awk -F: '/^sec:/{print $5; exit}')"echo "$KEYID" -
Initialize the
gopassstore.gopass --yes init "$KEYID" -
Link the store to the location that the helper reads.
ln -sfn "${XDG_DATA_HOME:-$HOME/.local/share}/gopass/stores/root" "$HOME/.password-store"
Don't add a Git remote to the store.
Configure Docker to use the helper
Set the credsStore key in your Docker configuration:
mkdir -p "$HOME/.docker"
cat > "$HOME/.docker/config.json" <<'EOF'
{
"credsStore": "pass"
}
EOF
If ~/.docker/config.json already exists, set only the credsStore key and keep the other keys. Remove any registry credentials under auths, so that no credential remains in plain text.
Use credsStore, not credHelpers. The s1 tool mounts your config.json file into its container when the file contains credHelpers, and the container has only the Amazon ECR helper. Without credHelpers, the s1 tool uses the AWS credentials in ~/.aws.
Sign in to the registry
-
Sign in with the temporary registry token. Use
sudo -Eso that Docker runs with your home directory.aws ecr get-login-password --region us-west-2 \| sudo -E docker login --username AWS --password-stdin \176947481038.dkr.ecr.us-west-2.amazonaws.comThe output includes
Login Succeeded. The token is valid for 12 hours. The helper stores it encrypted, and~/.docker/config.jsonreceives no credential. -
Confirm that Docker stored no inline credential.
grep -q '"auth"' "$HOME/.docker/config.json" && echo "unexpected inline auth found"The expected result is no output.
-
Confirm that the helper returns the credential.
printf '%s' "176947481038.dkr.ecr.us-west-2.amazonaws.com" | sudo -E docker-credential-pass getThe output is a JSON object with the
ServerURL,Username, andSecretkeys:{"ServerURL":"176947481038.dkr.ecr.us-west-2.amazonaws.com","Username":"AWS","Secret":"<token>"}The
sudo -E docker logincommand creates the store entry as the root user, so run the helper withsudo -E. Withoutsudo, the helper reportspermission denied.
Deploy or upgrade
After the sign-in is in place, run the deployment or upgrade. See Deploy Privilege Secure for Discovery with Docker. The deployment script deploys the stack with --with-registry-auth, so Docker Swarm passes the registry credential to the nodes that pull images.
Because the token expires after 12 hours, repeat the sign-in before each deployment or upgrade.
On a three-node cluster, the script pulls the images only on the primary node. If a service restarts on another node after the token expires, and that node never pulled the image, the pull can fail. To fix it, sign in again with a fresh token, and then run deploy again.
Manage the stored credential
- Docker uses the helper automatically after you set
credsStoretopass. You don't run the helper during routine deployments. - Docker scopes credentials to the registry host name. Sign in separately to each registry you use.
- Run
sudo -E docker-credential-pass listto show the registries that have a stored credential. - Run
sudo -E docker logout 176947481038.dkr.ecr.us-west-2.amazonaws.comto delete the stored credential. - Pipe the token with
--password-stdin, as in the sign-in command, so that the token doesn't appear in shell history, process lists, or environment variables. - If the node already uses another Docker credential store, setting
credsStoretopassreplaces it for your Docker client.