Using Trivy to Scan Software Artifacts

Learn to use Trivy to analyze container images and other software artifacts for a variety of issues

Trivy is a vulnerability scanner for a wide variety of software artifacts and deployments. Trivy is written in the Go programming language and is maintained by Aqua Security. Trivy targets container images, VMs, filesystems, remote GitHub repositories, and Kubernetes and Amazon Web Services deployments. The tool can be used to detect known vulnerabilities (CVEs), generate SBOMs, analyze licenses, and scan for misconfigurations and exposed secrets. Trivy can be installed from package managers or as a binary, and can also be run as a container image.

Installation

Package Managers

For Homebrew, use:

brew install trivy

Aqua Security maintains sources and packages for a variety of additional operating systems and distributions on their installation page.

Binary Installation

Aqua Security provides an installation script for Trivy. To install Trivy with the script, change the /usr/local/bin argument to the desired installation location on your path before running the following command:

curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v0.52.2

On many system configurations, you may need to provide elevated permissions via sudo:

curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin v0.52.2

You can also manually install Trivy by downloading the binary for your operating system and architecture from the Trivy releases page and manually placing the binary on your path.

Container Image

Container images for Trivy are hosted on a variety of registries. When running Trivy as a container image, it is recommended to mount a cache directory as a volume. For scanning container images, it is also recommended to mount docker.sock.

The following command will pull Trivy from Docker Hub, mount the two volumes, run the Trivy container, and use the running container to scan the official nginx image on Docker Hub:

docker run \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $HOME/Library/Caches:/root/.cache/ \
  aquasec/trivy:0.52.2 \
  image nginx

Basic Usage

Throughout this tutorial, we’ll use the trivy command to run Trivy. If you’re running Trivy as a container image, replace this command with the appropriate docker run command.

To use Trivy, provide a subcommand indicating the type of artifact or deployment to be scanned along with the location of the target. For example, to scan the official Python image on Docker Hub:

trivy image python

Trivy will output a series of informational messages, a short summary of CVEs found, including severity, and an itemized list of CVEs.

Valid Targets

Trivy can scan a wide variety of artifacts, collections, or deployments, collectively called targets. Each type of software artifact has a specific set of Trivy scanners enabled by default. For example, when scanning container images, Trivy will look for vulnerabilities and exposed secrets by default.

Scanning a Container Image

To scan a container image on Docker Hub, use the image subcommand and the name of the image as an argument:

trivy image nginx

For images on other registries:

trivy image cgr.dev/chainguard/nginx:latest

Scanning a Filesystem

Trivy can recursively scan directories on a local machine.. To start a filesystem scan, run:

trivy fs <path>

where <path> indicates the root folder where the scan will begin. Trivy looks out for specific files containing lists of packages, such as Python’s requirements.txt or poetry.lock, PHP’s composer.lock, or Node’s package-lock.json.

The following creates a Python project folder with virtual environment, installs a set of older packages, generates a requirements.txt file itemizing all transitive dependencies, and scans the project folder using Trivy:

mkdir python-project && cd python-project
python -m venv venv
./venv/bin/pip install WTForms==2.3.3 Werkzeug==2.0.1
./venv/bin/pip freeze > requirements.txt
trivy fs .

The following creates a default Node project, installs an older package with npm, and scans the project with Trivy:

mkdir node_project && cd node_project
npm init -y
npm install qs@6.5.2
trivy fs .

You should see a summary and itemized list of CVEs for the outdated Node package.

Scanning Clusters

To scan a Kubernetes cluster:

trivy k8s --report summary <cluster-name>

To try out the above command on a test Kubernetes cluster, First install Kind, a utility allowing Kubernetes to be run on your local machine.

Once Kind is installed and accessible on your path, run the following to create a cluster:

kind create cluster --name test-cluster

Run the following to scan the new cluster with Trivy:

trivy k8s --report summary kind-test-cluster

When scanning clusters, requesting only summary output is recommended, as tables in more verbose output may not display correctly.

Scanning SBOMs

Trivy can both generate and scan SBOMs.

What is an SBOM?

A Software Bill of Materials (SBOM) is a formally structured list of libraries, modules, licenses, and version information that make up any given piece of software. An SBOM provides a comprehensive view of the components contained in a software artifact, allowing for systematic analysis, investigation, and automation. SBOMs are most useful in identifying known vulnerabilities, surveying licenses for compliance, and making decisions based on project status or supplier trust.

Read more about SBOMs on Chainguard Academy.

First, generate an SBOM file in CycloneDX format to scan

trivy image -f cyclonedx -o results.cdx.json nginx

Trivy can scan this generated CycloneDX SBOM with the following:

trivy sbom results.cdx.json

By default, the sbom subcommand scans only for vulnerabilities. License scanning can be enabled using the --scanners license flag.

Some image providers, such as Chainguard, associate images with an SBOM attestation verifying that the image has not been tampered with since the time of creation. Trivy provides functionality to query attestations registered in the Rekor transparency log. To retrieve an SBOM attestation from a Rekor transparency log, set the --sbom-sources flag to rekor and provide the --rekor-url flag to the instance of the transparency log you wish to query against. The following will perform a scan using the SBOM attestation for Chainguard’s nginx image as registered on the Rekor public server:

trivy image --sbom-sources rekor --rekor-url https://rekor.sigstore.dev/ cgr.dev/chainguard/nginx

Learn more about SBOMs and other output formats in the section on specifying output formats.

Comprehending Trivy Output

