This article explains how to implement vulnerability scanning support for Chainguard Libraries in your scanner. This guide assumes your scanner already has the capability to detect language ecosystem packages (only Python currently) and match them to vulnerabilities using existing databases like NVD, GitHub Advisory Database, or OSV. This guide focuses on how to integrate Chainguard's VEX feed to correctly handle remediated packages.
Note: This article assumes you're already familiar with the material covered in Foundational Concepts.
To support Chainguard Libraries, your scanner needs to:
- Detect library packages using your existing detection methods
- Fetch VEX data from Chainguard's VEX feed
- Apply VEX statements to suppress vulnerabilities that have been fixed in remediated versions
- Example implementation in Grype: anchore/grype#2886
The integration primarily involves consuming Chainguard's VEX feed and applying the VEX statements to your scan results.
Use your scanner's existing methods to detect library packages. The key requirement is preserving the full version string including local version identifiers:
- Python:
werkzeug==3.0.2+cgr.0(the+cgr.0suffix is critical)
Important: Remediated packages use local version identifiers (e.g., +cgr.0) to distinguish them from upstream versions. Your scanner must preserve these identifiers to correctly match VEX statements. The version identifier can be accessed from a lock file and/or after the dependency resolution step for ingestion.
When scanning declared dependencies (like requirements.txt), be aware that the declared version may differ from the actually installed version. For best results, scan the installed environment (Python virtual environments) rather than just lock files.
🎯 Goal: Apply VEX statements from Chainguard's feed to suppress false positives for remediated vulnerabilities.
Chainguard's VEX feed is compatible with the vex-repo-spec and follows the OpenVEX v0.2.0 specification.
Base URL: https://libraries.cgr.dev/openvex/v1/
Index file: https://libraries.cgr.dev/openvex/v1/index.json
The index file lists all available packages with their modification timestamps:
{
"packages": [
{
"id": "pkg:pypi/werkzeug",
"location": "pypi/werkzeug.openvex.json",
"modified": "2025-10-23T06:01:33.081Z"
},
{
"id": "pkg:pypi/pillow",
"location": "pypi/pillow.openvex.json",
"modified": "2025-10-23T06:01:32.44Z"
}
]
}Individual package files: https://libraries.cgr.dev/openvex/v1/<ecosystem>/<package_name>.openvex.json
For packages with namespaces: https://libraries.cgr.dev/openvex/v1/<ecosystem>/<namespace>/<package_name>.openvex.json
Examples:
https://libraries.cgr.dev/openvex/v1/pypi/werkzeug.openvex.json
Each VEX file follows the OpenVEX v0.2.0 specification. As an exmple:
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-...",
"author": "Chainguard Team",
"supplier": "Chainguard",
"statements": [
{
"vulnerability": {
"name": "CGA-p5p5-4cg9-7w3c",
"aliases": [
"CVE-2024-34069",
"GHSA-xg8h-j46f-w952"
]
},
"products": [
{
"identifiers": {
"purl": "pkg:pypi/werkzeug@3.0.2%2Bcgr.1"
}
}
],
"status": "fixed",
"timestamp": "2025-10-23T06:01:32.44Z"
}
]
}After detecting packages using your scanner's existing methods, apply VEX data:
-
For each detected package, construct its PURL (Package URL):
- Format:
pkg:<ecosystem>/<package_name>@<version> - Example:
pkg:pypi/werkzeug@3.0.2%2Bcgr.0
- Format:
-
Fetch the VEX file for the package:
- URL:
https://libraries.cgr.dev/openvex/v1/<ecosystem>/<package_name>.openvex.json - Optionally use
index.jsonto trackmodifiedtimestamps for cache invalidation
- URL:
-
Process VEX statements:
- Find statements where
products[].identifiers.purlmatches your package PURL - Extract the vulnerability information and status
- Find statements where
-
Apply VEX status to your scan results:
"fixed": Suppress this vulnerability. This is the only status Chainguard currently uses for remediated vulnerabilities.
-
Map vulnerability identifiers:
- Use
vulnerability.aliasesto map to CVE/GHSA IDs - Report using standard identifiers familiar to users
- Use
Detected package: werkzeug==3.0.2+cgr.0
-
Construct PURL:
pkg:pypi/werkzeug@3.0.2%2Bcgr.0 -
Fetch VEX file:
GET https://libraries.cgr.dev/openvex/v1/pypi/werkzeug.openvex.json -
Parse VEX statement:
{
"vulnerability": {
"name": "CGA-2g68-c3qc-8985",
"aliases": ["CVE-2024-34069", "GHSA-2g68-c3qc-8985"]
},
"products": [
{"identifiers": {"purl": "pkg:pypi/werkzeug@3.0.2%2Bcgr.0"}}
],
"status": "fixed"
}- Apply result: Suppress
CVE-2024-34069from scan results for this package