CycloneDX / CycloneDX/specification

[FEATURE]: internal component provenance tracking

Open
#807 1 comment 0 reactions 0 assignees View on GitHub
proposed core enhancement
Dominant language
XSLT
Stars
547
Forks
93
Avg merge
7h 11m
Merged PRs (30d)
37

Description

## Describe the feature

Embedded Linux build-systems such as [Buildroot](https://buildroot.org/), [Yocto](https://www.yoctoproject.org/), [OpenWRT](https://openwrt.org/) and [Debian](https://www.debian.org/) all have their own definition of a an 'external layer':

* Buildroot has 'externals'
* OpenWRT has 'feeds'
* Yocto has 'layers'
* Debian has 'PPA'

These external layers act as extensions of the 'parent' build-system. There are a way to developers to add their own component/3rd party software to the parent build-system.

Let's say you want to create an SBOM of a debian image that has `docker`. The CycloneDX SBOM is the representation of the final your operating system and components are the packages present on that debian image. Docker is supplied by a custom `ppa` (https://docs.docker.com/engine/install/debian/#install-using-the-repository).
I want to trace from which `ppa` the component 'docker' is pulled from. For this I need a way to reference from the `component` level the origin of the component.

## Possible solutions

To reference all those external layers, they can be part of the 'top-level' `metadata:component` entry.

The following example re-use the debian + docker example. It reference the 'core' repositories that constitue the end product alongside the external ones.

```json
{
"metadata": {
"type": "firmware",
"bom-ref": "",
"name": "",
"version": "",
"components": [
{
"type": "firmware", // <-- No proper 'type' exists I think.
"bom-ref": "trixie-free",
"name": "trixie-free",
},
{
"type": "firmware",
"bom-ref": "trixie-non-free",
"name": "trixie-non-free",
},
{
"type": "firmware",
"bom-ref": "docker-ppa",
"name": "docker-ppa",
},
]
}
...
}
```

This might not be the correct way to reference this hierarchy. Any pointers are welcome.

### Solution 1. Use `distribution-intake`

The most suitable description I can find from the CycloneDX spec for this problem is the `distribution-intake` from the `components:externalReferences`:

> The location where a component was published to. This is often the same as "distribution" but may also include specialized publishing processes that act as an intermediary.

```json
"components: [
{
"name": "docker",
"externalReferences": [
{
"type": "distribution-intake",
"url": "...."
}
]
}
...
]
```

* Issue

The 'reference' here is not external. PPA or external layers don't necessarly have an url. BomLink could be an alternative but we want to only provide a single `bom-ref` which the `externalReference` doesn't allow.

### Solution 2. Use recursive components hierarchy

Another way to see the problem is to actually group the components as children of the PPA that provides them.

```json
"components: [
{
"name": "docker-ppa",
"components": [
{
"type": "application",
"name": "docker"
}
]
}
...
]
```

* Issue

Makes the SBOM more difficult to parse and I would expect the packages to be the most important components, not the PPA.

### Solution 3. custom property

If there is no proper way to reference this. Maybe create a new `provenance` property that would reference internally the layer/PPA.

```json
"components: [
{
"name": "docker",
"provenance": "docker-ppa"
}
...
]
```

## Additional context

* https://github.com/CycloneDX/specification/discussions/720

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.