Backpatch VEX feed
A backpatch carries the upstream security fix onto the exact release you already
run, published as +backpatch.NNN. Your scanner reads the version number, sees the old
release, and flags the CVE anyway. This feed is the proof it's already patched.
vex.backpatch.moderne.io/openvex/all.json
vex.backpatch.moderne.io/cyclonedx/backpatch-vex.cdx.json
Every statement matches by exact package URL. Fetch the feed, wire it in, findings move to suppressed.
Also the engine in Anchore Enterprise
Reads local OpenVEX. Fetch the feed, pass it with --vex.
curl -fsSLO https://vex.backpatch.moderne.io/openvex/all.json &&
grype sbom:my-app.cdx.json --vex all.json --show-suppressed
Also the engine in Harbor and GitLab
Point --vex at the file; matching PURLs move to suppressed.
curl -fsSLO https://vex.backpatch.moderne.io/openvex/all.json &&
trivy sbom my-app.cdx.json --vex ./all.json
Advanced Security (3.136+) ingests external CycloneDX VEX. Enable Skip Not Applicable CVEs, plus one scoped ignore rule per (component, CVE).
curl -fsSLO https://vex.backpatch.moderne.io/cyclonedx/backpatch-vex.cdx.json
# Import as an external CycloneDX VEX source, then enable
# the "Skip Not Applicable CVEs" contextual-analysis rule.
Matches by binary hash — rebuilt backpatches often clear on their own. For a waiver, POST the CycloneDX to the experimental Analysis API.
curl -fsSLO https://vex.backpatch.moderne.io/cyclonedx/backpatch-vex.cdx.json &&
curl -u "$IQ_USER:$IQ_TOKEN" -X POST \
"$IQ_URL/api/experimental/vex/application/$APP_ID/report/$SCAN_ID" \
--data-binary @backpatch-vex.cdx.json
Ingests CycloneDX VEX per project. Re-apply after each SBOM upload — or do both in one CI step.
curl -fsSLO https://vex.backpatch.moderne.io/cyclonedx/backpatch-vex.cdx.json &&
curl -X POST https://dtrack.example.com/api/v1/vex \
-H "X-Api-Key: $DT_API_KEY" \
-F "project=$PROJECT_UUID" -F "vex=@backpatch-vex.cdx.json"
Regenerated on every publish, served without caching.
# how many statements are live?
curl -fsS https://vex.backpatch.moderne.io/openvex/all.json | jq '.statements | length'
# confirm a backpatched artifact is cleared
grype my-app.cdx.json --vex all.json --show-suppressed | grep 'suppressed by VEX'
New to VEX? Here's what these documents say, and why the feed ships two formats.
A scanner reads your SBOM and flags every CVE ever filed against the versions it
finds. VEX
(Vulnerability Exploitability eXchange) is the other half: a machine-readable statement of whether a CVE
actually affects a specific artifact, and what was done about it. Statements in this feed carry one of
two statuses: fixed, where we shipped a patch, and not_affected, where the CVE
is filed against the baseline but the vulnerable code is not in the artifact we ship.
OpenSSF · for Grype and Trivy
A minimal, standalone VEX format. Each document is a small JSON file of statements, so CLI
scanners read it directly with --vex.
OWASP · for Xray, Dependency-Track, auditors
A full SBOM standard that also carries vulnerability and analysis data, and can embed pedigree linking the upstream fix commit as evidence.
VEX in CycloneDX →A single OpenVEX statement looks like this:
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://vex.backpatch.moderne.io/openvex/gson-2.8.8+backpatch.001.json",
"author": "Moderne Backpatch Alliance <support@moderne.io>",
"timestamp": "2026-07-05T06:53:21Z",
"version": 1,
"statements": [
{
"vulnerability": { "name": "CVE-2022-25647", "aliases": ["GHSA-4jrv-ppp4-jm57"] },
"products": [
{
"@id": "pkg:maven/com.google.code.gson/gson@2.8.8%2Bbackpatch.001",
"identifiers": { "purl": "pkg:maven/com.google.code.gson/gson@2.8.8%2Bbackpatch.001" },
"hashes": { "sha-256": "2575baa2fd678a378998e9c3f238d68bdffe327303c00192401eff3ee570be17" }
}
],
"status": "fixed",
"action_statement": "CVE-2022-25647 fixed by backporting the upstream fix onto the 2.8.8 baseline."
}
]
}
fixed means a patch for it ships in that baseline. not_affected means it never applied to what we ship.fixed statement, a plain-language note on what was done.not_affected statement, the OpenVEX label saying why it does not apply, usually vulnerable_code_not_present. An optional impact_statement spells the same reason out in prose.