diff --git a/schema/bom-1.7.proto b/schema/bom-1.7.proto index b84f2be5..44d2ea74 100644 --- a/schema/bom-1.7.proto +++ b/schema/bom-1.7.proto @@ -43,7 +43,7 @@ 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. + // A collection of attributions indicating which entity supplied information for specific fields within the BOM. repeated Citation citations = 16; } @@ -2618,20 +2618,38 @@ enum PatentAssertionType { 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. +// Details a specific attribution of data within the BOM to a contributing entity or process. message Citation { + message Pointers { + // Users of other serialisation formats (e.g. XML) shall use the JSON Pointer format to ensure consistent field referencing across representations. + // Must contain at least 1 item. + repeated string pointer = 1; + } + message Expressions { + // Specifies a path expression used to locate a value within a BOM. The expression syntax shall conform to the format of the BOM's serialisation. + // Use [JSONPath](https://datatracker.ietf.org/doc/html/rfc9535) for JSON, [XPath](https://www.w3.org/TR/xpath/) for XML, and default to JSONPath for Protocol Buffers unless otherwise specified. + // Implementers shall ensure the expression is valid within the context of the applicable serialisation format. Use either "pointer" or "expression" but not both in this object. + // Must contain at least 1 item. + repeated string expression = 1; + } + // 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; - // Specifies a path expression used to locate a value within a BOM. The expression syntax shall conform to the format of the BOM's serialisation. Use [JSONPath](https://datatracker.ietf.org/doc/html/rfc9535) for JSON, [XPath](https://www.w3.org/TR/xpath/) for XML, and default to JSONPath for Protocol Buffers unless otherwise specified. Implementers shall ensure the expression is valid within the context of the applicable serialisation format. Use either "pointer" or "expression" but not both in this object. - repeated string expression = 3; + // Exactly one of the "pointers" or "expressions" elements must be present. + oneof target { + // One or more JSON Pointers(https://datatracker.ietf.org/doc/html/rfc6901) identifying the BOM fields to which the attribution applies. + Pointers pointers = 2; + // One or more path expressions used to locate values within a BOM. + Expressions expressions = 3; + } // Timestamp when the attribution was made or the information was supplied. google.protobuf.Timestamp timestamp = 4; - // The `bom-ref` of an object, such as a component, service, organisational entity, or person that supplied the cited information. + // The `bom-ref` of an object, such as a component, service, tool, organisational entity, or person that supplied the cited information. + // At least one of the "attributed_to" or "process" elements must be present. optional string attributed_to = 5; - // 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. + // 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 "attributed_to" or "process" elements must be present. optional string process = 6; - // 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. + // An optional description or comment about the context or quality of the data attribution. optional string note = 7; } diff --git a/schema/bom-1.7.schema.json b/schema/bom-1.7.schema.json index 50742f25..a682e76c 100644 --- a/schema/bom-1.7.schema.json +++ b/schema/bom-1.7.schema.json @@ -532,7 +532,7 @@ "items": {"$ref": "#/definitions/citation"}, "uniqueItems": true, "title": "Citations", - "description": "A list of attributions indicating which entity supplied information for specific fields within the BOM." + "description": "A collection of attributions indicating which entity supplied information for specific fields within the BOM." }, "properties": { "type": "array", @@ -6125,32 +6125,27 @@ "$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." + "description": "A [JSON Pointer](https://datatracker.ietf.org/doc/html/rfc6901) identifying the BOM field to which the attribution applies.\nUsers 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." + "description": "One or more [JSON Pointers](https://datatracker.ietf.org/doc/html/rfc6901) identifying the BOM fields to which the attribution applies.\nExactly one of the \"pointers\" or \"expressions\" elements must be present." }, "expressions": { "type": "array", "items": { "type": "string", "title": "Path Expression", - "description": "Specifies a path expression used to locate a value within a BOM. The expression syntax shall conform to the format of the BOM's serialisation. Use [JSONPath](https://datatracker.ietf.org/doc/html/rfc9535) for JSON, [XPath](https://www.w3.org/TR/xpath/) for XML, and default to JSONPath for Protocol Buffers unless otherwise specified. Implementers shall ensure the expression is valid within the context of the applicable serialisation format." + "description": "Specifies a path expression used to locate a value within a BOM. The expression syntax shall conform to the format of the BOM's serialisation.\nUse [JSONPath](https://datatracker.ietf.org/doc/html/rfc9535) for JSON, [XPath](https://www.w3.org/TR/xpath/) for XML, and default to JSONPath for Protocol Buffers unless otherwise specified.\nImplementers shall ensure the expression is valid within the context of the applicable serialisation format." }, "minItems": 1, "title": "Path Expressions", - "description": "One or more path expressions used to locate values within a BOM." + "description": "One or more path expressions used to locate values within a BOM.\nExactly one of the \"pointers\" or \"expressions\" elements must be present." }, "timestamp": { "type": "string", @@ -6158,10 +6153,15 @@ "title": "Timestamp", "description": "The date and time when the attribution was made or the information was supplied." }, + "attributedTo": { + "$ref": "#/definitions/refLinkType", + "title": "Attributed To", + "description": "The `bom-ref` of an object, such as a component, service, tool, organisational entity, or person that supplied the cited information.\nAt least one of the \"attributedTo\" or \"process\" elements must be present." + }, "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." + "description": "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.\nAt least one of the \"attributedTo\" or \"process\" elements must be present." }, "note": { "type": "string", diff --git a/schema/bom-1.7.xsd b/schema/bom-1.7.xsd index b93dc949..9f8682c9 100644 --- a/schema/bom-1.7.xsd +++ b/schema/bom-1.7.xsd @@ -8883,10 +8883,15 @@ limitations under the License. - At least one of the "attributedTo" or "process" elements must be present. This is equivalent to the "anyOf" constraint in the JSON schema. + Details a specific attribution of data within the BOM to a contributing entity or process. + + + Exactly one of the "pointers" or "expressions" elements must be present. + + @@ -8899,7 +8904,8 @@ limitations under the License. - 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. + 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. @@ -8917,7 +8923,9 @@ limitations under the License. - Specifies a path expression used to locate a value within a BOM. The expression syntax shall conform to the format of the BOM's serialisation. Use [JSONPath](https://datatracker.ietf.org/doc/html/rfc9535) for JSON, [XPath](https://www.w3.org/TR/xpath/) for XML, and default to JSONPath for Protocol Buffers unless otherwise specified. Implementers shall ensure the expression is valid within the context of the applicable serialisation format. + Specifies a path expression used to locate a value within a BOM. The expression syntax shall conform to the format of the BOM's serialisation. + Use [JSONPath](https://datatracker.ietf.org/doc/html/rfc9535) for JSON, [XPath](https://www.w3.org/TR/xpath/) for XML, and default to JSONPath for Protocol Buffers unless otherwise specified. + Implementers shall ensure the expression is valid within the context of the applicable serialisation format. @@ -8935,7 +8943,7 @@ limitations under the License. - The `bom-ref` of an object, such as a component, service, organisational entity, or person that supplied the cited information. + The `bom-ref` of an object, such as a component, service, tool, organisational entity, or person that supplied the cited information. At least one of the "attributedTo" or "process" elements must be present. @@ -9073,7 +9081,7 @@ limitations under the License. - A list of attributions indicating which entity supplied information for specific fields within the BOM. + A collection of attributions indicating which entity supplied information for specific fields within the BOM. diff --git a/tools/src/test/resources/1.7/invalid-citations-1.7.json b/tools/src/test/resources/1.7/invalid-citations-1.7.json index 3ab39c44..d93cb908 100644 --- a/tools/src/test/resources/1.7/invalid-citations-1.7.json +++ b/tools/src/test/resources/1.7/invalid-citations-1.7.json @@ -32,7 +32,7 @@ { "bom-ref": "citation-1", "pointers": [ "/components/0/name" ], - "expressions": [ "expression here" ], + "expressions": [ "$..[?(@.bom-ref=='component-1')].version" ], "timestamp": "2025-05-01T14:00:00Z", "note": "Should not have both a pointer and expression." } diff --git a/tools/src/test/resources/1.7/invalid-citations-1.7.textproto b/tools/src/test/resources/1.7/invalid-citations-1.7.textproto new file mode 100644 index 00000000..4617b8f0 --- /dev/null +++ b/tools/src/test/resources/1.7/invalid-citations-1.7.textproto @@ -0,0 +1,48 @@ +# proto-file: schema/bom-1.7.proto +# proto-message: Bom + +spec_version: "1.7" +serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" +version: 1 + +metadata { + timestamp { + seconds: 1754424907 + nanos: 0 + } +} + +components { + type: CLASSIFICATION_LIBRARY + bom_ref: "component-1" + name: "example-lib" + version: "1.2.3" + licenses { + license { + id: "Apache-2.0" + } + } +} + +## !! NO formal check possible +#citations { +# bom_ref: "citation-1" +# pointers: { pointer: "/components/0/name" } +# timestamp { +# seconds: 1746108000 +# nanos: 0 +# } +# note: "Should have at least one of the following property sets: property 'attributedTo' or property 'process'" +#} + + +citations { + bom_ref: "citation-1" + pointers: { pointer: "/components/0/name" } + expressions: { expression: "$..[?(bom_ref=='component-1')].version" } + timestamp { + seconds: 1746108000 + nanos: 0 + } + note: "Should not have both a pointer and expression." +} diff --git a/tools/src/test/resources/1.7/invalid-citations-1.7.xml b/tools/src/test/resources/1.7/invalid-citations-1.7.xml index cd09406d..55962ab3 100644 --- a/tools/src/test/resources/1.7/invalid-citations-1.7.xml +++ b/tools/src/test/resources/1.7/invalid-citations-1.7.xml @@ -89,7 +89,7 @@ /components/0/licenses/0/license/id - expression here + //*[@bom-ref='component-1']/version 2025-05-01T14:05:00Z task-license-scan diff --git a/tools/src/test/resources/1.7/valid-citations-1.7.json b/tools/src/test/resources/1.7/valid-citations-1.7.json index d46185b9..50a1dddf 100644 --- a/tools/src/test/resources/1.7/valid-citations-1.7.json +++ b/tools/src/test/resources/1.7/valid-citations-1.7.json @@ -46,6 +46,13 @@ }, { "bom-ref": "citation-3", + "expressions": [ "$..[?(@.bom-ref=='component-1')].version" ], + "timestamp": "2025-05-01T14:00:00Z", + "process": "task-license-scan", + "note": "Semi-manually entered by Alice Example - with `process`" + }, + { + "bom-ref": "citation-4", "expressions": [ "$.components[*].licenses[*].license.id" ], "timestamp": "2025-05-01T14:05:00Z", "attributedTo": "scan-tool-1", diff --git a/tools/src/test/resources/1.7/valid-citations-1.7.textproto b/tools/src/test/resources/1.7/valid-citations-1.7.textproto index 24b2f9c7..09d7c072 100644 --- a/tools/src/test/resources/1.7/valid-citations-1.7.textproto +++ b/tools/src/test/resources/1.7/valid-citations-1.7.textproto @@ -32,7 +32,7 @@ components { citations [ { bom_ref: "citation-1" - pointer: "/components/0/name" + pointers: { pointer: "/components/0/name" } timestamp: { seconds: 1746108000 nanos: 0 @@ -41,8 +41,8 @@ citations [ note: "Manually entered by Alice Example" }, { - bom_ref: "citation-1" - pointer: "/components/0/name" + bom_ref: "citation-2" + pointers: { pointer: "/components/0/name" } timestamp: { seconds: 1746108000 nanos: 0 @@ -52,7 +52,17 @@ citations [ }, { bom_ref: "citation-3" - expression: "$.components[*].licenses[*].license.id" + expressions: { expression: "$..[?(bom_ref=='component-1')].version" } + timestamp: { + seconds: 1746108000 + nanos: 0 + } + process: "task-license-scan" + note: "Semi-manually entered by Alice Example - with `process`" + }, + { + bom_ref: "citation-4" + expressions: { expression: "$.components[*].licenses[*].license.id" } timestamp: { seconds: 1746108000 nanos: 0 diff --git a/tools/src/test/resources/1.7/valid-citations-1.7.xml b/tools/src/test/resources/1.7/valid-citations-1.7.xml index addc8190..599784ba 100644 --- a/tools/src/test/resources/1.7/valid-citations-1.7.xml +++ b/tools/src/test/resources/1.7/valid-citations-1.7.xml @@ -67,6 +67,14 @@ Semi-manually entered by Alice Example - with `process` + + //*[@bom-ref='component-1']/version + + 2025-05-01T14:00:00Z + person-1 + Semi-manually entered by Alice Example - with `process` + + /components/component/licenses/license/id