Trivy vs Grype: A Practical Guide to Choosing a Container Vulnerability Scanner
Let's start with the conclusion. Choose Trivy if you want one tool that also covers IaC, secrets, and Kubernetes. Choose Grype if your pipeline is SBOM-centric, you already use syft, or you need fine-grained ignore rules. Both are free and open source with similar GitHub stars, which is why picking one feels so hard—but the real differentiators aren't stars. They're DB source, false-positive handling, and CI fail policy. Use this post to decide in five minutes and ship it the same day with copy-paste CI snippets.
Why you should put a vulnerability scanner in CI now
SBOM submission is becoming de facto mandatory under U.S. Executive Order 14028 and the EU Cyber Resilience Act (CRA). The core of DevSecOps is "shift-left"—moving security checks from runtime into the build. Blocking CRITICAL vulnerabilities before an image hits the registry and before a PR is merged is now the standard. Trivy and Grype are the two leading open-source scanners competing for that slot.
5-minute hands-on: install and first scan
Run both against the same image (python:3.12-slim) and you'll feel the differences immediately.
# Trivy (Aqua Security)
brew install trivy
trivy image python:3.12-slim
# Grype (Anchore)
brew install grype
# 또는: curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
grype python:3.12-slimThe first run takes tens of seconds for both because they download the vulnerability DB; after that, cache makes subsequent scans finish in a few seconds. The output columns are similar too.
- Trivy:
Library(package) /Vulnerability(CVE-ID) /Severity/Installed Version/Fixed Version/Title - Grype:
NAME(package) /INSTALLED(installed version) /FIXED-IN(fixed version) /TYPE/VULNERABILITY(CVE-ID) /SEVERITY
The point is that both tell you which package, which version, which CVE, and which version to upgrade to. Getting different result counts on the same image is normal—that's because of the DB source differences in the table below.
Head-to-head comparison
| Item | Trivy | Grype |
|---|---|---|
| Vendor / org | Aqua Security | Anchore |
| Vulnerability DB | Trivy DB (Aqua-curated, distributed as OCI artifacts on GitHub) | grype-db (NVD, GitHub Security Advisory, and distro security feeds combined) |
| First-run speed | Seconds after DB download | Seconds after DB download (similar) |
| Speed after cache | Fast | Fast (Grype is usually a bit faster) |
| Scan targets | Images, filesystems, Git repos, IaC (Terraform, etc.), secrets, k8s | Images, filesystems, SBOM-centric |
| SBOM generation | Built-in (--format cyclonedx/spdx) | Via companion tool syft |
| Ignore false positives | .trivyignore | ignore: block in .grype.yaml |
| License | Apache 2.0 / free | Apache 2.0 / free |
Why the result counts differ: Trivy uses Aqua's processed and aggregated DB; Grype uses Anchore's DB that merges NVD with each distro's security feeds. Even for the same CVE, package matching rules and severity classification can differ, so counts diverge. Neither is "wrong"—they just have different data-source policies.
Wiring it into CI: fail the build + ignore false positives
GitHub Actions (Trivy)
- name: Trivy scan
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myorg/myapp:${{ github.sha }}'
severity: 'CRITICAL,HIGH'
exit-code: '1' # CRITICAL/HIGH 발견 시 1 → 잡 실패 → PR 머지 차단GitLab CI (Trivy)
scan:
script:
- trivy image --exit-code 1 --severity CRITICAL,HIGH $IMAGEGrype
grype myorg/myapp:latest --fail-on high
# high 이상(= high, critical) 발견 시 exit-code 1exit-code 1 is the key. When the CI job fails, branch protection blocks the PR merge, so developers upgrade the vulnerable package before merge. That's shift-left in practice.
Conditional suppression of false positives
Instead of blanket suppression, conditional suppression plus an expiry date is the operational best practice. The most dangerous thing is turning something off and forgetting about it.
# .trivyignore — CVE 한 줄씩, 만료일 지정 가능
CVE-2023-12345 exp:2026-12-31# .grype.yaml — vulnerability/package/fix-state 조건으로 정밀 무시
ignore:
- vulnerability: CVE-2023-12345
- package:
name: openssl
fix-state: not-fixed # 아직 패치 안 나온 건 한시적으로 무시Practical tip: I exclude "not-fixed" CVEs (no patched version yet) from build-breaking and track them in a separate backlog. If you break the build on things the team can't fix, they'll just turn the scanner off. That's where Grype's
fix-statecondition shines.
SBOM workflow differences
Grype pairs naturally with syft, which is also from Anchore.
syft myorg/myapp:latest -o syft-json | grype
# 또는 미리 만들어둔 SBOM 재스캔
grype sbom:./sbom.jsonTrivy can generate an SBOM on its own, without an extra tool, and rescan that SBOM.
trivy image --format cyclonedx -o sbom.json python:3.12-slim
trivy sbom sbom.jsonBoth cover SPDX and CycloneDX. The difference is whether you generate the SBOM with one tool (Trivy) or pipe a syft-generated SBOM straight through (Grype + syft). If you already have a syft pipeline, Grype feels natural. If you don't want another SBOM tool, Trivy alone is enough.
Choose by situation
| Your situation | Recommendation |
|---|---|
| All-in-one for images plus IaC, secrets, and k8s manifests | Trivy |
| Minimize learning curve, get started fast | Trivy (friendly defaults) |
| SBOM-centric pipeline, already using syft | Grype |
| Need fine-grained conditional ignore (fix-state, etc.) | Grype |
| Start light with a single binary | Either works |
FAQ
Q. Why do Trivy and Grype report different result counts? A. Because their vulnerability DB sources differ. Trivy uses Aqua's own aggregated DB; Grype uses grype-db, which combines NVD, GitHub Advisory, and distro feeds. Package matching rules and severity classification also differ, so counts diverge. Neither is wrong.
Q. Are both free? Are there commercial versions? A. Both are free under Apache 2.0. Aqua and Anchore also sell commercial platforms with policy management, reporting, and SLAs. For CI scanning, the free versions are enough.
Q. Which severity should we start failing CI on?
A. Start by failing the build on CRITICAL only, then expand to HIGH once things stabilize. If you block on MEDIUM and below from day one, false positives and unfixed CVEs will break builds so often that the team will disable the scanner.
Q. Can we scan images without an SBOM?
A. Yes. trivy image or grype <image> is enough to catch vulnerabilities. Add SBOM when you need supply-chain tracking, regulatory compliance, or automated rescan.
Q. We have too many false positives. How do we cut them down?
A. Use conditional suppression, not blanket ignore. In Trivy, add an expiry (exp:) in .trivyignore. In Grype, temporarily exclude only items with fix-state: not-fixed in .grype.yaml. Always track ignored items in a backlog.
Nodelog는 모든 콘텐츠의 내용과 출처를 공개 전에 검토합니다. 환경(OS·버전)에 따라 결과가 달라질 수 있는 기술 정보는 공식 문서와 함께 확인하며, 검토 기준과 정정 원칙은 편집 정책에서 안내합니다. 오류를 발견하시면 이메일로 제보해 주세요 — 확인 후 신속히 정정합니다.
Comments
Be the first to comment.