Triage a new scanner finding
Your SCA scanner reported a new finding. This guide shows how to record it in the Vulnlog file, which verdict fits which situation, and what each verdict means for the generated suppression files. At the end, the finding is triaged and your build reflects the decision.
Prerequisites
-
A Vulnlog file with at least one release (see the triage quickstart).
-
The scanner finding: its identifier, the affected package, and the scanner that reported it.
Record the finding first, decide later
Analysis takes time; recording the finding does not.
Add a stub entry the moment the scanner reports, either with vulnlog modify add or by hand:
- id: CVE-2026-5678
releases: [2.0.0]
packages: ["pkg:npm/image-lib@3.1.0"]
reports:
- reporter: trivy
tags: [webapp]
Without a verdict, Vulnlog tracks the entry as under investigation.
Nothing is suppressed, so the scanner keeps flagging the finding until you decide.
Record the verdict
Analyse the finding and pick the verdict that matches your conclusion. Each verdict has different required fields and different suppression behavior; the verdict reference defines all values.
The finding does not affect you
Record not affected with a justification and put your reasoning in analysis:
- id: CVE-2026-5678
releases: [2.0.0]
description: Memory corruption in image-lib
packages: ["pkg:npm/image-lib@3.1.0"]
reports:
- reporter: trivy
at: 2026-03-01
tags: [webapp]
analysis: >
The vulnerable code path requires SVG input processing.
Our application only accepts PNG and JPEG formats.
analyzed_at: 2026-03-02
verdict: not affected
justification: vulnerable code not in execute path
not affected entries are included in generated suppression files automatically; the finding is noise and needs no further decision.
The finding affects you and you fix it
Record affected with a severity.
Once the fix ships, add a resolution:
- id: CVE-2026-5678
releases: [2.0.0]
description: Memory corruption in image-lib
packages: ["pkg:npm/image-lib@3.1.0"]
reports:
- reporter: trivy
at: 2026-03-01
tags: [webapp]
analysis: >
Confirmed exploitable via crafted PNG uploads.
analyzed_at: 2026-03-02
severity: high
verdict: affected
resolution:
in: 2.0.1
at: 2026-03-03
ref: "https://jira.example.com/browse/SEC-99"
note: "Updated image-lib from 3.1.0 to 3.2.0"
An affected entry without a resolution stays visible in the scanner output; that is intentional, it is a live risk.
See Record a resolution for the fix workflow.
You accept the risk
Record risk acceptable with a severity.
Suppressing a live risk is a second, deliberate decision, so it needs an explicit suppress block on the report:
- id: CVE-2026-5678
releases: [2.0.0]
description: Memory corruption in image-lib
packages: ["pkg:npm/image-lib@3.1.0"]
reports:
- reporter: trivy
suppress: {}
tags: [webapp]
analysis: >
Vulnerability confirmed but only exploitable with
specially crafted input that our validation layer rejects.
severity: medium
verdict: risk acceptable
comment: >
Risk accepted by project lead. Revisit when upstream
releases a stable fix.
To make the suppression temporary, give the suppress block an expires_at date; the suppression reference defines the rules.
The finding is a false positive
A false positive is a not affected verdict whose analysis records why the scanner is wrong:
- id: CVE-2026-4321
releases: [2.0.0]
description: Remote code execution in logging-framework
packages: ["pkg:npm/logging-framework@2.0.0"]
reports:
- reporter: trivy
at: 2026-03-15
analysis: >
False positive. The scanner flagged logging-framework as a
runtime dependency, but it is only present in the test scope
and not included in the deliverable.
analyzed_at: 2026-03-16
verdict: not affected
justification: component not present
The finding only touches your build environment
A vulnerability in a build-time dependency that never reaches the deliverable is also not affected.
A tag such as build-dep keeps these entries filterable:
- id: CVE-2026-9999
releases: [2.0.0]
description: Command injection in build-tool
packages: ["pkg:npm/build-tool@5.0.0"]
reports:
- reporter: trivy
at: 2026-03-01
tags: [build-dep]
analysis: >
Affects the build pipeline only. The vulnerable command
injection requires untrusted input which the CI environment
does not expose.
verdict: not affected
justification: vulnerable code cannot be controlled by adversary
How an entry evolves
The same entry, refined as triage progresses.
Stage 1, the stub recorded on the day the scanner reports:
- id: CVE-2026-5678
releases: [2.0.0]
packages: ["pkg:npm/image-lib@3.1.0"]
reports:
- reporter: trivy
at: 2026-03-01
Stage 2, analysis complete and verdict recorded:
- id: CVE-2026-5678
releases: [2.0.0]
description: Memory corruption in image-lib
packages: ["pkg:npm/image-lib@3.1.0"]
reports:
- reporter: trivy
at: 2026-03-01
analysis: >
Confirmed exploitable via crafted PNG uploads.
analyzed_at: 2026-03-02
severity: high
verdict: affected
Stage 3, resolution recorded after the fix shipped:
- id: CVE-2026-5678
releases: [2.0.0]
description: Memory corruption in image-lib
packages: ["pkg:npm/image-lib@3.1.0"]
reports:
- reporter: trivy
at: 2026-03-01
analysis: >
Confirmed exploitable via crafted PNG uploads.
analyzed_at: 2026-03-02
severity: high
verdict: affected
resolution:
in: 2.0.1
at: 2026-03-03
note: "Updated image-lib from 3.1.0 to 3.2.0"
Once the resolution is recorded, the entry is excluded from generated suppression files; the scanner is expected to stop reporting the finding after the dependency update.
Verify
Validate the file after every triage session:
vulnlog validate vulnlog.yaml
Validated: vulnlog.yaml
Validation catches missing conditional fields, for example a not affected verdict without a justification.
Related
-
Verdicts and justifications defines every verdict, severity, and justification value.
-
Suppression defines which entries end up in suppression files.
-
Vulnerability states explains how verdict and resolution derive the entry state shown in reports.