Docker Config Reference (docker content trust)
We go over the basic foundations of using docker keypairs and docker trust.
Overview of Docker Content Trust and the Signing Process
Docker Content Trust (DCT) is a security feature integrated into the Docker CLI that enables the signing of container images to ensure their authenticity and integrity. When you sign an image using docker trust sign myrepo/myimage:latest, Docker attaches a cryptographic signature to the image's manifest, which includes metadata about its layers and configuration. This signature is created using a local key pair and is stored in a trust repository (typically on Docker Hub or a compatible registry). The process mitigates risks such as man-in-the-middle attacks or unauthorized modifications by allowing pullers (with content trust enabled) to verify that the image matches the signed version.
No additional libraries need to be installed beyond the standard Docker CLI, as DCT leverages the built-in Notary client for key management and signing. Docker version 1.13 or later includes this functionality natively. If your Docker installation lacks trust commands, ensure you are using an official Docker release (e.g., via apt or yum on Linux, or Docker Desktop on Windows/macOS). Enable content trust globally by setting the environment variable DOCKER_CONTENT_TRUST=1 (add to your shell profile for persistence).
Below, I outline the complete process step by step, including key generation, delegation setup, signing, and verification. All commands assume you are working in a terminal with Docker installed and authenticated to your registry (e.g., via docker login).
Step 1: Generating a Local Key Pair
Docker uses asymmetric cryptography (RSA keys by default) for signing. The key pair consists of a private key (for signing) and a public key (for verification). The docker trust key generate command creates this pair securely in your local Docker trust directory (typically ~/.docker/trust/).
docker trust key generate my-signer-key
This command generates a new RSA key pair named "my-signer-key". It prompts for a passphrase to encrypt the private key (recommended for security). The private key is stored locally, and the public key is outputted (copy it for delegation if needed). This key pair is used to sign images, establishing your identity as a signer. Repeat for multiple signers if collaborating.
Step 2: Setting Up Delegation in Detail
Delegation allows multiple signers to contribute signatures to a repository without sharing the root key. It creates a hierarchy: the root key (repository owner) delegates authority to targets (signers). This setup is crucial for collaborative environments, as it enables revocation of individual signers without invalidating the entire repository.
First, initialize the repository (this creates the root role if not present):
docker trust signer add --key /path/to/public-key.pem my-signer myrepo/myimage
- Replace
/path/to/public-key.pemwith the public key file generated earlier (e.g.,my-signer-key.pub). - "my-signer" is the delegate name.
- This adds the signer to the repository, uploading delegation metadata to the registry. It requires the root key passphrase if set.
For the initial setup (if no root key exists), Docker prompts to create one. To rotate or manage keys:
docker trust key load /path/to/new-private-key.pem --name my-signer-key
This loads an external private key. For revocation:
docker trust signer remove my-signer myrepo/myimage
This removes the delegate, invalidating future signatures from that signer but preserving existing ones. Delegation metadata is stored in the registry's Notary server (e.g., Docker Hub's), ensuring tamper-evident logs via timestamps.
Step 3: Attaching a Cryptographic Signature
Once keys and delegation are set, sign the image:
docker trust sign myrepo/myimage:latest
This command:
- Computes the image's canonical ID (a hash of its manifest).
- Signs the manifest using your private key (prompts for passphrase).
- Uploads the signature to the registry's trust repository.
- Attaches it to the tag "latest", allowing verifiers to check against modifications.
The signature verifies the image's layers and config haven't changed since signing.
Step 4: Verifying the Signature
To verify:
docker trust inspect --pretty myrepo/myimage:latest
This inspects trust data, showing signers and validity. For pull verification, enable DOCKER_CONTENT_TRUST=1:
export DOCKER_CONTENT_TRUST=1
docker pull myrepo/myimage:latest
This only pulls if signatures match, rejecting tampered images. For local verification:
docker trust view myrepo/myimage:latest
This displays signature details, confirming authorship and integrity.