Tools · Containers and Kubernetes security · 11 / 20
Trivy tutorial: scanning container images for vulnerabilities, secrets, and misconfigurations
Install Trivy, scan an image and a Dockerfile, read severity and fixed-version columns, and add a CI gate that fails only on fixable critical findings.
What Trivy finds
Trivy is an open-source scanner from Aqua Security. For images it inventories operating system packages and language dependencies, then matches them against vulnerability databases. It can also detect secrets committed into layers and misconfigurations in Dockerfiles, Kubernetes manifests, and Terraform.
Results are a list of package, installed version, CVE, severity, and fixed version. A finding with no fixed version is still real but cannot be solved by upgrading today.
Running scans
Scan a public image, then filter to what you can act on. --ignore-unfixed hides findings without a fix. --severity limits output. --scanners selects vulnerability, secret, or misconfiguration checks.
trivy image python:3.9-slim trivy image --severity HIGH,CRITICAL --ignore-unfixed python:3.9-slim trivy image --scanners secret myapp:dev trivy config ./deploy/ # Dockerfiles and Kubernetes YAML trivy image --format json -o report.json myapp:dev
Lab: compare two base images
Scan an older full base image such as python:3.9 and a slim or distroless equivalent. Count findings by severity using the JSON output and jq. Rebuild a small app on the smaller base and scan again. Most of the reduction comes from simply shipping fewer packages.
trivy image -q --format json python:3.9 | jq '[.Results[].Vulnerabilities[]?.Severity] | group_by(.) | map({(.[0]): length}) | add'
trivy image -q --format json gcr.io/distroless/python3-debian12 | jq '[.Results[].Vulnerabilities[]?.Severity] | group_by(.) | map({(.[0]): length}) | add'A sensible CI gate
Fail builds on fixable CRITICAL findings with --exit-code 1, and report everything else. Track accepted risks in a .trivyignore file with a comment and review date for each CVE. Rescan images already in registries on a schedule, because new CVEs appear for packages that were clean at build time.
trivy image --exit-code 1 --severity CRITICAL --ignore-unfixed myapp:${GIT_SHA}Diagram
Image scanning in a pipeline
- Build
Build the image from a pinned, minimal base.
- Scan
Scan for vulnerabilities, secrets, and misconfigurations.
trivy image --exit-code 1 --severity CRITICAL --ignore-unfixed app:sha
- Gate
Fail on fixable critical findings; report the rest.
- Rescan
Rescan stored images daily as new CVEs are published.
Check yourself
1. Which flag hides vulnerabilities that have no fixed version yet?
2. What usually reduces image findings the most?
3. Why rescan images that already passed CI?