Trivy started as a vulnerability scanner. It has since evolved into a comprehensive security tool that handles SBOM generation, vulnerability scanning, misconfiguration detection, secret scanning, and license compliance -- all in one binary. For teams that want SBOM generation and vulnerability scanning without maintaining two separate tools, Trivy is the practical choice.
Built by Aqua Security and contributed to the open-source community, Trivy runs everywhere: laptops, CI/CD pipelines, Kubernetes clusters, and air-gapped environments.
Installation
# Official install script
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
# Homebrew
brew install trivy
# Docker
docker run --rm aquasec/trivy:latest --help
# APT (Debian/Ubuntu)
sudo apt-get install trivy
# RPM (RHEL/CentOS)
sudo yum install trivy
SBOM Generation
Trivy generates SBOMs in both CycloneDX and SPDX formats from multiple source types.
Container Images
# CycloneDX SBOM from a container image
trivy image --format cyclonedx --output sbom.cdx.json nginx:latest
# SPDX SBOM
trivy image --format spdx-json --output sbom.spdx.json nginx:latest
Filesystem (Source Code)
# Scan a project directory
trivy fs --format cyclonedx --output sbom.json ./my-project
# Scan with specific lockfile detection
trivy fs --format cyclonedx --output sbom.json --scanners license ./my-project
Git Repositories
# Scan a remote repository directly
trivy repo --format cyclonedx --output sbom.json https://github.com/myorg/myapp
SBOM as Input
Trivy can scan an existing SBOM for vulnerabilities, making it a consumer as well as a producer:
# Generate SBOM with one tool, scan with Trivy
syft alpine:latest -o cyclonedx-json > sbom.json
trivy sbom sbom.json
This decouples generation from scanning. You might generate SBOMs with Syft for its broader ecosystem support but scan with Trivy for its vulnerability database.
Vulnerability Scanning
Basic Scanning
# Scan a container image for vulnerabilities
trivy image nginx:latest
# Scan with severity filter
trivy image --severity HIGH,CRITICAL nginx:latest
# Scan and fail if vulnerabilities found (CI/CD gate)
trivy image --exit-code 1 --severity CRITICAL nginx:latest
Combined SBOM + Vulnerability Output
Trivy can embed vulnerability findings in the SBOM:
# CycloneDX with embedded vulnerability data
trivy image --format cyclonedx --output sbom-with-vulns.json \
--scanners vuln nginx:latest
The resulting CycloneDX document includes both the component inventory and a vulnerabilities section mapping CVEs to affected components. This is a complete picture in a single file.
Vulnerability Database
Trivy maintains its own vulnerability database, aggregated from multiple sources:
- NVD (National Vulnerability Database)
- Red Hat Security Advisories
- Debian Security Tracker
- Alpine SecDB
- GitHub Security Advisories
- And many more
The database updates automatically on first run and can be cached for air-gapped environments:
# Download DB for offline use
trivy image --download-db-only
# Use in air-gapped mode
trivy image --skip-db-update --offline-scan myimage:latest
Scan Types Beyond SBOM
Trivy's multi-scanner architecture covers more than just packages:
Misconfiguration Scanning
# Scan Terraform files
trivy config ./terraform/
# Scan Kubernetes manifests
trivy config ./k8s-manifests/
# Scan Dockerfiles
trivy config ./Dockerfile
Secret Detection
# Find hardcoded secrets
trivy fs --scanners secret ./my-project
# Scan container image for secrets
trivy image --scanners secret myapp:latest
License Scanning
# Check licenses of all dependencies
trivy fs --scanners license ./my-project
# Fail on copyleft licenses
trivy fs --scanners license --severity UNKNOWN,HIGH ./my-project
You can combine scanners in a single run:
# Everything at once: vulnerabilities, secrets, misconfigurations, licenses
trivy fs --scanners vuln,secret,config,license --format cyclonedx ./my-project
Kubernetes Integration
Scanning Running Clusters
Trivy has a Kubernetes operator mode that continuously scans workloads in your cluster:
# Install Trivy Operator via Helm
helm install trivy-operator aqua/trivy-operator \
--namespace trivy-system \
--create-namespace
# View vulnerability reports
kubectl get vulnerabilityreports -A
The operator creates Kubernetes custom resources (VulnerabilityReport, ConfigAuditReport) for each workload, making scan results queryable through the Kubernetes API.
CLI Cluster Scanning
# Scan all images in a Kubernetes cluster
trivy k8s --report summary cluster
# Generate SBOMs for all running workloads
trivy k8s --format cyclonedx --output cluster-sbom.json cluster
CI/CD Integration
GitHub Actions
- name: Trivy SBOM and Scan
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: cyclonedx
output: sbom.json
scanners: vuln,secret
- name: Trivy Vulnerability Gate
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
exit-code: 1
severity: CRITICAL
scanners: vuln
GitLab CI
trivy-scan:
stage: security
image:
name: aquasec/trivy:latest
entrypoint: [""]
script:
- trivy image --format cyclonedx --output sbom.json ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA}
- trivy image --exit-code 1 --severity CRITICAL ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA}
artifacts:
paths:
- sbom.json
reports:
cyclonedx: sbom.json
Jenkins Pipeline
stage('Security Scan') {
steps {
sh '''
trivy image --format cyclonedx --output sbom.json myapp:${BUILD_NUMBER}
trivy image --exit-code 1 --severity CRITICAL myapp:${BUILD_NUMBER}
'''
archiveArtifacts artifacts: 'sbom.json'
}
}
Trivy vs Syft: When to Use Which
Use Trivy when:
- You want SBOM generation and vulnerability scanning in one tool
- You're scanning Kubernetes clusters
- You need misconfiguration and secret scanning alongside SBOMs
- You want a single tool to maintain and update
Use Syft when:
- You need the broadest possible ecosystem detection
- You want a dedicated SBOM tool without scanning opinions
- You're pairing with Grype for vulnerability scanning
- You need maximum SBOM output customization
Use both when:
- You want Syft's detection breadth for generation and Trivy's database for scanning
- You're comparing tools to validate SBOM completeness
Performance and Caching
Trivy's first run downloads its vulnerability database (approximately 30-40 MB compressed). Subsequent runs use the cached database.
# Cache database in CI (GitHub Actions example)
- name: Cache Trivy DB
uses: actions/cache@v3
with:
path: ~/.cache/trivy
key: trivy-db-${{ hashFiles('.github/workflows/security.yml') }}
restore-keys: trivy-db-
- name: Download DB
run: trivy image --download-db-only
For air-gapped environments, pre-download the database and mount it:
# Download on internet-connected machine
trivy image --download-db-only --cache-dir ./trivy-cache
# Transfer trivy-cache to air-gapped environment
# Use with --cache-dir and --skip-db-update
trivy image --cache-dir ./trivy-cache --skip-db-update myimage:latest
How Safeguard.sh Helps
Safeguard complements Trivy by providing continuous monitoring and organizational visibility that a scan-time tool can't offer. Upload Trivy-generated SBOMs to Safeguard, and the platform re-evaluates them against fresh vulnerability data continuously -- not just at scan time. When a new CVE is published between your Trivy scans, Safeguard catches it. The platform aggregates results across all your projects, tracks remediation progress, and enforces policies that span your entire portfolio.