Skip to content
Latchkey

Scanning Images for Vulnerabilities in CI

A scanner compares your image against CVE databases so you fix known vulnerabilities before they reach production.

Every base image and dependency you pull in can carry known vulnerabilities. Scanning in CI turns that into a gate you can enforce automatically. This lesson shows how to add a scan step and how to keep it from becoming noise.

What a scanner checks

An image scanner inventories the OS packages and language dependencies in your image, then matches them against vulnerability databases. It reports findings by severity, often with a fixed version when a patch exists.

Add a scan step

Run a scanner like Trivy against the built image and fail the job on high-severity findings.

.github/workflows/scan.yml
- uses: aquasecurity/trivy-action@0.24.0
  with:
    image-ref: ghcr.io/acme/myapp:sha-${{ github.sha }}
    severity: HIGH,CRITICAL
    exit-code: "1"
    ignore-unfixed: true

Keep the gate useful

  • Use ignore-unfixed so you only fail on vulnerabilities that actually have a fix.
  • Start by failing on CRITICAL, then tighten to HIGH as you clean up.
  • Scan the final image, not intermediate build stages.
  • Upload SARIF results so findings show in the security tab, not just logs.

Reduce findings at the source

The fastest way to pass a scan is to carry less. Minimal and distroless base images plus multi-stage builds drastically cut the number of packages -- and therefore the number of CVEs you have to triage.

Key takeaways

  • Scanners inventory packages and match them against CVE databases, reporting by severity.
  • Fail builds on fixable HIGH/CRITICAL findings and ignore unfixed noise.
  • Minimal and distroless bases cut the package count, so there is less to scan and triage.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →