specification icon indicating copy to clipboard operation
specification copied to clipboard

Support more relationship types

Open dn-scribe opened this issue 2 years ago • 5 comments

Hi, Currently, CycloneDX supports only relationships of parts in a system - dependencies and compositions. There is a need express several types of relationships. A thorough list of examples can be found in the Chapter 11 of the SPDX spec.

An example: Component A is documented in component C and also Component B is documented in component C, where component C is a part of the software BOM'd (C is "installation_manual.pdf").

Component A is documented in document C, and also B is documented in document C, but document C is an external document - not part of the SBOM. So it is does not make sense to add a component C object (because it is not really a component).

Suggestions:

  1. Add to the existing relationship objects (dependencies and compositions) also a properties object - so application specific relationships can describe the relationship. In the first example - one would create a property: "name":"relationship type" "value":"documentation" Even better to add an optional name field to the dependencies and composition objects.

  2. Add a generic relationships object, which will be populated by any relationship imagined. In such an object I would recommend defining at least a relationship name field.

Thanks

dn-scribe avatar Mar 04 '22 07:03 dn-scribe

SPDX, strictly speaking, is not a bill of materials format, it is a Body of Evidence (BOE) file format. SPDX currently cannot describe what something is, only what something can be based on an undefined belief system. This is being resolved in SPDX v2.3 and v3.0, but understanding that SPDX was designed as a BOE format is important to understand why most SPDX practitioners falsely conclude that CycloneDX has a limited number of relationships.

For example, this article is completely false with respect to the assumption that SPDX has a rich set of relationships and CycloneDX does not. There simply is no reality in the statements made.

The difference is that relationships in SPDX are explicit, as evidence itself needs to be explicit. There are only three explicit relationships in CycloneDX which include assemblies, dependencies/affects, and compositions. These relationship types are explicit because they affect inventory, the primary purpose for a BOM. All other relationships are expressed in BOM semantics.

For example:

Component A is documented in component C and also Component B is documented in component C, where component C is a part of the software BOM'd (C is "installation_manual.pdf").

To represent this in CycloneDX you would simply have an external reference of type documentation specified on Component A and Component B, both of which will reference Component C in the current BOM. Component C would then have an external reference of type documentation pointing to installation_manual.pdf.

Component A is documented in document C, and also B is documented in document C, but document C is an external document - not part of the SBOM. So it is does not make sense to add a component C object (because it is not really a component).

You would represent this the same was as above. To make this type of reference, use the format:

urn:cdx:serialNumber/version#bom-ref

The only difference between the two use cases is the serial number of the bom. In the first use case, the serial number (and version) are the same, whereas in the second example they are different.

Refer to https://cyclonedx.org/capabilities/bomlink/ for more information.

Not all SPDX relationships will be supported by CycloneDX, so it's important to understand the use cases desired.

Suggestions:

Add to the existing relationship objects (dependencies and compositions) also a properties object - so application specific > relationships can describe the relationship. In the first example - one would create a property: "name":"relationship type" "value":"documentation" Even better to add an optional name field to the dependencies and composition objects.

I don't think we'll ever have a relationships object as CycloneDX relationships are expressed in BOM semantics and with context, which SPDX does not support.

Add a generic relationships object, which will be populated by any relationship imagined. In such an object I would recommend defining at least a relationship name field.

The external reference type of other combined with bomlink syntax achieves this today.

I think we need to better understand what specific SPDX relationships are desired and see if there's a way to express them in CycloneDX or not. Note, there will be some additional relationships coming in a future version of the spec when we introduce support for formulation and some of the other more advanced use cases. But again, the relationships with have BOM semantics and will be in context with the data - not external to the data.

stevespringett avatar Mar 04 '22 16:03 stevespringett

Thank you for the elaborated answer. A few follow-ups:

Regarding the technical aspect of the issue:

To represent this in CycloneDX you would simply have an external reference of type documentation specified on Component A and Component B, both of which will reference Component C in the current BOM. Component C would then have an external reference of type documentation pointing to installation_manual.pdf.

Could you please clarify how would the component C object look like? Did you mean that component C is the component "installation_manual.pdf" This is a viable solution, but it has the drawbacks that apparently led the CycloneDX to represent dependencies as separate reference tables.

I don't think we'll ever have a relationships object as CycloneDX relationships are expressed in BOM semantics and with context, which SPDX does not support.

What I meant was to add a properties object to existing assemblies, dependencies and compositions. Does it make sense?

Regarding the CycloneDX <> SPDX issues:

I did not understand the distinction you tried to make between CycloneDX and SPDX by categorizing SPDX as BOE. If you could reference me to to some explanation (both regarding the inherent differences between CycloneDX and SPDX, and BOE vs BOM) it would be great.

You pointed to a specific SPDX clause:

An External Reference allows a Package to reference an external source of additional information, metadata, enumerations, asset identifiers, or downloadable content believed to be relevant to the Package.

