False-positive CVE: allowlist with justification and expiry in CI
When a container scanner flags a CVE that does not apply (a package present but not used, or a vendor backport the scanner misreads), suppress that one ID with a written reason and an expiry date. Do not lower the severity or disable the scanner, which hides real CVEs too.
What this error means
A scan blocks on a CVE that engineering has confirmed does not apply, and the tempting shortcut is to disable the gate or drop the severity, which suppresses every finding.
Total: 1 (HIGH: 1, CRITICAL: 0)
| libfoo | CVE-2024-ZZZZ | HIGH | 1.2.3 | 1.2.4 |
# team confirms not exploitable in this image, but blanket-ignoring hides real CVEsCommon causes
A genuine false positive or non-applicable CVE
The scanner matches a package version to a CVE that a distro backport already fixed, or the vulnerable code path is not present, so the finding is not actionable here.
Pressure to suppress broadly instead of precisely
Disabling the gate or dropping to CRITICAL-only removes the one false positive but also hides every other HIGH CVE.
How to fix it
Allowlist the single ID with reason and expiry
- Add only the specific vulnerability ID to the scanner allowlist.
- Record why it is accepted and a review/expiry date.
- Keep the gate at its normal severity so other CVEs still fail.
# .grype.yaml
ignore:
- vulnerability: CVE-2024-ZZZZ
reason: "backport-fixed in distro; not exploitable, review 2026-09-01"Re-verify at expiry rather than forever
An expiring entry forces a periodic recheck, so a suppression does not silently outlive its justification.
# trivy equivalent, with expiry
# .trivyignore.yaml
vulnerabilities:
- id: CVE-2024-ZZZZ
expired_at: 2026-09-01How to prevent it
- Suppress specific IDs, never whole severities or the gate.
- Require a justification and expiry on every allowlist entry.
- Review the allowlist so stale suppressions are removed.