Software Bill-of-Materials (SBOM)¶
Eine Software Bill-of-Materials (SBOM) ist ein Dokument zum Austausch von Informationen über Software und deren Zusammensetzung. Dieses Format wird vor allem im Sicherheitsbereich verwendet, um Software und ihre Abhängigkeiten mithilfe von Schwachstellendatenbanken wie CVE und OSV auf Schwachstellen zu überprüfen. Das vom CPython-Projekt verwendete SBOM-Format ist SPDX, das bei Bedarf in andere Formate konvertiert werden kann. Die SBOM-Datei für die in CPython enthaltenen Abhängigkeiten wird unter Misc/sbom.spdx.json verwaltet. Die Datei wird erstellt mit Tools/build/generate_sbom.py.
SBOM-Datei erstellen¶
… mit uv¶
uv bietet eine einfache Möglichkeit, eine SBOM-Datei im Format CycloneDX v1.5 zu erstellen mit:
$ uv export --format='cyclonedx1.5' > sbom.cdx.json
Die Datei enthält jedoch nur sehr rudimentäre Angaben, z. B. für cusy.tasks:
"component": {
"type": "library",
"bom-ref": "cusy-tasks-1@26.2.0",
"name": "cusy-tasks",
"version": "26.2.0",
"properties": [
{
"name": "uv:package:is_project_root",
"value": "true"
}
]
}
Mit uv export --all-groups --format='cyclonedx1.5' > sbom.cdx.json könnt
ihr auch alle Dependency-Groups in die SBOM-Datei übernehmen.
… mit CycloneDX Python¶
Deutlich umfangreicher ist die Ausgabe von CycloneDX Python:
{
"bom-ref": "cusy-tasks==26.2.0",
"description": "",
"externalReferences": [
{
"comment": "PackageSource: Local",
"type": "distribution",
"url": "file:///Users/veit/cusy/prj/cusy.tasks"
},
{
"comment": "from packaging metadata Project-URL: Documentation",
"type": "documentation",
"url": "https://tasks.cusy.io/"
},
{
"comment": "from packaging metadata Project-URL: Mastodon",
"type": "other",
"url": "https://mastodon.social/@Python4DataScience"
},
{
"comment": "from packaging metadata Project-URL: GitHub",
"type": "vcs",
"url": "https://github.com/cusyio/cusy.tasks"
}
],
"licenses": [
{
"license": {
"acknowledgement": "declared",
"id": "BSD-3-Clause"
}
}
],
"name": "cusy-tasks",
"type": "library",
"version": "26.2.0"
}
Der Kommandozeilenaufruf zum Erstellen der Datei ist:
$ uvx --from cyclonedx-bom cyclonedx-py environment .venv --output-file sbom.cdx.json
Warnung
CycloneDX Python erstellt die SBOM-Datei aus dem aktuellen
.venv-Verzeichnis. Ruft ihr cyclonedx-bom also in eurer
Entwicklungsumgebung auf, werdet ihr auch alle Entwicklungswerkzeuge in eurer
SBOM-Datei wiederfinden.
… mit sbomify¶
sbomify stellt eine GitHub Action zum Erstellen der SBOM-Datei bereit, die unter der Haube CycloneDX Python verwendet. Mit actions/attest-sbom kann die Datei dann attestiert werden:
---
name: Build with SBOM Attestation
on:
push:
branches: [main]
permissions:
contents: read
id-token: write
attestations: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Build
run: uv build
- name: Generate SBOM
uses: sbomify/sbomify-action@f38411f20fe2cc52e5bb7abd4d094ffc9dc5f17c # v26.7.0
env:
LOCK_FILE: uv.lock
OUTPUT_FILE: sbom.cdx.json
COMPONENT_NAME: myapp
COMPONENT_VERSION: ${{ github.sha }}
ENRICH: true
UPLOAD: false
- name: Attest SBOM
uses: actions/attest-sbom@c604332985a26aa8cf1bdc465b92731239ec6b9e # v4.1.0
with:
subject-path: './dist'
sbom-path: './sbom.cdx.json'
In GitLab CI könnt ihr sbomify folgendermaßen verwenden:
stages:
- build
- sbom
build:
stage: build
script:
- uv build
artifacts:
paths:
- dist/
generate-sbom:
stage: sbom
image: ghcr.io/sbomify/sbomify-action
variables:
LOCK_FILE: uv.lock
OUTPUT_FILE: sbom.cdx.json
COMPONENT_NAME: myapp
COMPONENT_VERSION: $CI_COMMIT_TAG
UPLOAD: "false"
ENRICH: "true"
script:
- /sbomify.sh
artifacts:
paths:
- sbom.cdx.json
reports:
cyclonedx: sbom.cdx.json
Ihr könnt auch Dependency Scanning integrieren:
include:
- template: Security/Dependency-Scanning.gitlab-ci.yml
generate-sbom:
stage: test
image: ghcr.io/sbomify/sbomify-action
variables:
LOCK_FILE: uv.lock
OUTPUT_FILE: gl-sbom-report.cdx.json
UPLOAD: "false"
ENRICH: "true"
script:
- /sbomify.sh
artifacts:
paths:
- gl-sbom-report.cdx.json
reports:
cyclonedx: gl-sbom-report.cdx.json
PEP 770 – SBOMs in Python-Paketen¶
PEP 770 standardisiert die Einbindung von SBOMs in Python-Wheels über das
Verzeichnis .dist-info/sboms/. Wenn ihr Python-Pakete auf PyPI
veröffentlicht, bedeutet dies, dass eure User die SBOM-Datei automatisch
erhalten, wenn sie euer Paket installieren, z. B.:
myapp-26.2.0.dist-info
├── METADATA
├── RECORD
└── sboms/
└── myapp.cdx.json
Build-Backends wie Hatchling≥1.28 unterstützen dies bereits mit der
sbom-files-Konfiguration:
[tool.hatch.build.targets.wheel]
sbom-files = ["myapp.cdx.json"]
Anstatt die SBOM-Datei beim Build von Grund auf neu zu generieren, kann eine minimale CycloneDX-SBOM-Datei in das Repository eingecheckt werden:
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"version": 1,
"metadata": {
"component": {
"type": "library",
"name": "mylib",
"version": "0.0.0-placeholder"
}
},
"components": []
}
Im CI-Workflow wird die Platzhalter-SBOM-Datei dann mit dem Code ausgecheckt. sbomify reichert sie dann mit den aktuellen Informationen an. Anschließend baut hatchling das Wheel mit der aktuellen SBOM-Datei und schließlich wird das Wheel auf PyPI veröffentlicht.
Analyse¶
Zur Sicherheits- und Lizenzprüfung stehen zahlreiche Tools zur Verfügung, die
sich auf unterschiedliche Problembereiche konzentrieren. Zwei Open-Source-Tools
für die SBOM-Analyse sind Dependency Track und
GUAC. Mit sbomify-action könnt ihr SBOMs aus der
CI-Pipeline direkt in eure Dependency Track-Instanz hochladen mit:
UPLOAD_DESTINATIONS=dependency-track