When run with default output and formatting, Trivy first prints a series of informational messages and warnings, then the name of the image and a one-line summary of the number and severity of issues found, and finally a table itemizing each issue.

In this section, we’ll use an Alpine version of the official Python image as an example. Since we’re specifying an older version, you may encounter more CVEs when following the examples than are shown here, as CVEs will accumulate on an image over time.

Scan the image with the following command:

trivy image python:3.10.14-alpine3.20

You will receive output similar to the following:

Screenshot of Trivy output showing first informational messages on which scanners are inabled, then the name of the image, then a listing of issues by severity, and finally a table formatted with ASCII seperators (pipes and underscores) showing itemized issues

Interpreting Trivy Output

The initial logging portion of Trivy’s output indicates which scanners are enabled and shows warnings if Trivy has an issue performing the scan.

In the initial portion of its results output, Trivy summarizes information on the scanned artifact and gives an overview of known vulnerabilities. In the case of a scanned image, the output includes the image digest. This is a unique hash of the image that can be used as an identifier.

Following the log, Trivy shows the name of the image and a count of issues by severity.

Total: 8 (UNKNOWN: 0, LOW: 0, MEDIUM: 8, HIGH: 0, CRITICAL: 0)

When scanning for vulnerabilities, this severity categorization sorts CVEs into four categories based on the Common Vulnerability Scoring System (CVSS).

What is CVSS?

CVEs are assigned numerical scores according to the Common Vulnerability Scoring System (CVSS), an open framework for communicating the severity of software vulnerabilities.

CVSS scores correspond to four categories

  • Critical (9.0-10.0)
  • High (7.0-8.9)
  • Medium (4.0-6.9)
  • Low (0.1-3.9)

In general, the higher the score, the more serious the vulnerability. Higher scores should be prioritized during CVE remediation.

In the case of a license scan, Trivy instead uses its own assessment of the business risk posed by specific license clauses. Similarly, explosed secrets and misconfigurations have their own severity mapping as determined by Aqua Security.

Itemized CVEs

In addition to the log and brief summary, Trivy provides an itemized list of issues. By default, these are in table format, and for a vulnerability scan list the library, vulnerability, severity, status, installed version, and fixed version of each issue. Other types of scan list different data—for example, a license scan lists the package, license, license classification, and perceived severity of business risk.

When scanning for vulnerabilities, information on fixed version can show which CVEs can be resolved by bumping the library version. Trivy also provides a short prose description of the nature of each issue.

By default, Trivy’s table output is relatively verbose, and Trivy does not respect the traditional 80-character line limit on terminal output. See Output Formats and Verbosity for information on more granular control over Trivy’s output.

Scanners

Specifying Scanners

Trivy can scan not only for known vulnerabilities, but also for misconfigurations, exposed secrets, and license risks. When scanning container images or filesystems, Trivy scans for vulnerabilities and exposed secrets by default.

Individual scanners can be selected by passing a comma-separated list after the --scanners flag. To add a misconfigurations scan to an analysis of a container image:

trivy image --scanners vuln,misconfig,secret nginx

To recursively scan only for exposed secrets on a filesystem:

trivy fs --scanners secret .

This will perform a recursive scan of all files and folders in the current working directory.

License Scanning

Trivy provides an opinionated license scan that flags license clauses that may pose a business risk. To perform a license scan on a container image:

trivy image --scanners license nginx

By default, the Trivy license scan only looks at packages installed by managers such as apt or apk. To scan other files, add the --license-full flag:

trivy image --scanners license --license-full nginx

Using the --license-fullflag will also show results for “loose” licenses, such as those provided as text files in project folders.

Output Formats and Verbosity

Specifying Output Formats

Trivy allows output in JSON, SARIF, CycloneDX, SPDX, SPDX-JSON, and GitHub formats. If no output or format flags are specified, Trivy first prints a series of informative messages and warnings to stderr and then prints a table of results to stdout.

The -q or --quiet flag suppresses the logging output normally printed to stderr. The following returns just the line summarizing the number and severity of issues:

trivy image -q nginx | grep Total:
Total: 173 (UNKNOWN: 2, LOW: 88, MEDIUM: 59, HIGH: 22, CRITICAL: 2)

The -f or --format flag specifies the output format, and the -o or --output flag specifies an output file. The following writes a JSON-formatted report to a results.json file.

trivy image -f json -o results.json nginx

Similarly, the following would write a report in SARIF format:

trivy image -f sarif -o results.sarif nginx

Other formats can be generated by passing the appropriate format type with the -f or --format flag.

Generating SBOMs

The CycloneDX, SPDX, and SPDX-JSON output formats are considered SBOMs, and can be scanned with the trivy sbom subcommand. The following command will generate an SBOM in CycloneDX format:

trivy image -f cyclonedx -o results.cdx.json nginx

See Scanning SBOMs for more on scanning these output formats.

Generating a Report from a Template

Trivy can generate reports in additional formats from user-contributed templates. To use templates, first clone the Trivy GitHub repository to your home folder:

git clone https://github.com/aquasecurity/trivy.git ~/.trivy

To generate a report using the HTML template, specify the path to the template in the cloned repository:

trivy image --format template --template "@.trivy/contrib/html.tpl" -o report.html nginx

This HTML output can be significantly more readable than Trivy’s default table output:

Screenshot of rendered HTML generated by the Trivy HTML template

Other template-based output formats can be browsed in the Trivy contrib directory.

Trivy Resources

The following resources may complement your use of Trivy: