← News
/PLAYBOOK · 2026-08-09

Trivy Container Image Scanning: CI/CD Vulnerability Detection and Remediation Guide

Install Trivy, run image scans, integrate CI/CD gates, export SARIF, and manage exemptions with .trivyignore. Includes a full GitHub Actions example that scans on build and blocks HIGH/CRITICAL from production.

Scope

Trivy container image scanning applies to these cases: automatic vulnerability scans after image builds in CI/CD, security admission checks on production images before release, periodic inspection of existing images in private registries, and image security validation before Kubernetes deployment. For teams already using Docker and Kubernetes, Trivy is the lowest-barrier image vulnerability management tool.

Prerequisites

Mechanism

Trivy (Treasure Vulnerability) is Aqua Security's open-source vulnerability scanner. It compares the image filesystem against a CVE database: it parses package-manager metadata in each image layer (APK, RPM, DEB), extracts package names and versions, then matches them against NVD, Red Hat, Debian, Alpine, Ubuntu, and other vulnerability sources, outputting affected CVEs and severity. Trivy also generates SBOMs (software bills of materials) and detects secrets such as keys. Scans typically finish in seconds.

Procedure

1. Install Trivy

# Debian/Ubuntu
sudo apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update && sudo apt-get install trivy

# Binary install (any distro)
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin

Verify install: `trivy --version`.

2. Basic image scan

# Pull the image to scan
docker pull nginx:1.27

# Scan image (first run downloads the vuln DB)
trivy image nginx:1.27

# HIGH and CRITICAL only
trivy image --severity HIGH,CRITICAL nginx:1.27

# Ignore unfixed vulns (many have no upstream patch)
trivy image --ignore-unfixed nginx:1.27

Output lists vulns by CRITICAL / HIGH / MEDIUM / LOW, with CVE IDs, affected packages, and fixed versions.

3. Output formats and export

# JSON, for platform integration
trivy image --format json --output result.json nginx:1.27

# SARIF, for GitHub Code Scanning
trivy image --format sarif --output trivy.sarif nginx:1.27

# Table output filtered by severity
trivy image --format table --severity CRITICAL nginx:1.27

4. Ignore false positives and baseline exemptions

# Create .trivyignore in project root
# One CVE ID per line, with comments
# CVE-2026-0000
# Affects non-default config only; defer fix

# Scan reads .trivyignore automatically
trivy image --ignorefile .trivyignore nginx:1.27

5. CI/CD pipeline integration (GitHub Actions)

name: image-scan
on:
  push:
    branches: [ main ]
jobs:
  trivy-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build image
        run: docker build -t myapp:latest .
      - name: Run Trivy scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'myapp:latest'
          format: 'table'
          exit-code: '1'
          severity: 'CRITICAL,HIGH'
          ignore-unfixed: true

Key: `exit-code: 1` fails the pipeline on HIGH/CRITICAL findings (release gate). `ignore-unfixed: true` avoids blocking on vulns with no fix.

6. Filesystem and Git repo scanning

# Scan local directory dependencies (no image needed)
trivy fs ./myapp

# Scan remote repo
trivy repo https://github.com/aquasecurity/trivy

# Scan IaC misconfigs (Dockerfile/K8s yaml)
trivy config ./deploy

Verification

# Verify 1: confirm scan output is parseable
trivy image --format json --severity CRITICAL nginx:1.27 | python3 -m json.tool | head -50

# Verify 2: confirm gate works (non-zero on high severity)
trivy image --exit-code 1 --severity CRITICAL nginx:1.27; echo "exit=$?"

If it returns `exit=1`, the image has CRITICAL vulns and the gate blocked it. After fix, scan should return `exit=0`.

FAQ

FAQ 1: Trivy results differ from Docker Hub official scans

Different tools use different vulnerability sources and matching algorithms; divergence is expected. Prefer Trivy and pin the database version: `trivy image --download-db-only --db-repository ghcr.io/aquasecurity/trivy-db` for offline sync so CI data stays consistent.

FAQ 2: Vulnerability has no fix version

Exempt it in `.trivyignore` with reason and review date. Reduce exploitability with mitigations (restrict egress, harden runtime flags) and recheck upstream patches regularly. Do not ignore CRITICAL vulns in production without assessment.

FAQ 3: Can Trivy scan private registry images?

Yes. `docker login` to the private registry, or set `TRIVY_USERNAME` / `TRIVY_PASSWORD`. Offline environments need a pre-exported vuln DB and `--offline-scan`.

Summary

Trivy is a de facto standard for container image scanning: zero config, multiple data sources, CI gates. Wire it into the build pipeline: scan immediately after image build, block HIGH/CRITICAL from release, manage exceptions with `.trivyignore`, and run a monthly full scan of existing images—scan at build, keep vulns out of production.