Unsigned container images can be silently replaced in a registry — an attacker who gains push access to a registry can swap a legitimate image for a malicious one with the same tag, and every subsequent deployment pulls the compromised image without any cluster-level detection (CWE-494, NIST 800-53 CM-14, SLSA L3). Image signing with Cosign or Docker Content Trust creates a cryptographically verifiable chain from the image back to the CI system that built it. SSDF 800-218 PS.2.1 requires build provenance. Without admission webhook enforcement, signing alone is advisory — images can still be deployed without verification.
Low because unsigned image exploitation requires registry write access as a prerequisite, making it a targeted rather than opportunistic attack vector.
Sign images during CI/CD with Cosign and enforce verification at admission. In .github/workflows/build.yml:
# Generate key pair once, store private key as CI secret
cosign generate-key-pair
# Sign after push
cosign sign --key cosign.key $IMAGE_REF
Store COSIGN_PRIVATE_KEY and COSIGN_PASSWORD as CI secrets. The public key (cosign.pub) is committed to the repository. For enforcement, deploy Sigstore's policy-controller and create a ClusterImagePolicy referencing your public key — this blocks admission of any pod whose image digest cannot be verified against the policy.
ID: infrastructure-hardening.monitoring-incident-response.image-signing
Severity: low
What to look for: Check CI/CD pipelines for image signing steps (Cosign, Docker Content Trust, Notary). Count all container images built by the project and determine how many include signing. Check Kubernetes admission controller policies for signature verification enforcement (ImageSigningPolicy, ClusterImagePolicy).
Pass criteria: 100% of container images built by the project are signed during the CI/CD build step using Cosign, Docker Content Trust, or equivalent. Kubernetes enforces image signature verification at deployment time via an admission webhook or policy controller. Report: "X of Y images are signed; verification enforced via Z."
Fail criteria: Any images are unsigned, or signing exists but Kubernetes does not enforce signature verification at deployment time.
Skip (N/A) when: The project has minimal container usage or image signing is not feasible in the environment.
Detail on fail: Quote the CI/CD config and admission policy. Example: "Container images in registry are unsigned. No Cosign or Docker Content Trust signatures found in .github/workflows/build.yml." or "Images are signed, but no ValidatingWebhookConfiguration enforces signature verification at deployment time"
Remediation: Enable image signing with Cosign and enforce verification:
# Sign image during build
cosign sign --key cosign.key <image:tag>
# Create signing key
cosign generate-key-pair
Enforce verification in Kubernetes with policy controller:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: image-signature-verify
webhooks:
- name: image-signature.example.com
clientConfig:
service:
name: cosign-webhook
namespace: cosign-system
rules:
- operations: ["CREATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]