Skip to main content

Docker Credential Helper on Headless Linux

Install Prerequisites

sudo apt update && sudo apt install -y gpg pass pinentry-tty curl


Setup Password Store

Configure GPG Agent for Headless Linux

[ -d "$HOME/.gnupg" ] || ( mkdir "$HOME/.gnupg" && chmod 700 "$HOME/.gnupg" )
cat > ~/.gnupg/gpg-agent.conf << 'EOF'
default-cache-ttl 3600
max-cache-ttl 86400
pinentry-program /usr/bin/pinentry-tty
EOF
export GPG_TTY=$(tty) && echo -e '\nexport GPG_TTY=$(tty)' >> "$HOME/.bashrc"
gpg-connect-agent reloadagent /bye

GPG Keys

Check for Existing GPG Key

gpg --list-secret-keys --keyid-format LONG

Determine if you've already generated a GPG key on the host, note the email set on the GPG key

If you've already generated a GPG key on the host, then you must know the password used to generate the original key.

If you know the password for the GPG key, then you can use the existing key to encrypt the Git Credential Manager secrets.

Generate New GPG Key

Only run this if you're sure you do not have an existing key or you want to start fresh

gpg --full-generate-key

Option 9, Option 1, Option 0, Note hexadecimal string for use with pass init

  • Enter your name
  • Enter your email
  • Enter a comment (e.g. Credential Encryption Key)

When prompted, generate a passphrase to protect the key. And, store the passphrase in a password vault.

Get the GPG Key Public Key Fingerprint

gpg --list-public-keys username@domain.tld | head -n 2 | tail -n 1 | tr -d ' '

Get the GPG key public key fingerprint using email ...

gpg --list-public-keys username | head -n 2 | tail -n 1 | tr -d ' '

... or, get the GPG public key fingerprint using username

Password Store

When you -- or applications -- save secrets using the pass backend, they will be encrypted with your GPG key. So, if you haven't already, store the GPG key passphrase in a password vault, as you will need then when pass goes to decrypt your secrets.

Check Password Store State

[ -f "$HOME/.password-store/.gpg-id" ] && echo "Password store initialized with GPG" || echo "Password store not yet initialized with GPG"

Determine if the password store has been initialized with GPG

If Already Initialized...
cat "$HOME/.password-store/.gpg-id"

Note the public key fingerprint and compare with the gpg command above

Check the output of .gpg-id. This should contain a hexadecimal string (fingerprint) that should equal the output of the gpg --list-public-keys command above.

If the fingerprints in .gpg-id and gpg --list-public-keys do not match, then any secrets in your password store were likely encrypted using another GPG key. You can pass init with a new GPG key fingerprint, but you will have to have access to the old key to re-encrypt.

If Not Yet Initialized...
pass init GPG_PUB_KEY_FINGERPRINT_HERE


Install Docker Credential Helper

Find the latest linux-amd64 from GitHub releases.

LATEST_VERSION=$(curl -sI 'https://github.com/docker/docker-credential-helpers/releases/latest' | grep location | rev | cut -d '/' -f 1 | rev | tr -d '[:space:]')
curl -sL "https://github.com/docker/docker-credential-helpers/releases/download/${LATEST_VERSION}/docker-credential-pass-${LATEST_VERSION}.linux-amd64" -o docker-credential-pass
chmod +x docker-credential-pass
sudo mv docker-credential-pass /usr/local/bin
[ -d "$HOME/.docker" ] || mkdir "$HOME/.docker"
nano ~/.docker/config.json
{
        "credsStore": "pass"
}
# Docker Hub
docker login
# Custom registry
docker login host.domain.tld