Skip to main content

Vulnerability data sources

TRUSCA correlates SBOMs against CVEs using the Trivy DB, a compiled bundle of five public vulnerability feeds. This page is the reference for what each source contributes, when it refreshes, and which ecosystems it covers.

Audience

Security leads, auditors, and operators answering "where does this CVE come from?" or "why is this ecosystem missing?". For the operator-facing lifecycle (download, refresh, air-gapped mirror) see Vulnerability data (Trivy DB).

Source matrix​

SourceOwnerRefresh upstreamWhat it contributes
NVD — National Vulnerability DatabaseNIST~6 hoursCVE IDs, CVSS v3 vectors, CPE matching, references. The CVE backbone.
OSV — Open Source VulnerabilitiesGoogleContinuousPer-ecosystem advisories with precise version ranges (introduced / fixed / last_affected).
GHSA — GitHub Security AdvisoriesGitHubContinuousAdvisory metadata, fix versions, withdrawal status. Often the first to publish for npm / pip / Maven.
EPSS — Exploit Prediction Scoring SystemFIRSTDaily30-day exploit probability 0.0–1.0 and percentile. Drives the optional EPSS gate.
KEV — Known Exploited VulnerabilitiesCISAAs publishedBoolean flag: this CVE has confirmed in-the-wild exploitation. Highest-priority triage signal.

Three of the five (NVD, OSV, GHSA) live in the same Trivy DB bundle, and the portal does not call any API at scan time: per-scan matching reads from /var/lib/trivy/db/ on the worker, which the Trivy DB refresh task keeps current.

EPSS and KEV do not come from the scanner. Its output carries neither, so each has its own daily sync that writes onto the vulnerability catalog: KEV from CISA's feed, EPSS from FIRST's daily CSV.

Both syncs reach the network, so both can be turned off, and EPSS_REFRESH_ENABLED is off by default. While it is off epss_score and epss_percentile stay empty, and every surface that reads them is empty with it: the EPSS column and the min_epss filter on the Vulnerabilities tab, the EPSS term in sort=priority, the EPSS columns in the Excel and PDF reports, and the optional GATE_EPSS_THRESHOLD build gate, which then passes every build no matter how low the threshold is set. Turn the sync on, or point EPSS_FEED_URL at an internal mirror, before relying on any of them.

EPSS is stewarded by the EPSS Special Interest Group at FIRST; the scores are generated and published by Empirical Security. FIRST asks for attribution where possible, and the citation they supply is:

Jay Jacobs, Sasha Romanosky, Benjamin Edwards, Michael Roytman,
Idris Adjerid (2021), Exploit Prediction Scoring System,
Digital Threats Research and Practice, 2(3)

Full terms are in THIRD_PARTY_NOTICES.md. The bulk CSV is deliberately the only ingest path: FIRST's guidance is that their lookup API must not be used for bulk downloads or to keep a local copy in sync.

One component-level source sits outside the Trivy DB:

SourcePublisherRefreshWhat it contributes
endoflife.date — product lifecycle datesendoflife.date community (code MIT; lifecycle dates are factual data)Snapshot vendored per release (scripts/refresh_eol_snapshot.py)End-of-life verdicts for a curated whitelist of runtimes/frameworks — the EOL badge and filter. Read from the bundled snapshot at scan time; zero network calls.

Refresh cadence in the portal​

LayerCadenceKnob
Upstream Trivy DB rebuild~6 hours (Aqua publishes a new OCI tag)—
Portal worker pulls the new DBWeeklyTRIVY_DB_REFRESH_HOURS (default 168)
Per-scan match against local DBPer scan (no network)—
Automatic re-match of existing SBOMsAfter every successful DB refreshCelery beat task tasks.rematch.run_rematch

The automatic re-match beat is the killer feature DT could not deliver in our deployment: when a new CVE lands in the refreshed DB, the beat task walks every project's most-recent SBOM and writes new vulnerability_findings rows where they match. Users see fresh findings on the Vulnerabilities tab without re-triggering a scan.

For the user-facing view of re-detection (banner, notification triggers), see Re-detection.

Ecosystem coverage​

The Trivy DB matches components by their package URL (purl). Coverage is dense for the ecosystems below — each has a dedicated OSV stream plus GHSA contributions.

