During container validation for AI-SGAP, we encountered a result that deserves more attention than a green dashboard usually receives.
One recorded runtime-image checkpoint showed:
| Scanner | Reported result |
|---|---|
| Trivy | 0 vulnerabilities |
| Grype | 9 Medium findings and 1 Negligible finding |
That was our October 28 development snapshot, not a statement about the current image.
The discrepancy did not establish that one scanner was correct and the other was wrong. It established that we needed to investigate what each result represented.
Here is what we learned.
A scanner count needs context
It is tempting to read “zero vulnerabilities” as a property of an image.
A more accurate interpretation is:
This scanner reported no matching vulnerabilities within its detection scope, using this configuration and vulnerability database at this point in time.
That distinction matters because several inputs influence the result:
- Which packages the scanner discovers.
- How it identifies their names, versions, and ecosystems.
- Which advisory sources it consults.
- How it matches packages to affected-version ranges.
- Which severity ratings it selects.
- Which findings are filtered or suppressed.
- Whether the scan completed successfully.
Our recorded totals alone do not identify which of those factors caused each difference. That requires examining the individual findings and scan metadata.
How Trivy approaches the problem
Trivy documents a distribution-aware approach to operating-system packages.
- For packages installed through an OS package manager, it uses the relevant distribution’s security advisories.
- This helps account for backported fixes: a distribution may patch a vulnerability without adopting the upstream project’s newer version number.
- Trivy generally prefers severity information from its selected advisory source.
- Its documented detection modes make a deliberate tradeoff between reducing false positives and finding more potential matches.
The practical lesson is that an apparently old version number does not, by itself, prove a distribution package remains vulnerable.
Package provenance matters.
How Grype helps explain its findings
Grype’s structured output provides information about how a vulnerability was matched.
Anchore distinguishes direct and indirect exact matches from CPE-based matches, which require additional verification. CPE is a standardized way of identifying software products; a product-name match still needs careful interpretation in the context of the actual package.
Grype also exposes advisory identifiers, package versions, severity, and fix information. These details make the JSON report valuable when investigating a discrepancy.
This does not mean Grype always produces more findings, or that additional findings are automatically false positives.
It means the matching explanation deserves attention alongside the count.
Filters can change the story
Before comparing two totals, check what each report includes.
For example:
- Trivy offers an option to hide unfixed vulnerabilities.
- Grype supports filtering by fix availability, ignore rules, and VEX documents that communicate vulnerability applicability.
- Grype’s failure threshold controls its exit behavior; a successful process exit should be interpreted alongside the configured policy and report.
A report containing only findings with available fixes answers a different question from a report containing all detected findings.
Filtering a finding does not remediate it. Any exclusion needs an explanation that survives beyond the terminal session.
What changed in our engineering approach
The most useful outcome was a stronger review process.
1. Establish exactly what was scanned
Before comparing results, record:
- Image digest and target platform.
- Scanner version.
- Scan command and configuration.
- Database identity and timestamp.
- Scan completion status and errors.
A shared image tag is insufficient evidence of an identical target. Tags can move, and multi-platform images require attention to the selected platform.
2. Compare findings individually
For every discrepancy, ask:
- Did both scanners discover the package?
- Did they identify the same installed version?
- Is it an OS package, application dependency, or separately installed component?
- Which advisory and affected-version range produced the match?
- Is a distribution-specific fix relevant?
- Are severity, fix status, or filtering responsible for the visible difference?
A useful comparison starts with package, version, ecosystem, and advisory identity. Comparing headline totals skips the information needed to make a decision.
3. Separate detection from applicability
A reported package vulnerability needs investigation in the application’s context:
- Is the affected component actually present?
- Is the vulnerable functionality included?
- Can the application or a dependency invoke it?
- Could untrusted input reach it?
- What mitigations apply?
“We do not intentionally use that library” is a starting hypothesis. It needs supporting evidence, particularly when dependencies may invoke it indirectly.
4. Make residual-risk decisions explicit
When immediate remediation is unavailable, document:
- The affected finding and image.
- The supporting applicability analysis.
- Mitigations and remaining uncertainty.
- The person accepting the residual risk.
- An expiry date or reassessment trigger.
Acceptance records a decision. It does not remove the vulnerability.
Freshness and reproducibility serve different purposes
Grype maintains a local vulnerability database and ordinarily checks for updates when launched. Trivy likewise maintains databases used during scanning. Changing advisory data can change results even when image bytes remain unchanged.
Our lesson is to preserve both:
- Historical evidence: enough information to explain the decision made then.
- Fresh evidence: a new scan to assess what is known now.
A current scan cannot reconstruct a missing historical database snapshot. Equally, a preserved historical report cannot establish today’s vulnerability status.
That has implications for evidence retention, build records, and repeatable release reviews.
Why we continue using both
For our workflow, the value of using Trivy and Grype is the additional opportunity to question assumptions.
Two tools can expose differences worth investigating. They can also share blind spots. Agreement between them does not establish that an image is secure.
The question we now ask is:
Can we explain the findings, the differences, and the decision we made?
That is the engineering habit this work reinforced and the habit we are carrying forward as we build AI-SGAP.
This post describes selected development observations, not a controlled benchmark or a universal ranking of either scanner. Tool behavior depends on version, configuration, database, and scan target. No proprietary AI-SGAP assessment logic is disclosed.