CycloneDX / CycloneDX/specification
[FEATURE]: internal component provenance tracking
- 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
Assessment
This issue has not been assessed yet.