A secure container image is more than an image with no obvious critical vulnerability. Before deployment, you should be able to explain where the image came from, what software it contains, whether its contents changed, which risks were accepted, and where it is allowed to run. This reusable container image security checklist covers base-image selection, vulnerability scanning, secrets detection, SBOM generation, signing, provenance, registry controls, admission policies, patch triage, and runtime verification.
Overview
Container security starts before an image reaches a registry. A practical process treats the image as a software supply-chain artifact rather than a disposable build output. The goal is not to promise that an image will never contain a vulnerability; that is rarely a realistic standard for software that depends on operating-system packages and application libraries. The goal is to make the image observable, verifiable, reproducible where possible, and subject to clear release decisions.
Use this checklist at four points: when selecting a base image, during the build, before promotion to a production registry, and at deployment time. Record the image digest, scan results, SBOM, signing information, build metadata, exceptions, and owner. A mutable tag such as latest is useful for development workflows but should not be the only production reference. A digest identifies a specific image manifest and makes later verification more precise.
For the scanning stage itself, compare capabilities rather than assuming one tool fits every environment. Our container vulnerability scanning comparison provides a starting point for evaluating standalone scanners, Docker-integrated tools, and registry-based scanning.
| Control | Question it answers | Useful output |
|---|---|---|
| Vulnerability scan | What known issues affect the image? | Finding, severity, package, fixed version, and status |
| Secret detection | Did credentials or sensitive files enter the image or its layers? | Finding location, type, and revocation status |
| SBOM | Which packages and components are present? | Machine-readable component inventory |
| Signing and provenance | Who built this artifact, and was it changed? | Signature, identity, digest, and build metadata |
| Admission control | Should this image be allowed to run here? | Allow, deny, or review decision |
Checklist by scenario
1. Selecting a base image
- Choose a base image with a clear maintainer, documented release process, and an update path that your team can monitor.
- Prefer a minimal image when it remains compatible with the application and operational tooling. Fewer packages generally make the inventory easier to review, but minimal does not automatically mean secure.
- Pin the base image by digest or use a controlled update process that records exactly which version entered the build.
- Check whether the image includes a package manager, shells, compilers, debugging tools, or other utilities that are unnecessary at runtime.
- Confirm that the application supports the chosen operating-system libraries and CPU architecture before standardizing the image.
2. Building the image
- Use a reviewed Dockerfile or equivalent build definition stored with the application source.
- Use multi-stage builds to keep compilers, test utilities, and source files out of the runtime stage where practical.
- Keep build inputs explicit. Avoid downloading unverified scripts or packages during a build without recording their origin and integrity information.
- Run tests, linting, dependency checks, and secret detection before publishing the image.
- Review build arguments and environment variables. Do not place passwords, API keys, private certificates, or tokens in build arguments, image environment variables, or filesystem layers.
- Generate an SBOM for the final image, not only for the source repository or an intermediate build stage. Use a recognized machine-readable format supported by your inventory and review systems.
3. Scanning and release decisions
- Scan both operating-system packages and application dependencies. A clean operating-system scan does not prove that language packages or bundled binaries are safe.
- Scan the final image after it is built, because later Dockerfile instructions can add files and packages that were absent from earlier stages.
- Capture the scanner database or tool version with the result where possible. Findings can change as vulnerability data and package matching improve.
- Define a release policy that considers severity, exploitability, exposure, affected functionality, available fixes, and compensating controls.
- Do not use a severity label as the only decision rule. A team may block a lower-rated issue in an exposed component or temporarily accept a higher-rated issue in an isolated, non-production image, provided the decision has an owner, rationale, and review date.
- Rescan images already in the registry. New vulnerability disclosures can affect an unchanged image.
4. Signing, provenance, and registry controls
- Sign the image or its digest after the approved build completes. Define which identity is trusted to sign production artifacts.
- Attach provenance that identifies the source revision, build system, builder or workflow identity, and relevant parameters. Keep provenance separate from assumptions about human authorship.
- Restrict who can push, delete, overwrite, or promote images in each registry repository.
- Separate development, testing, and production repositories or namespaces when that improves permission boundaries and review.
- Use immutable tags or digest-based promotion where your registry and deployment process support it.
- Apply retention rules carefully. Keep the signed artifact, SBOM, scan result, and release record together long enough to support incident response and auditing. See our guide to container registry retention policies before automating cleanup.
5. Deploying and verifying at runtime
- Configure the deployment platform to accept only approved registries, repositories, signatures, attestations, or digests as appropriate.
- Use admission controls to block unsigned images, images from untrusted locations, or images that fail defined policy checks.
- Run the application with a non-root user where feasible, restrict Linux capabilities, and use a read-only root filesystem when the application supports it.
- Set resource requests and limits, avoid unnecessary host mounts, and restrict access to the container runtime socket.
- Monitor the running workload and retain the image digest in deployment records so an alert can be tied to the exact artifact.
- For Kubernetes environments, align image policy with broader workload hardening. Our guide to Kubernetes Pod Security Standards covers the related deployment controls.
What to double-check
Before approving an image, verify that the scan covered the artifact that will actually run. A frequent gap occurs when CI scans one tag while deployment later resolves a different tag or digest. Compare the digest in the scan record, registry, deployment manifest, and running workload.
Review the SBOM for components that scanners may classify differently across ecosystems. Look for vendored libraries, statically linked binaries, copied application directories, generated files, and packages installed in earlier build stages that accidentally remain in the final layer. An SBOM is an inventory, not a guarantee of security, but it makes impact analysis substantially more concrete when a new issue is disclosed.
Confirm the secret-detection result includes image history and layers when the tool supports that inspection. Removing a secret in a later Dockerfile instruction may leave it recoverable in an earlier layer. If a real credential was committed or embedded, treat it as exposed: revoke or rotate it, investigate access, and rebuild the image rather than relying on deletion alone.
Finally, test the verification path. A signing policy that exists only in documentation does not protect a cluster. Confirm that an unsigned test image is rejected in the intended environment, that approved identities are recognized, and that emergency exceptions are logged and automatically expire.
Common mistakes
- Scanning only during development: Vulnerability data changes after release, so registry and deployed-image rescans are necessary.
- Trusting a tag: Tags can move. Use digests or a controlled promotion mechanism for production decisions.
- Blocking every finding without triage: This can encourage unsafe bypasses and obscure the findings that matter most. Define an accountable exception process instead.
- Generating an SBOM but not retaining it: Store it with the image digest and release record so it can be searched during an incident.
- Assuming a small image is automatically safe: Size reduction helps reduce inventory and attack surface, but it does not replace patching, identity controls, or runtime restrictions.
- Leaving build tools in production: Multi-stage builds and explicit runtime contents reduce unnecessary software and simplify review.
When to revisit
Review this checklist before onboarding a new base image, changing the build system, moving registries, enabling a new deployment platform, or preparing for a security or compliance review. Revisit it after a major vulnerability disclosure, a change to signing or provenance tooling, an update to SBOM formats, or a change in the admission-control policy supported by your platform.
At minimum, schedule a quarterly review of scanner coverage, severity guidance, registry permissions, signing identities, retention rules, and exception records. Also inspect the process before seasonal planning or large release cycles, when dormant images may return to production and ownership can be unclear.
For the next image you release, make the workflow concrete: record the base-image digest, build the smallest practical runtime image, scan the final artifact, detect secrets, generate and retain an SBOM, attach provenance, sign the digest, test the admission policy, and verify the digest after deployment. That sequence turns container image security from a one-time check into a repeatable release gate.