Container Security Scanning: Trivy, Grype, Snyk, and Docker Scout
Container Security Scanning: Trivy, Grype, Snyk, and Docker Scout
Shipping containers without scanning them is like deploying code without tests -- you might get away with it for a while, but eventually a known vulnerability will bite you. Container images inherit vulnerabilities from base images, OS packages, and application dependencies. A single node:18 base image can carry dozens of known CVEs at any given time.
The good news is that container scanning tools have matured significantly. The bad news is that choosing between them requires understanding real differences in vulnerability databases, scanning speed, false positive rates, and CI integration quality. This guide covers the four tools worth considering and helps you pick the right one.
What Container Scanners Actually Do
Container scanners analyze image layers to build a software bill of materials (SBOM), then cross-reference that inventory against vulnerability databases (NVD, GitHub Advisory Database, vendor-specific feeds). The scanner reports which packages have known CVEs, their severity, and whether a fix is available.
The differences between scanners come down to:
- Database coverage: Which vulnerability feeds they pull from, and how quickly new CVEs appear
- Language support: OS packages are universally covered, but application dependencies (npm, pip, Go modules, Ruby gems) vary
- Speed: Full image scans range from 5 seconds to several minutes
- False positives: Some scanners flag vulnerabilities in packages that are installed but not actually reachable in your application
- Integration: How well they fit into CI pipelines, registries, and developer workflows
Trivy: The Open Source Default
Trivy (from Aqua Security) has become the most popular open source container scanner. It scans container images, filesystems, Git repositories, and Kubernetes clusters. It is fast, covers both OS and language packages, and requires zero configuration.
Basic Usage
# Install
brew install trivy # macOS
sudo apt install trivy # Debian/Ubuntu
# Scan a local image
trivy image myapp:latest
# Scan a remote image (no docker pull needed)
trivy image ghcr.io/myorg/myapp:v1.2.0
# Scan and fail on critical/high severity
trivy image --severity CRITICAL,HIGH --exit-code 1 myapp:latest
# Output as JSON for programmatic consumption
trivy image --format json --output results.json myapp:latest
# Scan a Dockerfile (filesystem mode)
trivy fs --scanners vuln,secret,misconfig .
# Generate an SBOM
trivy image --format spdx-json --output sbom.json myapp:latest
CI Integration (GitHub Actions)
name: Container Security Scan
on:
push:
branches: [main]
pull_request:
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: table
exit-code: 1
severity: CRITICAL,HIGH
ignore-unfixed: true
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: trivy-results.sarif
Ignoring False Positives
Create a .trivyignore file in your repository to suppress known false positives:
# .trivyignore
# CVE-2023-XXXXX - not exploitable in our context (no network exposure)
CVE-2023-12345
# Disputed vulnerability, vendor says not affected
CVE-2024-67890
Strengths: Fast (typically under 15 seconds), comprehensive language support (Node.js, Python, Go, Java, Ruby, Rust, PHP, .NET), scans beyond just images (IaC misconfigurations, secrets, licenses), SBOM generation, actively maintained, free and open source.
Weaknesses: Vulnerability database can lag a few hours behind commercial feeds on newly disclosed CVEs. No built-in UI for tracking trends over time (you need to pipe results to something like DefectDojo or Trivy's own server mode).
Grype: The Anchore Alternative
Grype is an open source vulnerability scanner from Anchore. It pairs with Syft (Anchore's SBOM generator) and focuses purely on vulnerability detection -- no IaC scanning or secret detection.
Basic Usage
# Install
brew install grype # macOS
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
# Scan an image
grype myapp:latest
# Scan with severity threshold
grype myapp:latest --fail-on critical
# Scan from an SBOM (generated by Syft)
syft myapp:latest -o spdx-json > sbom.json
grype sbom:sbom.json
# Output formats
grype myapp:latest -o json
grype myapp:latest -o table
grype myapp:latest -o sarif
CI Integration (GitHub Actions)
- name: Scan image with Grype
uses: anchore/scan-action@v4
with:
image: myapp:${{ github.sha }}
fail-build: true
severity-cutoff: high
output-format: sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: results.sarif
Strengths: Clean separation of SBOM generation (Syft) and vulnerability scanning (Grype), excellent SBOM ecosystem integration, fast scans, good for environments that already use Anchore Enterprise.
Weaknesses: Slightly less language coverage than Trivy for newer ecosystems. No IaC or secret scanning -- it only does vulnerability matching. Community is smaller than Trivy's.
Snyk Container: The Commercial Option
Snyk Container is part of the Snyk platform and brings developer-friendly vulnerability scanning with a focus on actionable remediation advice. Where open source scanners tell you "this package has a CVE," Snyk tells you "upgrade to this version" and can auto-create pull requests with the fix.
Basic Usage
# Install Snyk CLI
npm install -g snyk
# Authenticate
snyk auth
# Scan an image
snyk container test myapp:latest
# Scan with specific severity threshold
snyk container test myapp:latest --severity-threshold=high
# Monitor (track continuously on Snyk dashboard)
snyk container monitor myapp:latest --org=my-org
# Suggest base image upgrades
snyk container test myapp:latest --file=Dockerfile
The --file=Dockerfile flag is particularly useful. Snyk analyzes your Dockerfile and suggests alternative base images with fewer vulnerabilities. For example, it might recommend switching from node:18 to node:18-slim or node:18-alpine, showing the CVE count reduction for each option.
CI Integration (GitHub Actions)
- name: Snyk Container Scan
uses: snyk/actions/docker@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
image: myapp:${{ github.sha }}
args: --severity-threshold=high --file=Dockerfile
Strengths: Best remediation advice (specific version recommendations, base image suggestions), auto-fix PRs, a polished web dashboard for tracking vulnerability trends, license compliance scanning, excellent developer experience.
Weaknesses: Free tier is limited (100 container tests per month). Full features require a paid plan ($25+/user/month for Teams). Vulnerability database is proprietary -- you are trusting Snyk's curation.
Docker Scout: Built Into Docker Desktop
Docker Scout is Docker's own scanning solution, built into Docker Desktop and the Docker CLI since Docker Desktop 4.17. If your team already uses Docker Desktop, Scout is the zero-friction option.
Basic Usage
# Scan a local image (Docker Desktop must be running)
docker scout cves myapp:latest
# Quick overview with vulnerability counts
docker scout quickview myapp:latest
# Compare two images (useful for checking if a rebuild fixed vulns)
docker scout compare myapp:v2.0 --to myapp:v1.9
# Recommendations for base image updates
docker scout recommendations myapp:latest
# Filter by severity
docker scout cves myapp:latest --only-severity critical,high
The docker scout compare command is uniquely useful. When you rebuild an image to address vulnerabilities, you can immediately verify what changed:
docker scout compare myapp:latest --to myapp:previous
# Shows: +3 fixed, -1 new, 12 unchanged
CI Integration (GitHub Actions)
- name: Docker Scout Scan
uses: docker/scout-action@v1
with:
command: cves
image: myapp:${{ github.sha }}
sarif-file: scout-results.sarif
only-severities: critical,high
Strengths: Zero setup for Docker Desktop users, excellent compare feature for tracking remediation progress, base image recommendations, integrated into docker build workflow.
Weaknesses: Requires Docker Desktop (or Docker Hub account for CI), free tier limited to 3 repositories, commercial pricing for larger usage, younger product with a smaller vulnerability database than Trivy or Snyk.
Comparison
| Feature | Trivy | Grype | Snyk Container | Docker Scout |
|---|---|---|---|---|
| Price | Free/OSS | Free/OSS | Freemium | Freemium |
| Scan speed (typical) | 10-20s | 10-15s | 20-40s | 15-30s |
| OS package scanning | Excellent | Excellent | Excellent | Good |
| Language dep scanning | Excellent | Good | Excellent | Good |
| IaC/misconfig scanning | Yes | No | Separate product | No |
| Secret detection | Yes | No | Separate product | No |
| SBOM generation | Yes | Via Syft | Yes | Yes |
| Remediation advice | Basic | Basic | Excellent | Good |
| Auto-fix PRs | No | No | Yes | No |
| Base image suggestions | No | No | Yes | Yes |
| CI/CD integration | Excellent | Good | Excellent | Good |
| Image comparison | No | No | Limited | Excellent |
| Self-hosted/air-gapped | Yes | Yes | Enterprise only | No |
Practical Scanning Workflow
Here is a workflow that covers the full development lifecycle:
During Development
Scan your Dockerfile and local images before pushing:
# Quick local scan during development
trivy image --severity HIGH,CRITICAL myapp:dev
In CI/CD
Gate your pipeline on scan results. Use --ignore-unfixed to avoid blocking on vulnerabilities that have no available patch:
trivy image \
--exit-code 1 \
--severity CRITICAL \
--ignore-unfixed \
myapp:${{ github.sha }}
In Your Registry
Enable scan-on-push in your container registry (Harbor, ECR, and GHCR all support this). This catches vulnerabilities in images that were built outside your CI pipeline.
Continuous Monitoring
Vulnerabilities are discovered after images are built. Rescan your deployed images on a schedule:
# Cron job or scheduled CI pipeline
trivy image --format json --output daily-scan.json ghcr.io/myorg/myapp:production
Recommendations
For most teams, the decision is straightforward:
Default choice: Use Trivy. It is free, fast, comprehensive, and has the largest community. It covers vulnerabilities, IaC misconfigurations, and secrets in a single tool.
Need remediation guidance: Add Snyk Container. Its base image recommendations and auto-fix PRs save real time, especially if you maintain many services. Use the free tier alongside Trivy to get the best of both worlds.
Already using Docker Desktop: Enable Docker Scout for local development scans. Its compare feature is genuinely useful for validating that image rebuilds reduced your vulnerability count.
SBOM-first approach: Use Grype + Syft. Generate SBOMs with Syft, scan with Grype, and feed the SBOMs into your compliance tooling.
Multiple scanners: Running two scanners catches more. Trivy + Grype is a solid combination -- both are free, fast, and use different vulnerability databases. Differences in their results highlight areas where database coverage varies.
Whatever scanner you pick, the critical step is gating your CI pipeline. A scanner that runs but does not block deployments is just generating noise. Set a severity threshold (CRITICAL at minimum, HIGH if your team can handle the volume), use --ignore-unfixed to stay practical, and treat scan failures like test failures.