Ecosystempurl typePrimary feed(s)Notes
npm (JavaScript / Node)pkg:npm/*OSV + GHSA + NVDFirst-class — most CVEs land in GHSA first.
PyPI (Python)pkg:pypi/*OSV + GHSA + NVDFirst-class.
Maven (Java / Kotlin)pkg:maven/*OSV + GHSA + NVDFirst-class. Classifier-aware as of v0.10.0.
Go modulespkg:golang/*OSV + GHSA + NVDFirst-class. Vulnerability DB at vuln.go.dev.
RubyGemspkg:gem/*OSV + GHSAFirst-class.
crates.io (Rust)pkg:cargo/*OSV + GHSAFirst-class.
Packagist (PHP)pkg:composer/*OSV + GHSAFirst-class.
NuGet (.NET)pkg:nuget/*OSV + GHSA + NVDFirst-class.
Hex (Elixir / Erlang)pkg:hex/*OSVSolid.
Pub (Dart / Flutter)pkg:pub/*OSVSolid.
Conan (C / C++)pkg:conan/*OSVSparser than the above — many C/C++ CVEs are OS-package CVEs, see below.
OS packages (Alpine, Debian, RHEL, …)pkg:apk/*, pkg:deb/*, pkg:rpm/*NVD + per-distro security advisoriesUsed by the container scan pipeline (scan_container.py). Source scans on a repo of C/C++ code do not produce these.

If a component's purl does not match a feed entry, no finding is created — silently, by design. Two common reasons:

  • Non-canonical purl. cdxgen is conservative: a malformed package.json may yield a purl that doesn't normalize. File an issue with the scan ID; we tighten the generator over time.
  • Ecosystem is not in OSV / GHSA yet. Coverage grows monthly. The OSV ecosystem list is the upstream source of truth.

Per-finding data signals​

Compared to a Dependency-Track-class tool, the Trivy DB exposes the following per-finding signals. The portal surfaces all of them on the Vulnerabilities tab and through the API.

SignalSourceWhere in the portal
CVE IDNVD / OSV / GHSARow identifier, header chip.
Severity (critical / high / medium / low)NVD CVSS v3 (preferred) → GHSA → OSVRow badge, distribution card, severity filter.
CVSS v3 vectorNVDFinding drawer → Summary.
Description / titleNVD / GHSAFinding drawer → Summary.
CWENVDFinding drawer → Summary.
Fixed versionGHSA → OSV (fixed range)Finding drawer → Affected component → "Fixed in".
Affected version rangesOSV (introduced / last_affected / fixed)Used by the matcher; not surfaced directly.
EPSS score / percentileEPSSFinding drawer → Summary; sortable column; gate via GATE_EPSS_THRESHOLD.
KEV (in the wild)KEV catalogueFinding row badge; can drive the gate (post-GA roadmap).
ReferencesNVD / GHSA / OSV (deduplicated by URL)Finding drawer → References.

The portal does not consume:

  • Curated vulnerability research from the proprietary feeds that commercial SCA tools bundle — by design, we ship the open feeds only.
  • Vendor-specific advisory feeds (Oracle CPU, Microsoft MSRC) beyond what flows into NVD. These can be added as additional Trivy data sources in a future release.
  • Reachability as a Trivy-DB signal — the Trivy DB does not carry reachability. TRUSCA does run reachability, but as a separate govulncheck analyser for Go, not from Trivy DB data (see Analysis types → Reachability). It marks Go findings reachable / not-reachable / not-analysed; findings in other ecosystems are not analysed and are shown as "potentially affected".

What this means for triage​

The matrix above is what is automatically in front of every analyst. Two practices keep triage signal-to-noise high:

  1. Layer EPSS over CVSS. A medium CVE with EPSS percentile > 95 deserves a faster look than a critical with EPSS < 5. Use the column sort or the GATE_EPSS_THRESHOLD env to gate.
  2. Filter by KEV. The Vulnerabilities tab carries a KEV filter — anything in the CISA catalogue has confirmed exploitation and should be patched ahead of severity-only ranking.

For the user-facing flow (drawer, VEX state machine, suppression), see Vulnerabilities.

See also​