Quickstart: answer a vulnerability inquiry

A customer or user reports that their scanner flags a vulnerability in your product. In about five minutes you find your project’s recorded decision and turn it into an answer, without redoing the triage.

Prerequisites

  • Read access to the project’s Vulnlog file, in the repository or on GitHub. To follow along, save the example file below as acme-web-app.vl.yaml.

acme-web-app.vl.yaml
# $schema: https://vulnlog.dev/schema/vulnlog-v1.json
---
schemaVersion: "1"

project:
  organization: Acme Corp
  name: Acme Web App
  author: Acme Corp Security Team

releases:
  - id: 1.0.0
    published_at: 2026-01-15
  - id: 1.1.0
    published_at: 2026-03-20
  - id: 1.2.0

vulnerabilities:

  - id: CVE-2026-8802
    releases: [1.1.0]
    packages: ["pkg:npm/session-store@1.4.0"]
    reports:
      - reporter: trivy
        at: 2026-07-01

  - id: CVE-2026-7791
    description: SQL injection in query-parser
    releases: [1.1.0]
    packages: ["pkg:npm/query-parser@5.2.1"]
    reports:
      - reporter: trivy
        at: 2026-05-15
    analysis: >-
      Confirmed exploitable through the search endpoint. Crafted filter expressions reach the vulnerable parser.
    analyzed_at: 2026-05-16
    verdict: affected
    severity: high
    resolution:
      in: 1.2.0
      at: 2026-06-20
      ref: "https://jira.example.com/browse/SEC-201"
      note: Updated query-parser from 5.2.1 to 5.3.0

  - id: CVE-2026-6685
    description: Denial of service in thumbnail-gen
    aliases: [SNYK-JS-THUMBNAILGEN-2984765]
    releases: [1.0.0]
    packages: ["pkg:npm/thumbnail-gen@2.0.0"]
    reports:
      - reporter: trivy
        at: 2026-04-02
        suppress: {}
    analysis: >-
      Confirmed but only exploitable with specially crafted image dimensions that the upload validation layer rejects.
    analyzed_at: 2026-04-03
    verdict: risk acceptable
    severity: low
    comment: Risk accepted by project lead. Revisit when thumbnail-gen 3.0 is released.

  - id: CVE-2026-1234
    description: Remote code execution in example-lib
    releases: [1.0.0]
    packages: ["pkg:npm/example-lib@2.3.0"]
    reports:
      - reporter: trivy
        at: 2026-02-01
    analysis: >-
      The vulnerable code path is not reachable in our application because we only use the safe subset of the API.
    analyzed_at: 2026-02-02
    verdict: not affected
    justification: vulnerable code not in execute path

  - id: CVE-2025-9876
    description: Authentication bypass in auth-middleware
    releases: [1.0.0]
    packages: ["pkg:npm/auth-middleware@3.0.2"]
    reports:
      - reporter: trivy
        at: 2026-01-20
    analysis: Confirmed. The bypass affects every session-authenticated route.
    analyzed_at: 2026-01-21
    verdict: affected
    severity: critical
    resolution:
      in: 1.1.0
      at: 2026-03-18
      ref: "https://jira.example.com/browse/SEC-158"
      note: Updated auth-middleware from 3.0.2 to 3.1.0

The inquiry for this example: "Our Trivy scan flags CVE-2026-1234 in example-lib 2.3.0, which ships with Acme Web App 1.0.0. Are we exposed?"

Step 1: Find the entry

Search the Vulnlog file for the reported identifier, with your editor, GitHub search, or grep:

grep -n "CVE-2026-1234" acme-web-app.vl.yaml
60:  - id: CVE-2026-1234

If the identifier does not match any id, search again before concluding it is untracked: the customer’s scanner may use a different identifier for the same vulnerability, and known ones are listed in the entry’s aliases field. In the example file, a search for SNYK-JS-THUMBNAILGEN-2984765 finds it as an alias of CVE-2026-6685.

Step 2: Read the recorded decision

The entry holds everything the triage produced:

  - id: CVE-2026-1234
    description: Remote code execution in example-lib
    releases: [1.0.0]
    packages: ["pkg:npm/example-lib@2.3.0"]
    reports:
      - reporter: trivy
        at: 2026-02-01
    analysis: >-
      The vulnerable code path is not reachable in our application because we only use the safe subset of the API.
    analyzed_at: 2026-02-02
    verdict: not affected
    justification: vulnerable code not in execute path

Three fields make the answer:

  • verdict is the position: not affected.

  • justification is the machine-readable reason, from the VEX vocabulary: vulnerable code not in execute path.

  • analysis is the human explanation you can quote.

Check that the customer’s release appears in releases; a verdict is recorded per release line.

Step 3: Answer the inquiry

An answer built only from the entry:

CVE-2026-1234 was reported for Acme Web App 1.0.0 by our own scans on 2026-02-01 and analysed on 2026-02-02. The verdict is "not affected": the vulnerable code path is not reachable in our application because we only use the safe subset of the API. No action is required on your side; you can suppress the finding in your scanner.

Every claim in the answer traces back to a field in the version-controlled file, and git log shows when the decision was made and by whom.

If the entry does not exist

Then the finding is untriaged, and the honest answer is "under investigation". Record the finding so the triage starts (see Triage a new scanner finding) and tell the customer when to expect the verdict.

What you did

You resolved an external vulnerability question by lookup instead of re-analysis: search by identifier or alias, read the verdict and justification, and quote the analysis.

Next steps

  • Generate reports produces a shareable HTML report when the inquiry warrants a full overview instead of a single answer.

  • Vulnerability states explains how entries progress from under investigation to a final state.