SBOM
Docker-SBOM: So erzeugen Sie eine, und was sie übersieht
Eine SBOM für ein Docker-Image erhalten Sie mit einem einzigen Befehl, zur Build-Zeit mit BuildKit oder nachträglich mit Docker Scout oder Syft. Jedes dieser Tools liest die Paketmetadaten, die es im Image findet. Das ist die richtige Aufzeichnung dessen, was das Image enthält, soweit die Metadaten reichen. Es ist keine Aufzeichnung dessen, wie das Image gebaut wurde.
Aktualisiert am
So erzeugen Sie eine SBOM für ein Docker-Image
Es gibt drei gängige Wege. BuildKit kann die SBOM schreiben, während es das Image baut, und sie als Attestierung an das Image anhängen. Docker Scout und Syft erzeugen eine aus einem bereits vorhandenen Image, lokal oder in einer Registry.
Zur Build-Zeit, mit BuildKit
Ergänzen Sie --sbom=true oder die Langform --attest type=sbom bei docker buildx build. BuildKit führt sein Syft-Scanner-Plugin auf dem Ergebnis aus und hängt die SBOM als SPDX-JSON-Dokument an das Image an. Bauen Sie mit dem local-Exporter, um die SBOM anzusehen, bevor Sie etwas pushen:
# Build the image, attach an SBOM attestation and push it
docker buildx build --sbom=true -t registry.example.com/app:1.0 --push .
# The long form of the same option
docker buildx build --attest type=sbom -t registry.example.com/app:1.0 --push .
# Check the SBOM before pushing: write the build result to ./out
docker buildx build --sbom=true --output type=local,dest=out .
# out/sbom.spdx.json is the SBOM Die an ein Image angehängte SBOM lesen
docker buildx imagetools inspect liest die Attestierung aus der Registry zurück. Alles, was die SBOM betrifft, liegt in seinem Go-Template unter .SBOM:
# Print the SPDX document attached to the image
docker buildx imagetools inspect registry.example.com/app:1.0 \
--format "{{ json .SBOM.SPDX }}"
# List each package and its version
docker buildx imagetools inspect registry.example.com/app:1.0 \
--format "{{ range .SBOM.SPDX.packages }}{{ .name }}@{{ .versionInfo }}{{ println }}{{ end }}" Aus einem vorhandenen Image, mit Docker Scout
docker scout sbom nutzt die SBOM-Attestierung des Images, falls es eine gibt. Gibt es keine, indiziert es den Inhalt des Images selbst. Standardmäßig gibt es JSON aus, und mit --output schreibt es in eine Datei:
# List the packages in an image
docker scout sbom --format list registry.example.com/app:1.0
# Write an SPDX or CycloneDX SBOM to a file
docker scout sbom --format spdx --output app.spdx.json registry.example.com/app:1.0
docker scout sbom --format cyclonedx --output app.cdx.json registry.example.com/app:1.0 Aus einem vorhandenen Image, mit Syft
Syft ist der Open-Source-Scanner, auf dem das BuildKit-Plugin aufbaut. Richten Sie ihn auf ein Image und wählen Sie das Format mit -o. Ergänzen Sie =file, um jedes Format in eine eigene Datei zu schreiben:
# CycloneDX JSON to the terminal
syft registry.example.com/app:1.0 -o cyclonedx-json
# Both formats, each to its own file
syft registry.example.com/app:1.0 -o spdx-json=app.spdx.json -o cyclonedx-json=app.cdx.json SPDX oder CycloneDX?
BuildKit-Attestierungen sind immer SPDX. Docker Scout schreibt SPDX oder CycloneDX, und Syft schreibt beide, neben anderen Formaten. Beide Standards führen Pakete, Versionen, Lizenzen und Package-URLs auf, die Wahl hängt also meist vom Tool ab, das die SBOM als Nächstes liest. Die Unterschiede finden Sie unter CycloneDX vs. SPDX.
Wie ein Image-Scanner eine SBOM erstellt
All diese Tools arbeiten gleich. Sie entpacken die Image-Schichten und lesen die Paketmetadaten, die sie finden: die Paketdatenbank des Betriebssystems und die Metadaten, die Sprach-Paketmanager hinterlassen. Jedes Paket, das sie identifizieren können, wird zu einem SBOM-Eintrag, einschließlich der Pakete aus dem Basis-Image.
Build-Stages und Build-Kontext einbeziehen
Standardmäßig scannt BuildKit nur die letzte Stage. Bei einem Multi-Stage-Build stehen die Compiler, Build-Tools und Pakete aus früheren Stages nicht im finalen Image und daher auch nicht in dessen SBOM. Die Docker-Dokumentation zu SBOM-Attestierungen beschreibt zwei Build-Argumente, die den Scan erweitern. BUILDKIT_SBOM_SCAN_STAGE ergänzt eine Stage, und BUILDKIT_SBOM_SCAN_CONTEXT ergänzt den Build-Kontext:
# syntax=docker/dockerfile:1
# Scan the build context as well as the image
ARG BUILDKIT_SBOM_SCAN_CONTEXT=true
FROM golang:1.25 AS build
# Include this build stage in the SBOM
ARG BUILDKIT_SBOM_SCAN_STAGE=true
WORKDIR /src
COPY . .
RUN go build -o /out/app .
FROM scratch
COPY --from=build /out/app /app
ENTRYPOINT ["/app"] Beide müssen im Dockerfile mit ARG deklariert werden. Sie nur mit --build-arg zu setzen, hat keine Wirkung, allerdings kann --build-arg einen im Dockerfile deklarierten Wert überschreiben. Mit dem local-Exporter erhält jede gescannte Stage eine eigene Datei, etwa sbom-build.spdx.json neben sbom.spdx.json.
Was ein Scan weiterhin übersieht
Das Scannen von Stages schließt eine Lücke. Der Scanner liest aber weiterhin Dateien, und manches, was ein Build nutzt, hinterlässt keine Datei oder keine, die er identifizieren kann:
- Dateien ohne Paketmetadaten. Eine mit
curlheruntergeladene Binärdatei, ein in einemRUN-Schritt entpackter Tarball oder hineinkopierter Vendored Code. Manche Binärdateien tragen Build-Informationen, die ein Scanner lesen kann, etwa Go-Binärdateien; viele nicht. - Was der Build heruntergeladen und gelöscht hat. Ein Paket oder Installer, den ein
RUN-Schritt lädt, nutzt und in derselben Schicht entfernt, hinterlässt im Dateisystem nichts, was ein Scanner lesen könnte, ob in der letzten Stage oder nicht. - Wie Dinge hineingekommen sind. Eine SBOM aus einem Scan listet auf, was vorhanden ist. Sie sagt nicht, aus welcher Registry oder von welchem Host ein Paket stammt oder welcher Schritt es geladen hat.
- Stages, die Sie nicht markiert haben. Das Scannen von Stages ist optional, pro Stage oder global. Eine Stage ohne das Argument bleibt weiterhin außen vor.
- Scan-Einstellungen. Was erscheint, hängt davon ab, wie der Scanner ausgeführt wird. Bei einem Projekt entscheidet ein einziges Syft-Flag, ob npm-Pakete überhaupt im Ergebnis auftauchen.
Warum das wichtig ist
Ein kompromittiertes Build-Tool oder Basis-Image wirkt sich auf das Ausgelieferte aus, selbst wenn es nie im finalen Image erscheint. Und eine Binärdatei ohne Metadaten kann eine Schwachstelle enthalten, auf die kein SBOM-Eintrag verweist. Wenn ein Advisory erscheint, müssen Sie wissen, was in den Bau des Images eingeflossen ist und was darin steckt.
Zeichnen Sie auch den Build auf
Die Image-SBOM beantwortet, was im Image steckt. Eine Aufzeichnung des Builds beantwortet, was der Build geladen hat: die gezogenen Basis-Images und die Pakete, die jeder Schritt geladen hat, einschließlich der versteckten Abhängigkeiten, die kein Lockfile auflistet. CRACI zeichnet das auf, während Ihr GitHub-Actions-Job läuft, über einen paketbewussten Proxy auf dem Runner, und die API liefert SBOMs, Netzwerk-Traces und Provenienz für den Job. Nutzen Sie die Image-SBOM für das, was Sie ausliefern, und die Build-Aufzeichnung dafür, wie es entstanden ist.
Siehe SBOM-Tools im Vergleich, SBOMs zur Build-Zeit und So erzeugen Sie eine SBOM in GitHub Actions.
Docker-SBOMs: häufig gestellte Fragen
Wie erzeuge ich eine SBOM für ein Docker-Image?
Es gibt drei gängige Wege. Ergänzen Sie --sbom=true bei docker buildx build, und BuildKit hängt eine SPDX-SBOM an das Image an. Führen Sie docker scout sbom auf einem vorhandenen Image aus. Oder nutzen Sie Syft, zum Beispiel syft IMAGE -o cyclonedx-json. Alle drei lesen die Pakete, die sie im Image finden.
Was ist ein SBOM-Scanner?
Ein Tool, das Dateien liest, etwa ein Quellverzeichnis, ein Lockfile oder ein Container-Image, und eine SBOM der Pakete schreibt, die es identifizieren kann. Syft, Trivy, Docker Scout und das Syft-Plugin von BuildKit sind SBOM-Scanner. Sie beschreiben die Dateien, die ihnen vorliegen, nicht den Build, der sie erzeugt hat.
Welches SBOM-Format erzeugt Docker?
BuildKit-Attestierungen sind SPDX-JSON-Dokumente, die an das Image angehängt werden. Docker Scout kann eine Paketliste ausgeben oder SPDX oder CycloneDX schreiben. Syft schreibt beide und mehr. Wählen Sie das Format, das das Tool erwartet, das die SBOM verarbeitet.
Wie erstellt ein Scanner eine SBOM aus einem Docker-Image?
Er entpackt die Image-Schichten und liest die Paketmetadaten, die er findet: die Paketdatenbank des Betriebssystems und Paketdateien der Programmiersprachen, etwa Metadaten installierter npm- oder Python-Pakete. Jedes Paket, das er identifizieren kann, wird zu einem Eintrag in der SBOM.
Warum kann in einer Image-SBOM eine Komponente fehlen?
Weil sie nur auflisten kann, was sie in den gelesenen Dateien identifizieren kann. Eine mit curl heruntergeladene Binärdatei trägt keine Paketmetadaten, ein Paket, das ein Build-Schritt heruntergeladen und gelöscht hat, hinterlässt nichts zum Lesen, und frühere Build-Stages bleiben außen vor, sofern Sie das Scannen von Stages nicht aktivieren.
Ist eine Image-SBOM trotzdem nützlich?
Ja. Sie ist die richtige Aufzeichnung dessen, was im ausgelieferten Image steckt, einschließlich der Pakete aus dem Basis-Image. Sie beschreibt nur nicht, wie das Image gebaut wurde. Kombinieren Sie sie daher mit einer Aufzeichnung des Builds, wenn das wichtig ist.
Sehen Sie, was Ihr Image-Build geladen hat
Lassen Sie einen Image-Build auf CRACI laufen und stellen Sie seine Aufzeichnung geladener Basis-Images und Pakete neben die Image-SBOM Ihres Scanners.
Demo buchen