SBOM

Trivy for SBOM Generation and Vulnerability Scanning

Trivy combines SBOM generation with vulnerability scanning in a single tool. Here's how to use both capabilities effectively.

Michael
Security Engineer
6 min read

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.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.