As I understand, "believed to be relevant" is simply a way to grant the SBOM creator the authority to decide what is relevant; one will think that to know that gcc came from the debian package manager is relevant, and someone else - not. So, I'm not sure I got your take on SPDX only "describing what things could be based on some undefined belief system". CycloneDX give the exact same authority to SBOM creators - one could decide what information is relevant to his SBOMs, and this will be based on his "requirements", maybe "anticipated-future-requirements" which are exactly SPDX's "beliefs". What do I miss?

dn-scribe avatar Mar 06 '22 07:03 dn-scribe

Component A is documented in component C and also Component B is documented in component C, where component C is a part of the software BOM'd (C is "installation_manual.pdf").

Pseudo-concrete example:


{
  "bomFormat": "CycloneDX",
  "specVersion": "1.4",
  "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
  "version": 1,
  "components": [
    {
      "bom-ref": "component-a",
      "name": "Component A",
      "externalReferences": [
        {
          "type": "documentation",
          "url": "urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#component-c"
        }
      ]
    },
    {
      "bom-ref": "component-b",
      "name": "Component B",
      "externalReferences": [
        {
          "type": "documentation",
          "url": "urn:cdx:3e671687-395b-41f5-a30f-a58921a69b79/1#component-c"
        }
      ]
    },
    {
      "bom-ref": "component-c",
      "name": "Component C",
      "externalReferences": [
        {
          "type": "documentation",
          "url": "https://example.com/docs/installation_manual.pdf"
        }
      ]
    }
  ]
}

Component A is documented in document C, and also B is documented in document C, but document C is an external document - not part of the SBOM. So it is does not make sense to add a component C object (because it is not really a component).

Pseudo-concrete example:


{
  "bomFormat": "CycloneDX",
  "specVersion": "1.4",
  "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
  "version": 1,
  "components": [
    {
      "bom-ref": "component-a",
      "name": "Component A",
      "externalReferences": [
        {
          "type": "documentation",
          "url": "urn:cdx:e869fa49-4870-4d07-bfa3-24b41197b1e3/1#component-c"
        }
      ]
    },
    {
      "bom-ref": "component-b",
      "name": "Component B",
      "externalReferences": [
        {
          "type": "documentation",
          "url": "urn:cdx:e869fa49-4870-4d07-bfa3-24b41197b1e3/1#component-c"
        }
      ]
    }
  ]
}

Where e869fa49-4870-4d07-bfa3-24b41197b1e3 is the serialNumber for the CycloneDX BOM for Component C.

I have not tested the examples for validity, they were free-form created, but I think it provides enough to go on.

Please see BOM-Link for more information about how the cdx urn works. I think you can do this basic thing for almost every URL (they're actually URI's) in the CycloneDX spec, including every external reference type.


So this brings us back to the question, what other relationship types are desired?

stevespringett avatar May 02 '22 04:05 stevespringett

Following up. Are there any concrete examples of relationship types that you'd like CycloneDX to support that it doesn't already?

stevespringett avatar Jan 17 '23 20:01 stevespringett

A few examples to relationships that could be useful:

  1. component C is a dependency of B which is a dependency of A. it could be useful to have the relation "transive (or indirect) dependency", and C would be a transitive dependency of A. Of course this info can be convayed by two dependency objects - one tieing B to A, and one tieing C to b. Nevertheless, it is convenient, and sometimes enough to simply state direct and indirect dependencies.
  2. component A is a "commit component" representing a commit (branch info, hash, message etc.) , and a set of "file components" have the relation "were modified in" with commit A.
  3. Suppose docker layer info is part of the sbom described in a "layer component". In this case the packages of the layer could be dependencies or assemblies of the layer component. In order to convey the information about the order of the layers in the image, a relationship of "after", or "linked to" could enable representing such a list.
  4. Suppose a project has devDependecies. To convay this info it would be useful to have a "depenency table" of type : "devDependencies". Similar examples are java-felix <Import-Package> and <Export-Package> marked packages (see here).
  5. A "downloaded by" relationship could convey provenance info about components that were downloaded by a specific tool (curl, wget) or process.

The external reference is a way to link a component to anything else, but using it to convay any relationship, though can be done, is not intuitive and will require complex implementations (e.g. scanning all components to create a relationship table).

In the more conceptual level, as I review the above conversation, I think one can have two takes on the CycloneDX format:

  1. A format to describe the BOM, leaving out all other "supply-chain" or "build process" info. I believe this was the goal of creating it.
  2. A format to package supply-chain data. Some of the examples above clearly fall in this category and not in the "ingredient-list" category.

I think the industry has taken the second route and is using CycloneDX in a broad sense; once an sbom is generated it is convenient to have it contain whatever is needed, instead of generating and handling multiple documents; It does not make sense to create and handle both CycloneDX and SPDX documents just to convay some relation info that is hard to express in CycloneDX.

So to wrap it up, I still see the usefullness of a defining a relationship type, where specific types would be standardizes ("depends on").

dn-scribe avatar Jan 18 '23 06:01 dn-scribe