How do you implement Docker content trust and image signing to prevent tampered images from running?
Quick Answer
Docker Content Trust uses The Update Framework (TUF) to sign images with cryptographic keys at push time and verify signatures at pull time. Modern approaches use Cosign with keyless signing tied to CI/CD identity providers, combined with Kubernetes admission controllers like Kyverno or OPA Gatekeeper that enforce signature verification, blocking any unsigned or tampered image from running in production clusters.
Detailed Answer
Think of image signing like the notarization process for financial documents at a bank. When a loan officer prepares a mortgage document, the document is reviewed, verified, and stamped by a licensed notary. The notary seal proves three things: the document came from the bank (provenance), it has not been altered since signing (integrity), and a specific authorized person vouched for it (accountability). If anyone changes even a single word after notarization, the seal becomes invalid and the document is rejected. Container image signing provides the same guarantees for software: the image was built by an authorized pipeline, it has not been tampered with since signing, and there is an auditable record of who authorized it.
Docker Content Trust is Docker's built-in signing mechanism, based on The Update Framework and the Notary project. When DCT is enabled through the DOCKER_CONTENT_TRUST environment variable, every docker push operation signs the image with the publisher's private key, and every docker pull operation verifies the signature before accepting the image. DCT uses a two-key architecture: a root key that should be stored offline in a hardware security module and a repository-specific signing key used for daily operations. While DCT provides basic signing capabilities, it has limitations in modern CI/CD environments: key management is complex, the Notary server adds infrastructure overhead, and integration with Kubernetes admission controllers requires additional tooling.
Cosign from the Sigstore project has emerged as the modern standard for container image signing in enterprise environments. Cosign's keyless signing mode uses OIDC identity providers to bind signatures to verified identities rather than manually managed private keys. In a banking CI/CD pipeline, the GitHub Actions workflow authenticates to Sigstore's Fulcio certificate authority using the workflow's OIDC token, receives a short-lived signing certificate, signs the image, and records the signature in Sigstore's Rekor transparency log. The signature is stored as an OCI artifact alongside the image in the container registry. This approach eliminates private key management entirely: there is no key to rotate, leak, or protect in a hardware security module. The transparency log provides a tamper-evident audit trail of every signing event, which banking regulators can verify independently.
Kubernetes admission controllers complete the trust chain by enforcing signature verification at deployment time. Without admission control, signing images is security theater because nothing prevents unsigned images from running. Kyverno's verifyImages rule or OPA Gatekeeper with the Cosign constraint template intercept pod creation requests, extract the image reference, query the registry for the Cosign signature, verify it against the expected identity (the CI/CD pipeline's OIDC issuer and subject), and reject the pod if verification fails. In banking environments, this policy applies to all production namespaces and blocks images from unauthorized registries, unsigned images from authorized registries, and images signed by unauthorized pipelines. The admission controller also validates image attestations, which are signed metadata about the image's build process, such as the scan results, SBOM, and build provenance.
The production gotcha is the operational complexity of bootstrapping trust across a large organization. When image signing is first enforced, every existing deployment must be updated with signed images, or pods will fail to start after a rollout. Teams must coordinate a migration period where the admission controller runs in audit mode, logging violations without blocking. During this period, all CI/CD pipelines are updated to include the signing step, all existing images in the registry are re-signed, and all Deployment manifests are updated to reference signed image digests. Another critical consideration is signature verification latency: the admission controller must contact the registry for every pod creation, adding milliseconds to pod scheduling. At scale, teams cache verification results and configure timeouts to prevent Vault or registry outages from blocking all pod creation. Banking teams also implement emergency bypass procedures for disaster recovery, where a designated security officer can temporarily disable enforcement through a documented break-glass process that is fully audited.