Docker Content Trust
A Docker security feature that enables cryptographic signing and verification of images using Notary. When enabled, Docker refuses to pull or run images that have not been signed by a trusted key — protecting against image tampering in transit.
Docker Content Trust — Cryptographic Image Verification
What Is Docker Content Trust in Simple Terms?
When you pull an image from a registry, how do you know it was not modified in transit? Docker Content Trust (DCT) uses cryptographic signatures to guarantee that the image you pull is exactly the image the publisher signed — nobody tampered with it between publishing and pulling.
Without DCT: Publisher pushes: nginx:1.25 (legitimate) Attacker modifies: nginx:1.25 in registry (malicious) You pull: nginx:1.25 (malicious version) No warning — looks exactly the same With DCT: Publisher signs: nginx:1.25 with private key Attacker modifies: nginx:1.25 in registry You pull: nginx:1.25 DCT verifies signature -> MISMATCH -> pull REJECTED Attack preventedEnabling Docker Content Trust
# Enable for a single commandDOCKER_CONTENT_TRUST=1 docker pull nginx:1.25 # Enable permanently (add to ~/.bashrc)export DOCKER_CONTENT_TRUST=1 # Verify it worksdocker pull nginx:1.25# Pull (1/1): nginx:1.25@sha256:...# docker.io/library/nginx:1.25: The image is signed # Try to pull an unsigned imagedocker pull some-unsigned-image:latest# Error: remote trust data does not exist for docker.io/...# Unsigned images are rejected when DCT is enabledSigning Your Own Images
# Generate signing keys (first time only)docker trust key generate myteam # Sign and push an imageDOCKER_CONTENT_TRUST=1 docker push registry.razorpay.in/payment-api:v3.1.0# Image automatically signed on push when DCT is enabled # Verify image signaturedocker trust inspect registry.razorpay.in/payment-api:v3.1.0# Shows: who signed it, when, and the key fingerprint # Add another signer (for team environments)docker trust signer add --key teammate-key.pub teammate \ registry.razorpay.in/payment-apiModern Alternative — Cosign / Sigstore
# Cosign is the modern replacement for DCT# Part of the Sigstore project (backed by Google, Red Hat, GitHub) # Install cosignbrew install cosign # Sign an image (uses keyless signing with OIDC)cosign sign registry.razorpay.in/payment-api:v3.1.0 # Verify signaturecosign verify registry.razorpay.in/payment-api:v3.1.0 # Cosign advantages over DCT:# Keyless signing via OIDC (no key management)# Works with any OCI-compatible registry# Better integration with Kubernetes admission controllersRememberDocker Content Trust only works with image tags — not digests. If you pull by digest (
image@sha256:...), you are already guaranteed the exact content — DCT adds signature verification on top of that for tags which can be overwritten.
Frequently Asked Questions
What attack does Docker Content Trust actually protect against?
It protects against a registry or the network path to it being compromised and an attacker swapping a legitimate image for a malicious one with the same tag. DCT is built on Notary and The Update Framework (TUF), using a hierarchy of signing keys (root, targets, snapshot, timestamp) so that even if one key is compromised, the whole trust chain doesn't fall apart. Without DCT, `docker pull myimage:latest` trusts whatever bytes the registry returns, with no cryptographic verification of who published them.
Why do so few teams actually run with DCT enabled in production?
Enabling `DOCKER_CONTENT_TRUST=1` means every image you build must be signed before push and Docker will refuse to pull anything unsigned, which breaks CI pipelines and base image pulls that weren't set up for it — a real operational lift. Most teams now get equivalent protection with less friction using Sigstore/cosign for image signing plus registry-level policies (like Kubernetes admission controllers) rather than DCT's older Notary-based workflow, so DCT usage has declined even though the threat it addresses is still real.