Safeguard
Containers

Container Image Vulnerability Scanning in CI

How to wire container image vulnerability scanning into your CI pipeline so builds fail on real risk instead of shipping unscanned images to production.

Safeguard Team
Product
Updated 6 min read

A container image that passes unit tests can still ship a base OS with a dozen unpatched CVEs, because unit tests check application logic, not the operating system layers underneath it. Picking the right container image vulnerability tool for your pipeline starts with this idea: container image vulnerability scanning in CI means running an automated scanner against every built image before it's allowed to push to a registry or deploy, catching known-vulnerable packages, outdated base images, and exposed secrets while a fix is still a one-line diff instead of a production incident. Teams that only scan after deployment consistently find the same class of vulnerabilities — they just find them weeks later, after the image is already running somewhere.

Where in the pipeline should the scan actually run?

The scan should run immediately after the image build step and before the push-to-registry step, gating the pipeline so a vulnerable image never reaches a place another team or system could pull it from. Running the scan earlier, on source alone, misses vulnerabilities introduced by the base image and installed OS packages; running it later, against a running container in production, means the vulnerable image has already been deployed. The practical sequence most CI pipelines converge on is: build image, scan image, fail or warn based on policy, then push only images that pass. This also means the scan needs to be fast enough not to become the bottleneck — a scan step that adds ten minutes to every merge will get skipped or disabled the first time someone's under deadline pressure.

What should actually fail the build vs. just get logged?

New critical- or high-severity vulnerabilities with a known fix available should fail the build; everything else should be logged and tracked without blocking. This distinction matters because container images routinely carry dozens or hundreds of low-severity findings in packages the application never actually invokes, and gating on every single CVE regardless of severity or exploitability trains developers to ignore or bypass the gate entirely. A workable policy usually looks like:

  • Fail on critical/high CVEs with a published fix and no existing exception.
  • Warn (but don't block) on medium/low findings, routed to a backlog with an SLA.
  • Allow time-boxed exceptions for cases where no fix exists yet, tracked so they don't become permanent.
  • Re-scan images already sitting in the registry on a schedule, since a base image that was clean at build time can have a new CVE disclosed the following week.

Which layer catches problems the source-code scanner misses?

Image scanning catches vulnerabilities in the base OS and installed packages that never appear in your application's own source code or dependency manifest, because a Dockerfile pulling FROM node:20 inherits every package Debian or Alpine bundled into that image, not just the packages your package.json lists. This is the layer where CVEs in openssl, glibc, curl, or zlib show up — packages your team never explicitly chose to install but that came along with the base image. It's a distinct concern from source code analysis and dependency scanning, which is why most mature pipelines run SAST/DAST and SCA scanning alongside, not instead of, image scanning — each layer catches a different class of risk.

How do you handle reachability so you're not drowning in noise?

Reachability analysis — determining whether a vulnerable function or package is actually invoked by your application's code paths — cuts the volume of findings that need human triage dramatically, because a large share of CVEs reported in a full OS image sit in binaries or libraries the running application never calls. Without reachability filtering, a typical scan of even a moderately minimal image can return 50-150 findings, most of which are theoretical risk rather than exploitable risk in that specific deployment. Prioritizing by reachability, exploit availability (is there a public PoC or is it actively exploited), and exposure (internet-facing vs. internal-only service) turns an unmanageable list into a short one engineers will actually work through.

How does registry re-scanning fit alongside pipeline scanning?

Pipeline scanning only checks the image at the moment it's built — it says nothing about a CVE disclosed against that same base image three months later. Registry re-scanning closes that gap by periodically re-checking images already stored and in use, surfacing newly disclosed vulnerabilities in images that passed their original gate cleanly. Teams that skip this step end up with a false sense of security: everything that shipped "passed the scan," but nobody's re-checking what's still running six months on. Safeguard runs both continuous SCA scanning and image re-checks so a newly published CVE against an already-deployed base image surfaces automatically instead of waiting for the next rebuild.

FAQ

What are the best container vulnerability scanning tools to plug into CI?

Common options include Trivy, Grype, Docker Scout, Snyk Container, and Safeguard's own container scanning within its SCA and SAST/DAST products. Most integrate as a CLI step or GitHub Action that scans an image tag or tarball and exits non-zero on policy violation. Whichever container image vulnerability tool you pick, verify it can gate the build itself rather than just report findings after the fact — a tool that only produces a dashboard report doesn't stop a vulnerable image from shipping.

Does scanning slow down CI meaningfully?

A well-tuned scan against a cached vulnerability database typically adds well under a minute for small-to-medium images. Slowdowns usually come from re-downloading vulnerability feeds on every run rather than caching them, or scanning every layer redundantly instead of the final flattened image.

Should you scan multi-stage build images at every stage?

Scan the final runtime stage that actually ships — that's what runs in production. Some teams also scan intermediate build stages to catch secrets or vulnerable build tools, but the gating decision should be based on what's in the image that actually gets deployed.

What's the difference between image scanning and container image solutions more broadly?

Image scanning is one component of broader container image solutions, which typically also include base image hardening, registry access controls, image signing, and runtime monitoring. Scanning tells you what's wrong; the rest of the toolchain is about preventing and containing it.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.