This tutorial walks you through setting up Trivy for comprehensive container security scanning in your CI/CD pipeline.
Install Trivy
# macOS
brew install trivy
# Linux (Ubuntu/Debian)
sudo apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update && sudo apt-get install trivy
# RHEL/Rocky/Alma
sudo rpm -ivh https://github.com/aquasecurity/trivy/releases/latest/download/trivy_*_Linux-64bit.rpmScan Container Images
# Basic scan
trivy image nginx:latest
# Only high and critical
trivy image --severity HIGH,CRITICAL nginx:latest
# Ignore unfixed vulnerabilities
trivy image --ignore-unfixed nginx:latest
# JSON output for CI/CD
trivy image -f json -o results.json nginx:latest
# Exit code for CI/CD gating
trivy image --exit-code 1 --severity CRITICAL nginx:latestScan Your Dockerfile
# Scan for misconfigurations
trivy config Dockerfile
# Common findings:
# - Running as root
# - Using latest tag
# - Missing HEALTHCHECK
# - Exposing unnecessary portsScan Kubernetes Manifests
# Scan YAML files
trivy config k8s/
# Common findings:
# - Containers running as root
# - Missing resource limits
# - Missing securityContext
# - Writable root filesystemScan Running Kubernetes Cluster
# Full cluster scan
trivy k8s --report summary cluster
# Specific namespace
trivy k8s -n production --report all
# Compliance report
trivy k8s --compliance k8s-nsa --report summaryCI/CD Integration
GitHub Actions
name: Security Scan
on: [push, pull_request]
jobs:
trivy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Trivy vulnerability scan
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: sarif
output: trivy-results.sarif
severity: HIGH,CRITICAL
- name: Upload results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarifGitLab CI
trivy-scan:
image: aquasec/trivy:latest
script:
- trivy image --exit-code 1 --severity CRITICAL $CI_REGISTRY_IMAGE:$CI_COMMIT_SHAGenerate SBOM
# SPDX format
trivy image --format spdx-json -o sbom.spdx.json myapp:v1
# CycloneDX format
trivy image --format cyclonedx -o sbom.cdx.json myapp:v1Suppressing False Positives
Create a .trivyignore file:
# Accepted risk: low impact, no fix available
CVE-2023-12345
# Will be fixed in next release
CVE-2024-67890Tips and Tricks
- Run
trivy image --download-db-onlyin CI setup to cache the vulnerability database - Use
trivy serverfor centralized scanning to avoid downloading the DB on every runner - Combine image scanning + config scanning + secret scanning for complete coverage
- Set up Trivy Operator for continuous scanning inside Kubernetes