VEX Feed
July 3, 2026 · View on GitHub
This document describes Questarr's Vulnerability Exploitability eXchange (VEX) feed: how known vulnerabilities in third-party components are tracked, assessed for exploitability in the context of this project, and published. It satisfies OpenSSF Baseline OSPS-VM-04.02: any vulnerability reported against a component Questarr ships that does not actually affect the project must be recorded here with a justification, rather than silently ignored.
This is distinct from two adjacent documents:
docs/SBOM.md— the inventory of components (what's shipped). The VEX feed makes exploitability statements about entries in that inventory.docs/SECURITY_ASSESSMENT.md— a risk register of Questarr's own architectural/design risks (e.g. session handling, SSRF surface). VEX only covers vulnerabilities in third-party dependencies (npm packages and thenode:22-alpinebase image), identified by CVE/GHSA ID, not first-party design tradeoffs.
Format
The feed is a single OpenVEX v0.2.0 JSON document:
security/vex/questarr.openvex.json
Each entry is a statement scoped to a vulnerability (CVE/GHSA ID) and a
product (a package URL identifying the affected component and version, or
the published container image), with a status of one of:
not_affected— the vulnerable code path is present but not reachable or not exploitable in how Questarr uses the component. Requires ajustification(OpenVEX's fixed enum, e.g.vulnerable_code_not_in_execute_path,vulnerable_code_not_present,component_not_present) plus a free-textimpact_statementexplaining the specific reasoning.affected— exploitable; tracked until a fix is available. Should includeaction_statementdescribing the mitigation or remediation plan.fixed— resolved in the version currently shipped.under_investigation— triage in progress; a temporary state, not a resting one.
Why the feed is currently empty
As of the last update to this document, npm audit --omit=dev and
npm audit both report zero known vulnerabilities against Questarr's
resolved dependency tree (see docs/DEPENDENCIES.md for how that tree is
pinned and kept current via Dependabot). There is nothing to make an
exploitability statement about yet. An empty statements array is a valid,
honest OpenVEX document — it is not a placeholder to be replaced later with
fabricated entries; it reflects the last real scan.
The feed exists as infrastructure, not a one-time snapshot: it is
regenerated by CI (see below) every time the container image is scanned, and
maintainers append a statement whenever a scanner (Grype/Trivy against the
SBOM, npm audit, or a GitHub Dependabot/security advisory) flags something
that turns out not to apply.
How the feed is generated and kept current
- Scanning —
.github/workflows/vulnerability-scan.ymlruns on every push tomain, on a weekly schedule, and on demand. It:- Runs
npm audit --omit=dev --jsonagainst the committedpackage-lock.json. - Builds the production Docker image and scans it with
Trivy, which covers both the
npm dependency tree and OS packages in the
node:22-alpinebase image (a common source of "known but unreachable" findings, since Questarr never invokes most Alpine base-image tooling at runtime). - Passes
security/vex/questarr.openvex.jsonto Trivy via--vexso previously-assessednot_affected/fixedfindings are suppressed from the report instead of re-flagging on every run. - Uploads the raw scan results (SARIF) to GitHub code scanning and as a workflow artifact for maintainer review.
- Runs
- Triage — when the scan surfaces a new CVE/GHSA not already covered by
a statement, a maintainer assesses it:
- If Questarr's usage of the component doesn't exercise the vulnerable
code (e.g. a CLI-only flag never invoked, a dev-only tool that never
ships to production, an Alpine package present in the base image but
never executed by the app), add a
not_affectedstatement with a specificimpact_statement— not a generic "doesn't apply". Speculative or unverified reasoning is not accepted; the justification must reference the actual code path (or its absence) in this repository. - If it's exploitable, add an
affectedstatement describing the mitigation in place (if partial) and open a tracking issue; resolving it (upgrading/patching) later flips the statement tofixed. - Statements are appended to
security/vex/questarr.openvex.jsonin a PR, reviewed like any other change, and the document's top-levelversionis incremented andtimestampupdated on every change.
- If Questarr's usage of the component doesn't exercise the vulnerable
code (e.g. a CLI-only flag never invoked, a dev-only tool that never
ships to production, an Alpine package present in the base image but
never executed by the app), add a
- Publishing — the feed is committed to the repository (so it's
versioned alongside the code it describes) and, like the SBOM, attached
as a workflow artifact on each scan run so external consumers (e.g.
Dependency-Track, or anyone running Trivy/Grype against a Questarr image
themselves) can pull it in with
--vex.
Consuming the feed
To apply Questarr's exploitability assessments when scanning a Questarr image yourself:
trivy image --vex security/vex/questarr.openvex.json ghcr.io/doezer/questarr:latest
Update policy
Revisit this document, and add/update statements in the feed, whenever:
- The vulnerability-scan workflow flags a new CVE/GHSA not yet covered.
- A dependency named in an existing
not_affected/affectedstatement is upgraded, removed, or its usage in Questarr changes such that the justification no longer holds (re-verify or flip the statement tofixed). - The base image (
node:22-alpine) digest pinned inDockerfileis bumped.