Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions schema/bom-1.7.proto
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ message Bom {
repeated Declarations declarations = 14;
// A collection of reusable objects that are defined and may be used elsewhere in the BOM.
repeated Definition definitions = 15;
// Details a specific attribution of data within the BOM to a contributing entity or process.
repeated Citation citations = 16;
}

enum Classification {
Expand Down Expand Up @@ -331,6 +333,8 @@ enum ExternalReferenceType {
EXTERNAL_REFERENCE_TYPE_PATENT_FAMILY = 44;
// References assertions made regarding patents associated with a component or service. Assertions distinguish between ownership, licensing, and other relevant interactions with patents.
EXTERNAL_REFERENCE_TYPE_PATENT_ASSERTION = 45;
// A reference to external citations applicable to the object identified by this BOM entry or the BOM itself. When used with a BOM-Link, this allows offloading citations into a separate CycloneDX BOM.
EXTERNAL_REFERENCE_TYPE_CITATION = 46;
}

enum HashAlg {
Expand Down Expand Up @@ -2613,3 +2617,19 @@ enum PatentAssertionType {
// The patent or patent family is being used under a research or evaluation license.
PATENT_ASSERTION_TYPE_RESEARCH_OR_EVALUATION = 8;
}

// At least one of the "attributedTo" or "process" elements must be present. This is equivalent to the "anyOf" constraint in the JSON schema.
message Citation {
// Optional unique identifier for the citation
optional string bom_ref = 1;
// One or more JSON Pointers(https://datatracker.ietf.org/doc/html/rfc6901) identifying the BOM fields to which the attribution applies.
repeated string pointer = 2;
// Timestamp when the attribution was made or the information was supplied.
google.protobuf.Timestamp timestamp = 3;
// The `bom-ref` of an object, such as a component, service, organisational entity, or person that supplied the cited information.
optional string attributed_to = 4;
// An optional `bom-ref` to a process (such as a formula, workflow, task, or step) defined in the `formulation` section that executed or generated the attributed data. At least one of the "attributedTo" or "process" elements must be present.
optional string process = 5;
// An optional description or comment about the context or quality of the data attribution. At least one of the "attributedTo" or "process" elements must be present.
optional string note = 6;
}
63 changes: 63 additions & 0 deletions schema/bom-1.7.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,13 @@
}
}
},
"citations": {
"type": "array",
"items": {"$ref": "#/definitions/citation"},
"uniqueItems": true,
"title": "Citations",
"description": "A list of attributions indicating which entity supplied information for specific fields within the BOM."
},
"properties": {
"type": "array",
"title": "Properties",
Expand Down Expand Up @@ -1899,6 +1906,7 @@
"patent",
"patent-family",
"patent-assertion",
"citation",
"other"
],
"meta:enum": {
Expand Down Expand Up @@ -1947,6 +1955,7 @@
"patent": "References information about patents which may be defined in human-readable documents or in machine-readable formats such as CycloneDX or ST.96. For detailed patent information or to reference the information provided directly by patent offices, it is recommended to leverage standards from the World Intellectual Property Organization (WIPO) such as [ST.96](https://www.wipo.int/standards/en/st96).",
"patent-family": "References information about a patent family which may be defined in human-readable documents or in machine-readable formats such as CycloneDX or ST.96. A patent family is a group of related patent applications or granted patents that cover the same or similar invention. For detailed patent family information or to reference the information provided directly by patent offices, it is recommended to leverage standards from the World Intellectual Property Organization (WIPO) such as [ST.96](https://www.wipo.int/standards/en/st96).",
"patent-assertion" : "References assertions made regarding patents associated with a component or service. Assertions distinguish between ownership, licensing, and other relevant interactions with patents.",
"citation": "A reference to external citations applicable to the object identified by this BOM entry or the BOM itself. When used with a BOM-Link, this allows offloading citations into a separate CycloneDX BOM.",
"other": "Use this if no other types accurately describe the purpose of the external reference."
}
},
Expand Down Expand Up @@ -6104,6 +6113,60 @@
"$ref": "#/definitions/patentFilingDate"
}
}
},
"citation": {
"type": "object",
"title": "Citation",
"description": "Details a specific attribution of data within the BOM to a contributing entity or process.",
"additionalProperties": false,
"properties": {
"bom-ref": {
"$ref": "#/definitions/refType",
"title": "BOM Reference"
},
"attributedTo": {
"$ref": "#/definitions/refLinkType",
"title": "Attributed To",
"description": "The `bom-ref` of an object, such as a component, service, organisational entity, or person that supplied the cited information."
},
"pointers": {
"type": "array",
"items": {
"type": "string",
"title": "Field Reference",
"description": "A [JSON Pointer](https://datatracker.ietf.org/doc/html/rfc6901) identifying the BOM field to which the attribution applies. Users of other serialisation formats (e.g. XML) shall use the JSON Pointer format to ensure consistent field referencing across representations."
},
"minItems": 1,
"title": "Field References",
"description": "One or more [JSON Pointers](https://datatracker.ietf.org/doc/html/rfc6901) identifying the BOM fields to which the attribution applies."
},
"timestamp": {
"type": "string",
"format": "date-time",
"title": "Timestamp",
"description": "The date and time when the attribution was made or the information was supplied."
},
"process": {
"$ref": "#/definitions/refLinkType",
"title": "Process Reference",
"description": "An optional `bom-ref` to a process (such as a formula, workflow, task, or step) defined in the `formulation` section that executed or generated the attributed data."
},
"note": {
"type": "string",
"title": "Note",
"description": "An optional description or comment about the context or quality of the data attribution."
},
"signature": {
"$ref": "#/definitions/signature",
"title": "Signature",
"description": "An optional digital signature verifying the authenticity or integrity of the attribution."
}
},
"required": ["pointers", "timestamp"],
"anyOf": [
{ "required": ["attributedTo"] },
{ "required": ["process"] }
]
}
}
}
109 changes: 109 additions & 0 deletions schema/bom-1.7.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -1782,6 +1782,11 @@ limitations under the License.
<xs:documentation>References assertions made regarding patents associated with a component or service. Assertions distinguish between ownership, licensing, and other relevant interactions with patents.</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="citation">
<xs:annotation>
<xs:documentation>A reference to external citations applicable to the object identified by this BOM entry or the BOM itself. When used with a BOM-Link, this allows offloading citations into a separate CycloneDX BOM.</xs:documentation>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="other">
<xs:annotation>
<xs:documentation>Use this if no other types accurately describe the purpose of the external reference</xs:documentation>
Expand Down Expand Up @@ -8856,6 +8861,105 @@ limitations under the License.
</xs:sequence>
</xs:complexType>

