Trivy can scan your container images for vulnerabilities, misconfigurations, and secrets without needing to download the entire image first.
Let’s see it in action. Imagine you have a Dockerfile like this:
FROM alpine:3.18
RUN apk add --no-cache nginx
COPY index.html /var/www/localhost/htdocs/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
You want to build this image and then scan it.
First, build the image:
docker build -t my-nginx-app:latest .
Now, run your first Trivy scan against that image for vulnerabilities:
trivy image my-nginx-app:latest
The output will look something like this, detailing vulnerabilities found in the alpine:3.18 base image and any packages you installed:
my-nginx-app:latest (alpine 3.18.4)
Total: 56 (CRITICAL: 0, HIGH: 15, MEDIUM: 21, LOW: 20)
┌───────────────┬───────────┬───────────┬────────────┬─────────────┬─────────────┐
│ LIBRARY │ INSTALLED │ VULNERABLE│ DESCRIPTION│ SEVERITY │ CVE ID │
├───────────────┼───────────┼───────────┼────────────┼─────────────┼─────────────┤
│ nginx │ 1.24.0 │ 1.24.0 │ CVE-2023-38545 │ HIGH │ CVE-2023-38545 │
│ │ │ │ │ │ CVE-2023-38546 │
│ │ │ │ │ │ CVE-2023-38547 │
│ │ │ │ │ │ CVE-2024-24972 │
│ │ │ │ │ │ CVE-2024-25081 │
│ │ │ │ │ │ CVE-2024-25082 │
│ │ │ │ │ │ CVE-2024-25083 │
│ │ │ │ │ │ CVE-2024-25084 │
│ │ │ │ │ │ CVE-2024-25085 │
│ │ │ │ │ │ CVE-2024-25086 │
│ │ │ │ │ │ CVE-2024-25087 │
│ │ │ │ │ │ CVE-2024-25088 │
│ │ │ │ │ │ CVE-2024-25090 │
│ │ │ │ │ │ CVE-2024-25091 │
│ │ │ │ │ │ CVE-2024-25092 │
│ alpine │ 3.18.4 │ 3.18.4 │ CVE-2023-2650 │ MEDIUM │ CVE-2023-2650 │
│ │ │ │ │ │ CVE-2023-3962 │
...
This output shows the nginx package and alpine base image have vulnerabilities. Trivy tells you the exact version installed, the vulnerable version, a brief description, the severity, and the CVE ID.
Trivy works by leveraging a vast, regularly updated vulnerability database. When you scan an image, it doesn’t just look at the package names; it inspects the specific versions of every installed package. It then cross-references these versions against its database of known Common Vulnerabilities and Exposures (CVEs). For configuration scans, it checks for common security misconfigurations based on predefined policies. Secrets detection involves pattern matching for common sensitive data formats.
The core problem Trivy solves is the inherent complexity and risk associated with containerized applications. As applications grow, so does their dependency surface. Manually tracking vulnerabilities across numerous base images, application libraries, and system packages is practically impossible. Trivy automates this, providing a clear, actionable report that security teams and developers can use to prioritize remediation efforts.
You can also scan for different types of issues. To check for misconfigurations (like open ports in your Dockerfile or insecure kernel settings), use the --security-checks config flag:
trivy config --severity HIGH,CRITICAL --filter-unfixed -f json Dockerfile
This command scans the Dockerfile itself for potential misconfigurations, focusing on high and critical severity findings and excluding any that haven’t been fixed in newer versions of the scanned components. The -f json flag outputs the results in JSON format, which is useful for integration with other tools.
Here’s an example of what a configuration scan might reveal:
[
{
"Target": "Dockerfile",
"Severity": "HIGH",
"RuleId": "dockerfile-1",
"RuleCategory": "SECURITY_MISCONFIGURATION",
"Messages": [
"Ensure that the container is not running as root user."
],
"Description": "Running containers as root can lead to privilege escalation if the container is compromised.",
"Links": [
"https://avd.aquasec.com/misconfigurations/dockerfile-1"
]
}
]
The key to effectively using Trivy lies in understanding its different scan types and how to tailor the output. You can scan container images (as shown above), file systems (trivy fs /path/to/your/app), Git repositories (trivy repo https://github.com/youruser/yourrepo), and even Kubernetes manifests (trivy k8s /path/to/k8s/manifests). Each scan type uses different techniques to identify vulnerabilities, misconfigurations, or secrets relevant to its target.
What’s often overlooked is how Trivy handles different package managers. It has built-in support for detecting and analyzing packages installed via apk (Alpine Linux), apt (Debian/Ubuntu), yum (CentOS/RHEL), npm, pip, gem, maven, and many others. When you scan an image, Trivy intelligently identifies the operating system and its package manager, then uses the appropriate detection logic to list installed packages and their versions, making it broadly applicable across diverse application stacks.
The next step after identifying vulnerabilities is to remediate them. You’ll often find yourself needing to update base images or application dependencies.