Skip to content

Commit 1abe3f7

Browse files
committed
Update the OpenVEX specification to OPEV-0014
This commit modifies the openvex spec to reflect the changes in the OpenVEX Enhancement Proposal 0014: Expansion of the VEX Product Field. Signed-off-by: Adolfo García Veytia (Puerco) <puerco@chainguard.dev>
1 parent d919792 commit 1abe3f7

File tree

1 file changed

+81
-15
lines changed

1 file changed

+81
-15
lines changed

OPENVEX-SPEC.md

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ expected to flow.
110110
#### Subcomponent
111111

112112
Any components possibly included in the product where the vulnerability originates.
113-
The subcomponents SHOULD also be software identifiers and they SHOULD also be
114-
listed in the product SBOM. subcomponents will most often be one or more of the
113+
The subcomponents SHOULD also list software identifiers and they SHOULD also be
114+
listed in the product SBOM. `subcomponents` will most often be one or more of the
115115
product's dependencies.
116116

117117
### Document
@@ -135,8 +135,8 @@ Here is a sample of a minimal OpenVEX document:
135135
{
136136
"vulnerability": "CVE-2023-12345",
137137
"products": [
138-
"pkg:apk/wolfi/git@2.39.0-r1?arch=armv7",
139-
"pkg:apk/wolfi/git@2.39.0-r1?arch=x86_64"
138+
{"@id": "pkg:apk/wolfi/git@2.39.0-r1?arch=armv7"},
139+
{"@id": "pkg:apk/wolfi/git@2.39.0-r1?arch=x86_64"}
140140
],
141141
"status": "fixed"
142142
}
@@ -174,8 +174,8 @@ A statement in an OpenVEX document looks like the following snippet:
174174
{
175175
"vulnerability": "CVE-2023-12345",
176176
"products": [
177-
"pkg:apk/wolfi/git@2.39.0-r1?arch=armv7",
178-
"pkg:apk/wolfi/git@2.39.0-r1?arch=x86_64"
177+
{"@id": "pkg:apk/wolfi/git@2.39.0-r1?arch=armv7"},
178+
{"@id": "pkg:apk/wolfi/git@2.39.0-r1?arch=x86_64"}
179179
],
180180
"status": "fixed"
181181
}
@@ -194,8 +194,7 @@ The following table lists the fields of the OpenVEX statement struct.
194194
| vuln_description || Optional free-form text describing the vulnerability |
195195
| timestamp || Timestamp is the time at which the information expressed in the Statement was known to be true. Cascades down from the document, see [Inheritance](#Inheritance). |
196196
| last_updated || Timestamp when the statement was last updated. |
197-
| products || Product identifiers that the statement applies to. Any software identifier can be used and SHOULD be traceable to a described item in an SBOM. The use of [Package URLs](https://github.com/package-url/purl-spec) (purls) is recommended. While a product identifier is required to have a complete statement, this field is optional as it can cascade down from the encapsulating document, see [Inheritance](#Inheritance). |
198-
| subcomponents || Identifiers of components where the vulnerability originates. While the statement asserts about the impact on the software product, listing `subcomponents` let scanners find identifiers to match their findings. |
197+
| products || List of product structs that the statement applies to. See the [Product Data Structure] section below for the full description. While a product is required to have a complete statement, this field is optional as it can cascade down from the encapsulating document, see [Inheritance](#Inheritance). |
199198
| status || A VEX statement MUST provide the status of the vulnerabilities with respect to the products and components listed in the statement. `status` MUST be one of the labels defined by VEX (see [Status](#Status-Labels)), some of which have further options and requirements. |
200199
| supplier || Supplier of the product or subcomponent. |
201200
| status_notes || A statement MAY convey information about how `status` was determined and MAY reference other VEX information. |
@@ -220,7 +219,7 @@ readable justification labels and optionally enrich the statement with an
220219
{
221220
"vulnerability": "CVE-2023-12345",
222221
"products": [
223-
"pkg:apk/wolfi/product@1.23.0-r1?arch=armv7",
222+
{"@id": "pkg:apk/wolfi/product@1.23.0-r1?arch=armv7"}
224223
],
225224
"status": "not_affected",
226225
"justification": "component_not_present",
@@ -229,6 +228,63 @@ readable justification labels and optionally enrich the statement with an
229228

230229
```
231230

231+
### Product Data Structure
232+
233+
The subject of an VEX statement is the _product_, a piece of software that MUST be
234+
addressable via one of the mechanisms offered by OpenVEX. The spec provides an
235+
expressive `product` struct with fields to address the product using identifiers,
236+
hashes. Note that all mechanisms to address the product are optional but a
237+
valid statement MUST identify a product to be valid.
238+
239+
The optional `@id` field takes an [IRI](#IRI) to make the product referenceable
240+
inside the document and addressable externally. As Package URLs are valid IRIs,
241+
the `@id` can take a purl as a value.
242+
243+
The product field should list as many software identifiers as possible to
244+
help VEX processors when matching the product. The use of
245+
[Package URLs](https://github.com/package-url/purl-spec) (purls) is recommended.
246+
247+
The product and its subcomponents fields share an abstract type called
248+
`Component` that defines the fields that can be used to identify them.
249+
The only difference in `product` is the nested `subcomponents` field.
250+
251+
#### Example Product Struct
252+
253+
```json
254+
{
255+
"@id": "pkg:apk/wolfi/product@1.23.0-r1?arch=armv7",
256+
"identifiers": {
257+
"purl": "pkg:maven/org.apache.logging.log4j/log4j-core@2.4",
258+
"cpe23": "cpe:2.3:a:apache:log4j:2.4:-:*:*:*:*:*:*",
259+
"cpe22": "cpe:/a:apache:log4j:2.4:-",
260+
},
261+
"hashes": {
262+
"sha-256": "402fa523b96591d4450ace90e32d9f779fcfd938903e1c5bf9d3701860b8f856",
263+
"sha-512": "d2eb65b083923d90cf55111c598f81d3d9c66f4457dfd173f01a6b7306f3b222541be42a35fe47191a9ca00e017533e8c07ca192bd22954e125557c72d2a3178"
264+
},
265+
"subcomponents": []
266+
}
267+
268+
```
269+
270+
271+
#### Component Fields
272+
273+
These fields are shared by both the `product` and `subcomponent` structs:
274+
275+
| Field | Required | Description |
276+
| --- | --- | --- |
277+
| @id || Optional [IRI](#IRI) identifying the component to make it externally referenceable. |
278+
| identifiers || A map of software identifiers where the key is the type and the value the identifier. OpenVEX favors the use of purl but others are recognized (see the Identifiers Labels table below) |
279+
| hashes || Map of cryptographic hashes of the component. The key is the algorithm name based on the [Hash Function Textual Names](https://www.iana.org/assignments/named-information/named-information.xhtml) from IANA. See [Hash Names Table] for the full supported list. |
280+
281+
The `product` struct uses the above listed fields but has a list of subcomponents,
282+
each itself a `component` subclass:
283+
284+
| Field | Required | Description |
285+
| --- | --- | --- |
286+
| subcomponents || List of `component` structs describing the subcomponents subject of the VEX statement. |
287+
232288
### Status Labels
233289

234290
Status labels inform the impact of a vulnerability in the products listed
@@ -340,7 +396,7 @@ example, the sole statement has its timestamp data derived from the document:
340396
{
341397
"vulnerability": "CVE-2023-12345",
342398
"products": [
343-
"pkg:apk/wolfi/git@2.39.0-r1?arch=armv7",
399+
{"@id": "pkg:apk/wolfi/git@2.39.0-r1?arch=armv7"}
344400
],
345401
"status": "under_investigation"
346402
}
@@ -366,14 +422,14 @@ to avoid duplication:
366422
"timestamp": "2023-01-08T18:02:03-06:00",
367423
"vulnerability": "CVE-2023-12345",
368424
"products": [
369-
"pkg:apk/wolfi/git@2.39.0-r1?arch=armv7",
425+
{"@id": "pkg:apk/wolfi/git@2.39.0-r1?arch=armv7"},
370426
],
371427
"status": "under_investigation"
372428
},
373429
{
374430
"vulnerability": "CVE-2023-12345",
375431
"products": [
376-
"pkg:apk/wolfi/git@2.39.0-r1?arch=armv7",
432+
{"@id": "pkg:apk/wolfi/git@2.39.0-r1?arch=armv7"}
377433
],
378434
"status": "fixed"
379435
},
@@ -403,7 +459,7 @@ processors.
403459

404460
### Public IRI Namespaces
405461

406-
As all documents are required to be identified by an IRI, open vex defines a
462+
As all documents are required to be identified by an IRI, OpenVEX defines a
407463
public namespace that can be used by documents. Users of OpenVEX MAY choose to
408464
use the shared namespace.
409465

@@ -420,7 +476,7 @@ There are two reserved shared namespaces with special meanings:
420476

421477
- `public` this is a public shared name where anybody that needs a valid IRI can
422478
issue identifiers. Only recommended for demos or experiments where name collisions
423-
don't matter.
479+
do not matter.
424480
- `example` a namespace for documentation, demos or other uses where no systems
425481
are expected to run.
426482

@@ -455,7 +511,15 @@ the project could issue an OpenVEX document as follows:
455511
{
456512
"vulnerability": "CVE-2021-44228",
457513
"products": [
458-
"pkg:maven/org.springframework.boot/spring-boot@2.6.0"
514+
{
515+
"@id": "pkg:maven/org.springframework.boot/spring-boot@2.6.0-M3",
516+
"identifiers": {
517+
"purl": "pkg:maven/org.springframework.boot/spring-boot@2.6.0-M3",
518+
}
519+
"hashes":{
520+
"sha-256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
521+
}
522+
}
459523
],
460524
"status": "not_affected",
461525
"justification": "vulnerable_code_not_in_execute_path"
@@ -472,6 +536,7 @@ alert and dashboards could present users with the official guidance from the pro
472536

473537
| Date | Revision |
474538
| --- | --- |
539+
| 2023-07-18 | Updated spec to reflect changes in [OPEV-0014: Expansion of the VEX Product Field](https://github.com/openvex/community/blob/main/enhancements/opev-0014.md) |
475540
| 2023-07-18 | Bumped version of the spec to v0.0.2 after update to meet the VEX-WG doc. |
476541
| 2023-06-01 | Removed supplier from the document level (following VEX-WG doc). |
477542
| 2023-05-29 | Specification updated to reflect the published [Minimum Requirements for VEX] document. |
@@ -489,3 +554,4 @@ alert and dashboards could present users with the official guidance from the pro
489554

490555
[Status Justifications]: https://www.cisa.gov/sites/default/files/publications/VEX_Status_Justification_Jun22.pdf
491556
[Minimum Requirements for VEX]: https://www.cisa.gov/sites/default/files/2023-04/minimum-requirements-for-vex-508c.pdf
557+
[IRI]: https://www.ietf.org/rfc/rfc3987.txt

0 commit comments

Comments
 (0)