Trivy¶
What Is It?¶
Trivy is an open-source vulnerability scanner that inspects container images, filesystems, and running systems for known security issues. Given an image name, it identifies the operating system, lists installed OS packages and language-level dependencies (pip, npm, gem, …), looks each one up in a vulnerability database, and reports the CVEs that affect them.
Trivy is the automated half of container image audit. It will reliably find publicly known vulnerabilities — outdated openssl, vulnerable npm dependencies, expired packages — but it can do nothing about a custom-written backdoor a malicious image author has planted, because no public CVE describes it. Pair it with Dive for layer-level manual inspection.
Installation¶
Trivy is distributed via an official RPM repository for RHEL/CentOS:
sudo tee /etc/yum.repos.d/trivy.repo > /dev/null <<'EOF'
[trivy]
name=Trivy repository
baseurl=https://aquasecurity.github.io/trivy-repo/rpm/releases/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://aquasecurity.github.io/trivy-repo/rpm/public.key
EOF
sudo dnf install -y trivy
Verify:
trivy --version
The first scan will download the vulnerability database (~50–100 MB). Subsequent scans use the cached DB and only refresh it every 12 hours.
Key Files and Directories¶
| Path | Purpose |
|---|---|
/etc/yum.repos.d/trivy.repo | RPM repository definition |
~/.cache/trivy/ | Cached vulnerability database |
/usr/bin/trivy | The Trivy binary |
Configuration¶
Trivy is configured primarily via command-line flags. For most lab work, no config file is needed. The behaviour you'll most often tune:
Severity Filter¶
By default, Trivy reports vulnerabilities at every severity level (LOW, MEDIUM, HIGH, CRITICAL, UNKNOWN). On a deliberately old image this is overwhelming. Filter:
trivy image --severity CRITICAL <image>
trivy image --severity CRITICAL,HIGH <image>
Output Format¶
table (the default) is human-readable. json is machine-readable and useful when piping into other tools:
trivy image --format json <image> # all data, structured
trivy image --format json --severity CRITICAL <image> | jq '.Results[].Vulnerabilities[].VulnerabilityID' | sort -u
Disabling Secret Scanning¶
Trivy also looks for accidentally-committed secrets (API keys, passwords). On most images this is empty and slow:
trivy image --scanners vuln <image>
Common Commands¶
# Standard scan
trivy image registry.hpc.ut.ee/public/lab10-consultancy:latest
# Critical-only, no progress bar (good for scripting)
trivy image --severity CRITICAL --no-progress \
registry.hpc.ut.ee/public/lab10-consultancy:latest
# JSON output, only vulnerabilities, list of CVE IDs
trivy image --severity CRITICAL --scanners vuln --format json <image> \
| jq -r '.Results[].Vulnerabilities[]?.VulnerabilityID' | sort -u
# Refresh the vulnerability DB (normally automatic every 12h)
trivy image --download-db-only
# Scan a filesystem path instead of an image
trivy fs /path/to/project
Reading the Output¶
A typical CRITICAL-severity table looks like this:
registry.hpc.ut.ee/public/lab10-consultancy:latest (alpine 3.11.11)
Total: 4 (CRITICAL: 4)
┌──────────────┬────────────────┬──────────┬────────┬───────────────────┬───────────────┬──────────────────────────────────┐
│ Library │ Vulnerability │ Severity │ Status │ Installed Version │ Fixed Version │ Title │
├──────────────┼────────────────┼──────────┼────────┼───────────────────┼───────────────┼──────────────────────────────────┤
│ apk-tools │ CVE-2021-36159 │ CRITICAL │ fixed │ 2.10.6-r0 │ 2.10.7-r0 │ libfetch out of boundary read │
│ libcrypto1.1 │ CVE-2021-3711 │ CRITICAL │ fixed │ 1.1.1k-r0 │ 1.1.1l-r0 │ openssl: SM2 buffer overflow │
│ zlib │ CVE-2022-37434 │ CRITICAL │ fixed │ 1.2.11-r3 │ 1.2.11-r4 │ zlib: heap buffer over-read │
└──────────────┴────────────────┴──────────┴────────┴───────────────────┴───────────────┴──────────────────────────────────┘
What each column means:
- Library — the affected package or module
- Vulnerability — the CVE-ID (CVE-YYYY-NNNNN format). This is the canonical identifier you record or look up.
- Severity — Trivy's classification, derived from the upstream CVE's CVSS score.
- Status —
fixedmeans a patched version exists;affectedmeans the vulnerability is unpatched. - Installed / Fixed Version — what's in the image vs. what would resolve the CVE.
For each CRITICAL CVE, the question is usually: can I rebuild the image on a newer base, or upgrade the offending package?
Logging and Debugging¶
Trivy logs to stderr at INFO level by default. Useful flags:
--debug— verbose output for troubleshooting why a scan failed--quiet— suppress informational messages, only print results--cache-dir <path>— override the cache directory if disk space is tight in~
Common errors:
unable to download db: check internet connectivity and thatghcr.iois reachable.OS version is no longer supported by the distribution: expected on deliberately old images. Trivy still reports CVEs, just with a warning that the upstream may not be patching them anymore.no such image: the image must be pulled first, or the registry path must be reachable.
Security Considerations¶
- Trivy's vulnerability database comes from upstream and is updated regularly. A CVE that wasn't reported last week may appear today.
- "No CRITICAL CVEs" is not a clean bill of health. Trivy can only find what's in its database. Custom-planted malware does not have a CVE-ID and will pass Trivy with no findings. Always pair Trivy with manual inspection (Dive).
- Trivy can also scan filesystems (
trivy fs), git repositories (trivy repo), and Kubernetes manifests (trivy k8s). All can be useful as CI gates.
Further Reading¶
- Trivy Documentation
- Aqua Security Vulnerability Database
- CVE Program — canonical CVE identifier registry
Related Documentation¶
- Concepts: Containers
- Technologies: Docker, Dive
- SOPs: Container Operations