SBOM
Docker-SBOM: hoe u er een genereert en wat hij mist
U kunt met één opdracht een SBOM voor een Docker-image krijgen, tijdens de build met BuildKit of achteraf met Docker Scout of Syft. Elk daarvan leest de pakketmetadata die het in de image vindt. Dat is het juiste record van wat de image bevat, voor zover de metadata reikt. Het is geen record van hoe de image is gebouwd.
Bijgewerkt op
Hoe u een SBOM voor een Docker-image genereert
Er zijn drie gangbare manieren. BuildKit kan de SBOM schrijven terwijl het de image bouwt en hem als attestatie aan de image koppelen. Docker Scout en Syft genereren er een uit een image die al bestaat, lokaal of in een registry.
Tijdens de build, met BuildKit
Voeg --sbom=true, of de lange vorm --attest type=sbom, toe aan docker buildx build. BuildKit draait zijn Syft-scannerplug-in op het resultaat en koppelt de SBOM als SPDX JSON-document aan de image. Bouw met de exporter local om de SBOM te bekijken voordat u iets pusht:
# 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 De SBOM lezen die aan een image is gekoppeld
docker buildx imagetools inspect leest de attestatie terug uit de registry. Alles wat met de SBOM te maken heeft, staat onder .SBOM in de Go-template:
# 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 }}" Uit een bestaande image, met Docker Scout
docker scout sbom gebruikt de SBOM-attestatie van de image als die er is. Is die er niet, dan indexeert het de inhoud van de image zelf. Standaard geeft het JSON als uitvoer, en met --output schrijft het naar een bestand:
# 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 Uit een bestaande image, met Syft
Syft is de open-sourcescanner waarop de plug-in van BuildKit is gebouwd. Richt hem op een image en kies het formaat met -o. Voeg =file toe om elk formaat naar een eigen bestand te schrijven:
# 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 of CycloneDX?
BuildKit-attestaties zijn altijd SPDX. Docker Scout schrijft SPDX of CycloneDX, en Syft schrijft beide, naast andere formaten. Beide standaarden vermelden pakketten, versies, licenties en package-URL's, dus de keuze hangt meestal af van de tool die de SBOM daarna leest. Zie CycloneDX vs SPDX voor de verschillen.
Hoe een imagescanner een SBOM opbouwt
Al deze tools werken op dezelfde manier. Ze pakken de imagelagen uit en lezen de pakketmetadata die ze vinden: de pakketdatabase van het besturingssysteem en de metadata die pakketbeheerders van programmeertalen achterlaten. Elk pakket dat ze kunnen identificeren, wordt een vermelding in de SBOM, inclusief de pakketten uit de base image.
Buildfasen en de buildcontext meenemen
Standaard scant BuildKit alleen de laatste fase. Bij een multi-stage build zitten de compilers, buildtools en pakketten uit eerdere fasen niet in de uiteindelijke image, dus ook niet in de SBOM ervan. De documentatie over SBOM-attestaties van Docker beschrijft twee buildargumenten die de scan verbreden. BUILDKIT_SBOM_SCAN_STAGE voegt een fase toe, en BUILDKIT_SBOM_SCAN_CONTEXT voegt de buildcontext toe:
# 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 moeten met ARG in de Dockerfile worden gedeclareerd. Ze alleen met --build-arg instellen heeft geen effect, al kan --build-arg wel een waarde overschrijven die de Dockerfile declareert. Met de exporter local krijgt elke gescande fase een eigen bestand, zoals sbom-build.spdx.json naast sbom.spdx.json.
Wat een scan nog steeds mist
Het scannen van fasen dicht één gat. De scanner leest echter nog steeds bestanden, en een deel van wat een build gebruikt, laat geen bestand achter, of geen bestand dat hij kan identificeren:
- Bestanden zonder pakketmetadata. Een binary die met
curlis gedownload, een tarball die in eenRUN-stap is uitgepakt, of vendored code die is meegekopieerd. Sommige binaries bevatten buildinformatie die een scanner kan lezen, zoals Go-binaries; veel andere niet. - Wat de build heeft gedownload en verwijderd. Een pakket of installatieprogramma dat een
RUN-stap in dezelfde laag ophaalt, gebruikt en verwijdert, laat niets op het bestandssysteem achter dat een scanner kan lezen, laatste fase of niet. - Hoe dingen erin zijn gekomen. Een SBOM uit een scan vermeldt wat er is. Hij zegt niet uit welke registry of van welke host een pakket kwam, of welke stap het heeft opgehaald.
- Fasen die u niet hebt gemarkeerd. Het scannen van fasen is opt-in, per fase of globaal. Een fase zonder het argument blijft buiten beschouwing.
- Scaninstellingen. Wat er verschijnt, hangt af van hoe de scanner wordt uitgevoerd. Bij één project bepaalt een enkele Syft-vlag of npm-pakketten überhaupt in het resultaat verschijnen.
Waarom het ertoe doet
Een gecompromitteerde buildtool of base image beïnvloedt wat u levert, ook als die nooit in de uiteindelijke image verschijnt. En een binary zonder metadata kan een kwetsbaarheid bevatten waar geen enkele SBOM-vermelding naar verwijst. Wanneer er een advisory verschijnt, moet u weten wat er is gebruikt om de image te bouwen én wat erin zit.
Leg ook de build vast
De image-SBOM beantwoordt wat er in de image zit. Een record van de build beantwoordt wat de build heeft binnengehaald: de base images die hij ophaalde en de pakketten die elke stap ophaalde, inclusief de verborgen afhankelijkheden die in geen enkele lockfile staan. CRACI legt dat vast terwijl uw GitHub Actions-job draait, via een proxy op de runner die pakketten herkent, en de API levert SBOM's, netwerktraces en herkomstgegevens voor de job. Gebruik de image-SBOM voor wat u levert en het buildrecord voor hoe het is gemaakt.
Zie SBOM-tools vergeleken, build-time SBOM's en een SBOM genereren in GitHub Actions.
Docker-SBOM's: veelgestelde vragen
Hoe genereer ik een SBOM voor een Docker-image?
Er zijn drie gangbare manieren. Voeg --sbom=true toe aan docker buildx build, en BuildKit koppelt een SPDX-SBOM aan de image. Voer docker scout sbom uit op een bestaande image. Of voer Syft uit, bijvoorbeeld syft IMAGE -o cyclonedx-json. Alle drie lezen ze de pakketten die ze in de image vinden.
Wat is een SBOM-scanner?
Een tool die bestanden leest, zoals een bronmap, een lockfile of een containerimage, en een SBOM schrijft van de pakketten die hij kan identificeren. Syft, Trivy, Docker Scout en de Syft-plug-in van BuildKit zijn SBOM-scanners. Ze beschrijven de bestanden die ze voor zich hebben, niet de build die ze heeft opgeleverd.
Welk SBOM-formaat levert Docker?
BuildKit-attestaties zijn SPDX JSON-documenten die aan de image zijn gekoppeld. Docker Scout kan een pakketlijst tonen of SPDX of CycloneDX schrijven. Syft schrijft beide, en meer. Kies het formaat dat de tool verwacht die de SBOM verwerkt.
Hoe bouwt een scanner een SBOM op uit een Docker-image?
Hij pakt de imagelagen uit en leest de pakketmetadata die hij vindt: de pakketdatabase van het besturingssysteem en pakketbestanden van programmeertalen, zoals de metadata van geïnstalleerde npm- of Python-pakketten. Elk pakket dat hij kan identificeren, wordt een vermelding in de SBOM.
Waarom zou een image-SBOM een component missen?
Omdat hij alleen kan vermelden wat hij kan identificeren in de bestanden die hij leest. Een binary die met curl is gedownload, heeft geen pakketmetadata, een pakket dat een buildstap heeft gedownload en verwijderd, laat niets achter om te lezen, en eerdere buildfasen blijven buiten beschouwing tenzij u het scannen van fasen inschakelt.
Is een image-SBOM nog steeds nuttig?
Ja. Hij is het juiste record van wat er in de image zit die u levert, inclusief pakketten uit de base image. Hij beschrijft alleen niet hoe de image is gebouwd, dus combineer hem met een record van de build wanneer dat ertoe doet.
Zie wat uw imagebuild binnenhaalde
Laat één imagebuild op CRACI draaien en leg het record van opgehaalde base images en pakketten naast de image-SBOM van uw scanner.
Demo boeken