← All guides

Container image scanning

Build & artifactsDraugr: available today

In plain terms#

Your application code is only part of what ships. When you build a container image, you also bundle an operating system, system packages, and language runtimes, often hundreds of components you never chose directly (they came from the base image). Container image scanning inventories everything inside an image and checks it for known vulnerabilities.

It's SCA applied to the whole box your app runs in, not just its dependencies.

Why it matters#

A pristine codebase running on a two-year-old base image is still exposed to every unpatched OS-level CVE in that image. Base images drift out of date silently, and "it built fine" says nothing about whether openssl inside it has a critical vulnerability. Image scanning is what keeps the gap between "my code is clean" and "my container is clean" from surprising you.

Where it fits#

  • Artifact: a built container image (local, or in a registry, referenced by tag or digest).
  • Stage: at build time (scan before you push) and continuously in the registry (a clean image today can have a new CVE tomorrow, the image didn't change, the world did).

How it works#

A scanner reads the image layer by layer, enumerates OS packages (from the apk/apt/rpm databases) and language dependencies, and matches them against vulnerability feeds. Good tools map findings to the specific layer that introduced them (so you know whether it's your Dockerfile or the base image at fault) and tell you if a fixed package version exists.

ToolNotes
TrivyOSS, very widely used; scans images, filesystems, and more
GrypeOSS, from Anchore; pairs with the Syft SBOM tool
ClairOSS; powers registry-side scanning (e.g. Quay)
Docker Scout, Snyk ContainerCommercial/integrated options

Common pitfalls#

  • Choose a small base image. Distroless or Alpine/Chainguard images carry far fewer packages, and therefore far fewer CVEs, than a full ubuntu base. The cheapest fix is often a smaller base.
  • Unreachable OS CVEs. Many flagged packages aren't used by your app; prioritize by exposure and reachability, not raw count.
  • Scan by digest. Tags move; pinning to an image digest makes scans reproducible.
How Draugr fits. Draugr's images control runs Trivy against each container image a component declares, normalized to SARIF. Combined with the component's exposure and criticality, image CVEs are ranked into an actionable order rather than a raw count. See how to declare images in a Saga in the docs.

Grype can serve the same control, on its own or beside Trivy. Both sets of findings arrive in one report, ranked by the same risk model. Two matchers draw on different advisory sources, so where they disagree that difference is a statement about coverage neither makes alone.

Keep learning#

  • SCA, vulnerabilities in your application dependencies
  • SBOM, the parts list image scanning builds on
  • IaC misconfiguration, securing the Dockerfile itself