This document describes the Chainguard v2 security feed format, officially rolled out on April 20, 2026. The v2 feed extends the Open Source Vulnerability (OSV) schema v1.7.5 with per-component ecosystem specific vulnerability data. Unlike the original Chainguard OSV feed, which only publishes resolved advisories (fixed and false positive), the v2 feed publishes all advisory statuses, including detections, pending upstream fixes, and other unresolved states, giving scanners complete visibility into Chainguard's vulnerability analysis. For details on the individual advisory statuses, see latest_event_status later in this document or Chainguard's summary of advisory statuses for broader context.
Note: This document assumes you're already familiar with the material covered in Foundational Concepts, including Chainguard's OSV feed. If you are migrating from the original Chainguard OSV feed, see Differences from the original feed for a summary of changes, including new architecture granularity and per-advisory component data.
The v2 feed uses path-based versioning. The version identifier (v2) is part of the URL path, making it possible to consume a specific feed version without ambiguity. Future feed versions will follow the same convention (e.g., /v3/osv/).
| Resource | URL |
|---|---|
| Index | https://advisories.cgr.dev/chainguard/v2/osv/all.json |
| Individual record | https://advisories.cgr.dev/chainguard/v2/osv/<CGA-ID>.json |
Note: The v2 feed is served from
advisories.cgr.dev, the new dedicated domain for Chainguard's security advisory feeds. The legacypackages.cgr.devdomain used by the original feed will eventually be deprecated. New integrations should useadvisories.cgr.devexclusively.
Consuming the feed is a two-step process:
Request the index to get the list of all available vulnerability records:
GET https://advisories.cgr.dev/chainguard/v2/osv/all.json
The response is a JSON array of id and modified pairs, sorted by id:
[
{ "id": "CGA-224q-ccj5-2p53", "modified": "2026-01-07T00:00:00Z" },
{ "id": "CGA-2255-2h2p-73q2", "modified": "2026-01-07T00:00:00Z" },
{ "id": "CGA-2266-xcqq-qpf4", "modified": "2026-01-26T20:04:09.447Z" },
...
]Each id is a parent CGA identifier that groups one or more advisory records for the same upstream vulnerability. Use the modified timestamps to detect changes since your last sync.
Use an id from the index to request the full vulnerability record:
GET https://advisories.cgr.dev/chainguard/v2/osv/CGA-224q-ccj5-2p53.json
This returns the complete record for CGA-224q-ccj5-2p53, including all affected packages, version ranges, component details, severity, and references. The full record schema is described below.
The feed is refreshed hourly. To keep your scanner's data current, poll the index at least once per hour and re-fetch any records whose modified timestamp has changed.
The following schema shows the structure of a vulnerability record. Each field is described in the sections that follow.
{
"schema_version": string,
"id": string,
"published": string,
"modified": string,
"severity": [ { "type": string, "score": string } ],
"upstream": [ string ],
"references": [ { "type": string, "url": string } ],
"affected": [ {
"package": {
"ecosystem": string,
"name": string,
"purl": string
},
"ranges": [ {
"type": string,
"events": [ { "introduced": string, "fixed": string } ]
} ],
"ecosystem_specific": {
"components": [ {
"advisory_id": string,
"architecture": string,
"component_name": string,
"component_version": string,
"component_type": string,
"component_location": string,
"component_purl": string,
"latest_event_status": string,
"latest_event_timestamp": string
} ]
}
} ]
}For the official definitions of top-level fields, see the OSV schema specification. The sections below describe how Chainguard uses them.
{
"schema_version": "1.7.5"
}The schema_version field identifies which version of the OSV schema the record conforms to. All v2 feed records use schema version 1.7.5.
{
"id": "CGA-2mh2-vjwv-24h5"
}The id field is the identifier for the vulnerability record. It is a Chainguard Advisory (CGA) identifier in the format CGA-xxxx-xxxx-xxxx.
{
"published": "2026-01-15T10:00:00Z",
"modified": "2026-06-15T12:00:00Z"
}The published field indicates the time the vulnerability was first recorded, as an RFC 3339 timestamp in UTC. It is derived from the earliest created_at timestamp across all advisories in the group. If no creation timestamp is available, the field is omitted.
The modified field indicates the time the record was last updated, as an RFC 3339 timestamp in UTC. It is derived from the latest updated_at timestamp across all advisories in the group. Given two records with the same id, the one with the later modified time should be considered authoritative.
{
"severity": [
{ "type": "CVSS_V3", "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }
]
}The severity field lists severity scores for the vulnerability. The type field identifies the scoring system. The score field contains the score string. The defined type values are CVSS_V2, CVSS_V3, and CVSS_V4.
If no severity data is available, the field is an empty array.
{
"upstream": ["CVE-2024-0001", "GHSA-abcd-efgh-ijkl"]
}The upstream field lists identifiers for the upstream vulnerability that this record describes. These are typically CVE and GHSA identifiers. The relationship is unidirectional (asymmetric). This record references the listed upstream vulnerabilities, but those upstream records do not reference this CGA.
{
"references": [
{ "type": "WEB", "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-0001" }
]
}The references field lists URLs for the vulnerability. Each entry has a type field and a url field. The defined type values follow the OSV specification: ADVISORY, ARTICLE, DETECTION, DISCUSSION, REPORT, FIX, INTRODUCED, PACKAGE, EVIDENCE, and WEB.
If no reference data is available, the field is an empty array.
{
"affected": [ ... ]
}The affected field lists packages affected by the vulnerability. Each entry represents one combination of package name, architecture, and ecosystem.
{
"package": {
"ecosystem": "Chainguard",
"name": "curl",
"purl": "pkg:apk/chainguard/curl?arch=x86_64"
}
}The package field identifies the affected package.
The ecosystem field identifies the package ecosystem. A package may appear under one or both of the following ecosystems:
| Ecosystem | Description |
|---|---|
Chainguard |
Packages built and distributed by Chainguard. |
Wolfi |
Packages from the Wolfi repository. Wolfi packages receive both a Chainguard and a Wolfi affected entry with the same version range. |
The name field is the package name as it appears in the APK repository (e.g., curl, openssl, go-1.23).
The purl field is a Package URL identifying the package. It includes an ?arch= qualifier specifying the CPU architecture (e.g., x86_64, aarch64). The PURL does not include a version component, since the affected version range is expressed in the ranges field.
{
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{ "introduced": "0" },
{ "fixed": "8.5.0-r1" }
]
}
]
}The ranges field lists the affected version ranges. Each range contains a type and a list of events.
The type field is always ECOSYSTEM. Versions are compared using APK version ordering.
The events list contains version markers. Each event object has one property:
introducedis the version at which the vulnerability was introduced. The value"0"represents a version that sorts before all other versions.fixedis the version at which the vulnerability was fixed. Versions fromintroducedup to but not includingfixedare affected. The value"0"is a special convention indicating a false positive determination (resulting in an empty affected range).
There is one range per affected entry. The events are determined by the status aggregation rules.
{
"ecosystem_specific": {
"components": [ ... ]
}
}While the ranges field defines the vulnerability status for the package as a whole, the ecosystem_specific field provides the granular, per-component data that informed that status. It contains a single components array holding per-component data.
{
"advisory_id": "CGA-abcd-efgh-ijkl",
"architecture": "x86_64",
"component_name": "libcurl",
"component_version": "8.4.0",
"component_type": "apk",
"component_location": "/usr/lib/libcurl.so.4",
"component_purl": "pkg:apk/libcurl@8.4.0",
"latest_event_status": "fixed",
"latest_event_timestamp": "2024-06-15T12:00:00Z"
}Each component object maps 1:1 to a Chainguard advisory record. The fields are:
The advisory_id field is the child CGA identifier for this specific advisory, rolling up to the parent group identified by the top-level id.
The architecture field is the CPU architecture of the package build (e.g., x86_64, aarch64).
The component_name field is the name of the component where the vulnerability was detected (e.g., libcurl, golang.org/x/crypto). This may differ from the package name when a package bundles other libraries.
The component_version field is the version of the component at the time of detection. This value is extracted from the advisory's detection scan data.
The component_type field identifies the component's package type using Syft type identifiers (e.g., apk, java-archive, go-module, python, npm, gem, rust-crate, php-composer, dotnet).
The component_location field is the filesystem path where the component was found within the package (e.g., /usr/lib/libcurl.so.4, /usr/share/java/netty.jar).
The component_purl field is a Package URL for the component, including its version. The PURL type is derived from the component_type. If the component type cannot be mapped to a PURL type, this field is empty.
The latest_event_status field is the resolution status of this advisory as a lowercase string. The defined values are:
| Status | Classification | Mapping to UI Status | Description |
|---|---|---|---|
fixed |
Resolved | Fixed | A fix has been applied to the affected component and the vulnerability is no longer present. |
false_positive_determination |
Resolved | Not affected | The vulnerability does not affect this component. |
detection |
Unresolved | Under investigation | The vulnerability has been detected for the component and is awaiting further investigation to determine its impact. |
true_positive_determination |
Unresolved | Affected | The vulnerability has been confirmed ro be present and affect the component. |
pending_upstream_fix |
Unresolved | Pending upstream fix | Remediating the vulnerability is not possible until a fix is made available from the upstream project. |
fix_not_planned |
Unresolved | Fix not planned | There are no plans to address the vulnerability in the component at this time. |
The latest_event_timestamp field is the time of the most recent advisory event, as an RFC 3339 timestamp in UTC.
The package-level version range in affected[].ranges is determined by aggregating the status of each component in the affected group. Each component's latest event is classified as resolved or unresolved:
| Classification | Event Types |
|---|---|
| Resolved | fixed, false_positive_determination |
| Unresolved | detection, true_positive_determination, analysis_not_planned, fix_not_planned, pending_upstream_fix |
These statuses combine using the following precedence (highest wins):
- Any component unresolved: the package is affected
- All resolved, at least one fixed: the package has a fix
- All resolved, all false positives: the vulnerability does not affect this package
| Outcome | ranges[].events |
Meaning |
|---|---|---|
| Affected (unresolved) | [{"introduced": "0"}] |
At least one component is unresolved. No fix version is present. |
| Fixed | [{"introduced": "0"}, {"fixed": "<version>"}] |
All components are resolved and at least one has a fix. The fixed version comes from the advisory's fixed event. |
| Not affected (false positive) | [{"introduced": "0"}, {"fixed": "0"}] |
All components are resolved and all are false positives. |
The following matrix shows how two component statuses combine. All unresolved event types behave the same.
FIXED FALSE_POS UNRESOLVED
FIXED Fixed Fixed Affected
FALSE_POS Fixed Not affected Affected
UNRESOLVED Affected Affected Affected
For each (package, architecture, ecosystem) group:
Any component unresolved?
+-- YES: Affected (no fix version)
+-- NO (all resolved):
Any component fixed?
+-- YES: Fixed at the advisory's version
+-- NO: Not affected (all false positives)
The following examples are taken from the live v2 feed. Click the record links to see the full data.
From CGA-224q-ccj5-2p53: a vulnerability in haproxy-2.2 (CVE-2025-32464) fixed in version 2.2.34-r0.
{
"package": {
"ecosystem": "Chainguard",
"name": "haproxy-2.2",
"purl": "pkg:apk/chainguard/haproxy-2.2?arch=x86_64"
},
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{ "introduced": "0" },
{ "fixed": "2.2.34-r0" }
]
}
],
"ecosystem_specific": {
"components": [
{
"advisory_id": "CGA-hxhw-2p27-xpg6",
"architecture": "x86_64",
"component_name": "haproxy-2.2",
"component_version": "2.2.33-r40",
"component_type": "apk",
"component_location": "/.PKGINFO",
"component_purl": "pkg:apk/haproxy-2.2@2.2.33-r40",
"latest_event_status": "fixed",
"latest_event_timestamp": "2025-04-25T13:01:15Z"
}
]
}
}The range [{"introduced": "0"}, {"fixed": "2.2.34-r0"}] indicates that all versions before 2.2.34-r0 are affected. A scanner seeing haproxy-2.2 at version 2.2.33-r40 should flag this vulnerability.
From CGA-6f85-jvrm-qq3w: CVE-2026-32288 was determined to be a false positive for the Go stdlib component in actions-runner-controller.
{
"package": {
"ecosystem": "Chainguard",
"name": "actions-runner-controller",
"purl": "pkg:apk/chainguard/actions-runner-controller?arch=aarch64"
},
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{ "introduced": "0" },
{ "fixed": "0" }
]
}
],
"ecosystem_specific": {
"components": [
{
"advisory_id": "CGA-32qj-p4rc-7jv7",
"architecture": "aarch64",
"component_name": "stdlib",
"component_version": "go1.26.1",
"component_type": "go-module",
"component_location": "/usr/bin/ghalistener",
"component_purl": "pkg:golang/stdlib@go1.26.1",
"latest_event_status": "false_positive_determination",
"latest_event_timestamp": "2026-04-10T20:56:35Z"
}
]
}
}The range [{"introduced": "0"}, {"fixed": "0"}] uses "0" as both the introduced and fixed version, resulting in an empty affected range. A scanner should not flag this vulnerability for this package.
From the same record CGA-224q-ccj5-2p53: the same CVE-2025-32464 vulnerability affects haproxy-2.9, but a fix is pending from the upstream project.
{
"package": {
"ecosystem": "Chainguard",
"name": "haproxy-2.9",
"purl": "pkg:apk/chainguard/haproxy-2.9?arch=x86_64"
},
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{ "introduced": "0" }
]
}
],
"ecosystem_specific": {
"components": [
{
"advisory_id": "CGA-72p4-pqqf-9q8x",
"architecture": "x86_64",
"component_name": "haproxy-2.9",
"component_version": "2.9.10-r40",
"component_type": "apk",
"component_location": "/.PKGINFO",
"component_purl": "pkg:apk/haproxy-2.9@2.9.10-r40",
"latest_event_status": "pending_upstream_fix",
"latest_event_timestamp": "2025-04-14T20:11:36Z"
}
]
}
}The range contains only [{"introduced": "0"}] with no fixed event. No fix version is available because the vulnerability is still unresolved. A scanner should flag this. The latest_event_status of pending_upstream_fix tells you why no fix exists yet.
Note that all unresolved statuses (detection, true_positive_determination, pending_upstream_fix, fix_not_planned) produce the same range output. The latest_event_status in components is the only way to distinguish between them.
When a single affected entry contains multiple components with different statuses, the decision matrix determines the package-level range. Any unresolved component keeps the entire package affected, even if other components are fixed:
{
"package": {
"ecosystem": "Chainguard",
"name": "nginx",
"purl": "pkg:apk/chainguard/nginx?arch=x86_64"
},
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{ "introduced": "0" }
]
}
],
"ecosystem_specific": {
"components": [
{
"advisory_id": "CGA-comp-fixed",
"architecture": "x86_64",
"component_name": "libxml2",
"component_version": "2.11.0",
"component_type": "apk",
"component_location": "/usr/lib/libxml2.so.2",
"component_purl": "pkg:apk/libxml2@2.11.0",
"latest_event_status": "fixed",
"latest_event_timestamp": "2024-05-20T11:00:00Z"
},
{
"advisory_id": "CGA-comp-detected",
"architecture": "x86_64",
"component_name": "pcre2",
"component_version": "10.42",
"component_type": "apk",
"component_location": "/usr/lib/libpcre2-8.so.0",
"component_purl": "pkg:apk/pcre2@10.42",
"latest_event_status": "detection",
"latest_event_timestamp": "2024-04-01T09:00:00Z"
}
]
}
}The libxml2 component is fixed, but the unresolved pcre2 component keeps the package-level range as [{"introduced": "0"}] with no fix. The components array shows which components are resolved and which are not.
The v2 feed differs from the original Chainguard OSV feed (https://packages.cgr.dev/chainguard/osv/) in the following ways. Note that the v2 feed is also served from a new domain, advisories.cgr.dev. The packages.cgr.dev domain will eventually be deprecated.
| Aspect | Original feed | v2 feed |
|---|---|---|
| Feed URL | packages.cgr.dev/chainguard/osv/all.json |
advisories.cgr.dev/chainguard/v2/osv/all.json |
| Record URL | packages.cgr.dev/chainguard/osv/<CGA-ID>.json |
advisories.cgr.dev/chainguard/v2/osv/<CGA-ID>.json |
| Affected entry granularity | One entry per (package, ecosystem) | One entry per (package, architecture, ecosystem) |
| Architecture | Not represented | Included as ?arch= PURL qualifier |
| Alias field | related |
upstream |
| Component detail | Not present | Per-advisory data in ecosystem_specific.components |
| Fixed version | Highest version across all advisories for a package | Aggregate fixed version across advisory events for (package, architecture, ecosystem) |
| Advisory coverage | Only resolved advisories (fixed, false positive) | All advisory statuses published in a single feed, including detections, pending upstream fixes, and other unresolved states |
| Severity and references | Not present | From vulnerability metadata when available |
| Schema version | Not set | 1.7.5 |
The original feed will eventually be archived. New integrations should use the v2 feed or later.
- Foundational Concepts - overview of Wolfi, Chainguard Images, and security data
- Scanning Implementation - how to implement scanning using the OSV feed
- OSV Schema Specification
- Package URL Specification