<xs:complexType name="citationsType">
<xs:sequence>
<xs:element name="citation" type="bom:citationType" minOccurs="1" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>
Details a specific attribution of data within the BOM to a contributing entity or process.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>

<xs:complexType name="citationType">
<xs:annotation>
<xs:documentation>
At least one of the "attributedTo" or "process" elements must be present. This is equivalent to the "anyOf" constraint in the JSON schema.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="pointers" minOccurs="1" maxOccurs="1">
<xs:annotation>
<xs:documentation>
One or more JSON Pointers(https://datatracker.ietf.org/doc/html/rfc6901) identifying the BOM fields to which the attribution applies.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="pointer" type="xs:string" minOccurs="1" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>
A JSON Pointer(https://datatracker.ietf.org/doc/html/rfc6901) identifying the BOM field to which the attribution applies. Users of other serialisation formats (e.g. XML) shall use the JSON Pointer format to ensure consistent field referencing across representations.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="timestamp" type="xs:dateTime" minOccurs="1" maxOccurs="1">
<xs:annotation>
<xs:documentation>
The date and time when the attribution was made or the information was supplied.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="attributedTo" type="bom:refLinkType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>
The `bom-ref` of an object, such as a component, service, organisational entity, or person that supplied the cited information.
At least one of the "attributedTo" or "process" elements must be present.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="process" type="bom:refLinkType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>
The `bom-ref` to a process (such as a formula, workflow, task, or step) defined in the `formulation` section that executed or generated the attributed data.
At least one of the "attributedTo" or "process" elements must be present.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="note" type="xs:string" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>
An optional description or comment about the context or quality of the data attribution.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>
Allows any undeclared elements as long as the elements are placed in a different namespace.
</xs:documentation>
</xs:annotation>
</xs:any>
</xs:sequence>
<!-- Attention:
This would be formal, if the support for XSD1.1's `assert` was properly implemented in validators and tools digesting XML.
<xs:assert vc:minVersion="1.1"
id="requires_attributedTo_or_process"
test="attributedTo or process">
At least one of the "attributedTo" or "process" elements must be present.
</xs:assert>
/-->
<xs:attribute name="bom-ref" type="bom:refType" use="optional">
<xs:annotation>
<xs:documentation>
An optional identifier which can be used to reference the object elsewhere in the BOM.
Uniqueness is enforced within all elements and children of the root-level bom element.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:anyAttribute namespace="##other" processContents="lax">
<xs:annotation>
<xs:documentation>User-defined attributes may be used on this element as long as they
do not have the same name as an existing attribute used by the schema.</xs:documentation>
</xs:annotation>
</xs:anyAttribute>
</xs:complexType>

<xs:element name="bom">
<xs:complexType>
<xs:sequence>
Expand Down Expand Up @@ -8937,6 +9041,11 @@ limitations under the License.
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="citations" type="bom:citationsType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>A list of attributions indicating which entity supplied information for specific fields within the BOM.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>
Expand Down
33 changes: 33 additions & 0 deletions tools/src/test/resources/1.7/invalid-citations-1.7.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"version": 1,
"metadata": {
"timestamp": "2025-05-01T14:23:00Z"
},
"components": [
{
"type": "library",
"bom-ref": "component-1",
"name": "example-lib",
"version": "1.2.3",
"licenses": [
{
"license": {
"id": "Apache-2.0"
}
}
]
}
],
"citations": [
{
"bom-ref": "citation-1",
"pointers": [ "/components/0/name" ],
"timestamp": "2025-05-01T14:00:00Z",
"note": "Should have at least one of the following property sets: property 'attributedTo' or property 'process'"
}
]
}
88 changes: 88 additions & 0 deletions tools/src/test/resources/1.7/invalid-citations-1.7.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.7"
serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79"
version="1">
<metadata>
<timestamp>2025-05-01T14:23:00Z</timestamp>
<authors>
<author bom-ref="person-1">
<name>Alice Example</name>
<email>[email protected]</email>
</author>
</authors>
</metadata>
<components>
<component type="library" bom-ref="component-1">
<name>example-lib</name>
<version>1.2.3</version>
<licenses>
<license>
<id>Apache-2.0</id>
</license>
</licenses>
</component>
</components>
<formulation>
<formula bom-ref="formula-1">
<components>
<component type="application" bom-ref="scan-tool-1">
<name>My Scan Tool</name>
</component>
</components>
<workflows>
<workflow bom-ref="workflow-1">
<uid>259bae74-5ec4-4de8-9386-c91b1f7719b8</uid>
<name>My workflow</name>
<tasks>
<task bom-ref="task-license-scan">
<uid>6d75f8d6-a008-41cf-8b65-c4129fc249f9</uid>
<description>License scan of the source files using OpenSourceScanner v2.1</description>
<taskTypes>
<taskType>scan</taskType>
</taskTypes>
</task>
<task bom-ref="task-license-scan-2">
<uid>dfc0268a-89cb-4823-bb88-84115a06b64d</uid>
<description>License scan of the source files using [REDACTED]</description>
<taskTypes>
<taskType>scan</taskType>
</taskTypes>
</task>
</tasks>
<taskTypes>
<taskType>scan</taskType>
</taskTypes>
</workflow>
</workflows>
</formula>
</formulation>
<citations>
<!-- spec-requirement that is not formalized in the XSD:
<citation bom-ref="citation-1">
<pointers>
<pointer>/components/0/name</pointer>
</pointers>
<timestamp>2025-05-01T14:00:00Z</timestamp>
<note>Should have at least one of the following children 'attributedTo' or 'process'</note>
</citation>
-->
<citation bom-ref="citation-2">
<pointers>
<pointer>/components/0/licenses/0/license/id</pointer>
</pointers>
<timestamp>2025-05-01T14:05:00Z</timestamp>
<attributedTo>person-1</attributedTo>
<attributedTo>scan-tool-1</attributedTo>
<note>Should have at max one 'attributedTo'</note>
</citation>
<citation bom-ref="citation-3">
<pointers>
<pointer>/components/0/licenses/0/license/id</pointer>
</pointers>
<timestamp>2025-05-01T14:05:00Z</timestamp>
<process>task-license-scan</process>
<process>task-license-scan-2</process>
<note>Should have at max one 'process'</note>
</citation>
</citations>
</bom>
Loading