In the blog you will see how you can store the Docker registry credentials in 1Password. I want to do this because I am in the process of removing all clear text credentials from the configuration files, into 1Password.
Docker Registry Credentials
Docker normally keeps all credentials for container registries stored in ~/.docker/config.json, as shown below:
{
"auths": {
"ghcr.io": {
"auth": "bXlsb25ndXNlcm5hbWU6YXZlcnlsb25ncGFzc3dvcmQ="
}
}
}
As you can see, the credentials are stored in base64 encoded form. This is not very secure, as anyone with access to the the file can steal the credentials.
Docker Desktop Credential Helper
If you use Docker Desktop, normally the desktop credential helper is configured as shown below:
{
"credsStore": "desktop",
"auths": {
"ghcr.io": {}
}
}
This will store the credential in the OS/X keychain, which is better than base64 encoded in a text file. But, it will still provide unauthenticated access to the secret through the docker-credential-desktop and docker-credential-osxkeychain programs.
$ docker-credential-desktop get <<< ghcr.io
{"Username":"mylongusername", "Secret": "averylongpassword", "ServerURL": "ghcr.io"}
This is because Docker Desktop grants default access to the docker-credential-osxkeychain helper executable, as shown in the screenshot below.
If this grant is removed, you will be prompted for your password every time the registry credentials are accessed. This is good but rather tedious. Unfortunately, it is not possible to use the fingerprint for authentication.
Using the 1Password password manager
The 1Password password manager, provides a command line interface which you can use to access any secret stored in your vault. The following command shows how you can use the 1Password CLI to retrieve a Github Enterprise token and pass it as an environment variable to the gh command line tool:
GH_ENTERPRISE_TOKEN="$(op read "op://Private/github enterprise token/credential")" gh list
You can use this utility to implement a docker credential helper for 1Password.
Docker Credential helper for 1Password
The Docker credential helper is a program that reads and writes credentials to a secure storage location. To implement a credential helper for 1Password, you need to create a program named docker-credential-1password
and implement the commands store, list, get and erase.
Store credentials in 1Password
The store command reads a json object with ServerURL, Username and Secret values from stdin and stores it in 1Password.
$ docker-credential-1password store <<EOF
{
"ServerURL": "https://example.com",
"Username": "myusername",
"Secret": "averylongpassword"
}
EOF
List credentials in 1Password
The list command prints a json object with all the server URL and username pairs in the 1Password docker vault.
$ docker-credential-1password list
{
"https://example.com": "myusername"
}
Get credentials from 1Password
The get command reads the registry name from stdin and prints a json object with ServerURL, Username and Secret values.
$ docker-credential-1password get <<< example.com
{"ServerURL": "https://example.com", "Username": "myusername", "Secret": "averylongpassword"}
Erase credentials from 1Password
The erase commands reads the registry name from stdin, and removes the credentials from 1Password.
$ docker-credential-1password erase <<< example.com
The fun part is that every time a new process wants to access the credentials, the user will be prompted for authorization. You can configure Touch ID to make this process more convenient.
Installing the 1Password credential helper
To use the 1Password credential helper, you need to install it, copy the credentials and update the docker configuration to use it.
Install the 1Password credential helper in the path
The 1Password credential helper is a simple shell script, which you can install by copying it to a directory in your PATH.
$ cd /usr/local/bin
$ wget https://raw.githubusercontent.com/xebia/docker-credential-1password/refs/heads/main/bash/docker-credential-1password
$ chmod +x docker-credential-1password
Copy credentials into 1Password
Now you can copy all the credentials from the docker desktop app into 1Password:
docker-credential-desktop list | \
jq -r '.|to_entries|map(.key|sub("^https://"; ""))|.[]' | \
while read registry; do
docker-credential-desktop get <<< $registry | \
docker-credential-1password store
done
Update the docker configuration
Lastly, you configure the 1Password credential helper by updating the docker configuration ~/.docker/config.json. You do this by changing all references to the “desktop” credential helper to “1password”, as shown below.
{
"auths": {
"ghcr.io": {}
}
"credsStore": "1password",
"credHelpers": {
"ghcr.io": "1password"
}
}
Conclusion
In this blog you saw how you can store your container registry credentials in 1Password using a simple credential helper and avoid clear text credentials and unauthenticated access to your container registries.
Image by carmen6969 from Pixabay