SBOM
En SBOM bør beskrive bygget som ble levert
En SBOM fra bygget registreres mens bygget kjører, ut fra trafikken som faktisk kom inn i det. De fleste SBOM-generatorer rekonstruerer i stedet listen etterpå fra lockfilen eller utdataene, og går dermed glipp av de skjulte avhengighetene et bygg henter på egen hånd. Her ser du hvorfor, og hva det endrer å registrere bygget.
Oppdatert
Bygge-SBOM, kilde-SBOM, analysert SBOM
CISAs veiledning om SBOM-typer sorterer SBOM-er etter når og hvordan de lages. Tre av dem dekker nesten alle SBOM-generatorer som er i bruk:
| Type | Hvordan den lages | Hva den kan gå glipp av |
|---|---|---|
| Kilde | Fra kildefiler, manifester og lockfiler, vanligvis med et SCA-verktøy | Komponenter fra kjøretid, plugins eller plattform; alt som ikke er deklarert i filene |
| Bygg | Som en del av bygget som lager den utgivbare artefakten | Det byggemiljøet ikke kan se, og derfor bør fullstendigheten angis |
| Analysert | Etter bygget, ved å analysere en kjørbar fil, en pakke eller et container-image | Komponenter verktøyet ikke kan gjenkjenne; resultatene avhenger av heuristikk |
CISA nevner to fordeler med en bygge-SBOM: større tiltro til at SBOM-en representerer artefakten riktig, på grunn
av informasjonen som er tilgjengelig under bygge- og CI/CD-prosessen, og mer tillit, fordi den samme bygge-workflowen
kan signere både SBOM-en og artefakten. Ulempen CISA nevner, er at du kan måtte endre byggeprosessen for å
generere en. Med CRACI er den endringen én linje, runs-on: craci, og registreringen følger med
runneren.
Skanne en mappe eller registrere et bygg
De fleste SBOM-generatorer er skannere. Du peker en mot et kildetre eller et container-image, og den finner ut hva den tror gikk inn, ved å lese manifester, lockfiler, installerte pakker eller binærfiler. Det er nyttig, og for programvare du ikke har bygget selv, er det ofte det eneste alternativet.
Svakheten er at en skanner bare ser det den har foran seg. Hvis ingen lockfile ble committet, hvis avhengighetene ikke ble installert før skanningen, eller hvis produktet leveres som en kompilert binærfil, har skanneren mindre å jobbe med enn bygget hadde. En skanning som ikke finner noen komponenter i det hele tatt, produserer likevel et gyldig SBOM-dokument, og det er den delen som overrasker folk.
CRACI går en annen vei. Det genererer SBOM-en inne i sin egen CI-runner, så artefakten som leveres, er artefakten som beskrives. Det er ikke en skanning som kjørte et sted i nærheten.
SBOM basics: SPDX, CycloneDX and OpenVEX
Hva en SBOM registrerer, hvordan formatene SPDX og CycloneDX skiller seg i praksis, og hva OpenVEX tilfører om hvorvidt en sårbarhet faktisk rammer et produkt.
Petteri Pulkkinen og Erika Marttinen på Kubernetes Community Days Helsinki 2026, 16:50 til 22:05 av SBOMbastic: Getting Ready for Upcoming EU Cybersecurity Regulation in Software Supply Chains.
Hva en skanning avhenger av
Syft, Trivy, cdxgen, Microsoft SBOM Tool, eksporten av GitHubs avhengighetsgraf og Socket CLI utleder alle en SBOM fra det de kan lese. Mønstrene nedenfor følger av hvordan verktøyene fungerer ifølge sin egen dokumentasjon.
Verktøy er uenige om hva som teller som en komponent
Hver generator avgjør selv hva som teller som en komponent og hvilke filer den skal stole på, så den samme festede commiten gir hver av dem en forskjellig liste.
Noe av det handler om navn. Verktøy identifiserer den samme GitHub Action under forskjellige package URL-typer, så de kan liste opp det samme og likevel ikke stemme overens. Det er også en del av problemet: En SBOM som bruker en annen identifikator for en komponent, er vanskeligere å matche mot sårbarhetsdata.
Om du installerte først, kan bety mer enn verktøyet
Express 5.2.1 committer ingen lockfile. Pekt mot en ren utsjekk har en
generator som løser avhengigheter fra lockfiler eller et installert tre,
ingen av delene foran seg, så ingen av npm-avhengighetene deklarert i
package.json når dokumentet. Den kan likevel returnere en liste,
laget av det andre den gjenkjenner, for eksempel GitHub Actions og
workflow-filene som refererer til dem. Ingen av verktøyene her er ødelagt.
På en installert kopi av samme repositorium endrer ett Syft-flagg svaret igjen. Samme verktøy, samme tre, samme versjon. Syft er laget slik at en katalogskanning rapporterer det et prosjekt deklarerer, og katalogisereren som leser installerte pakker, er ikke med i standardsettet for kataloger.
Noe programvare har ikke noe manifest å lese
Repositoriet anthropics/claude-code på v2.1.259 har ikke noe avhengighetsmanifest
av noe slag: ingen package.json, lockfile eller
tilsvarende. Det hver generator returnerer for det, er satt sammen fra andre
filtyper, så svaret sier mer om verktøyet enn om prosjektet.
Den publiserte npm-pakken er ikke så annerledes. @anthropic-ai/claude-code deklarerer null kjøretidsavhengigheter og
åtte plattformspesifikke pakker som pakker inn en ferdigbygd binærfil.
@openai/codex 0.149.1 har samme form. Det som kjører på
utviklerens maskin, er en kompilert binærfil som ingen manifestleser kan se
inn i. Dette er ikke en feil i ett bestemt verktøy. Det er en distribusjonsmodell som
skanning i etterkant ikke kan beskrive.
Versjoner og leverandører
Der to verktøy finner samme pakke, er de ikke alltid enige om versjonen. Det ene kan feste en GitHub Action til en commit-SHA, mens det andre rapporterer en utgivelsestagg. Et sårbarhetsoppslag basert på feil versjon gir et selvsikkert, feil svar.
Leverandørfeltet, et av NTIAs minimumselementer, blir ofte tomt, fordi de fleste generatorer ikke har noen kilde til det.
Skjulte avhengigheter: det ingen skanning kan se
Alle verktøyene ovenfor begynner med lockfilen eller utdataene fra bygget og finner ut hva som gikk inn. Et bygg henter mer enn det. Disse skjulte avhengighetene står ikke i noen lockfile, så en skanning kan ikke finne dem:
-
Installasjonshooks. npm-skriptene
preinstallogpostinstallkjører under installasjonen og kan laste ned mer kode. Det var slik Shai-Hulud-ormen kjørte. - Byggeskript. Rust-byggeskript, blant andre, laster ned det de trenger under bygging.
- Base-images. Et containerbygg henter et base-image og operativsystemlagene i det, som ingen lockfile for et programmeringsspråk lister opp.
- Cacher og byggeverktøy. Pakker gjenopprettet fra CI-cacher og verktøy installert av oppsettsteg kommer også utenfor lockfilen.
Å skanne utdataene etterpå tetter ikke hullet. En ferdig binærfil, særlig kompilert kode som Rust, lar skanneren gjette seg til hva som gikk inn i den.
To bygg, to SBOM-er
Det er en annen grunn til at en skanning ikke kan erstatte bygget: De fleste bygg er ikke reproduserbare. Bygg samme commit to ganger rett etter hverandre, og det er ingen garanti for at du får de samme pakkene. Pakkebehandlere løser og installerer i den rekkefølgen svarene kommer, og det betyr mest når det ikke finnes noen lockfile, som i mange Python-prosjekter, og byggesteg kan ha tilfeldighet i seg. Bygg som er reproduserbare byte for byte, er mulige, med verktøy som Nix, men de er sjeldne.
En SBOM generert senere, på en annen maskin eller fra et annet bygg, beskriver derfor et bygg som kanskje aldri ble levert. Bare SBOM-en registrert under CI-bygget som produserte en utgivelse, beviser hva som er i produksjon.
Dette endrer det å registrere bygget
CRACI ser trafikken; det gjør ikke skannere. Det kjører GitHub Actions-jobbene dine på sine egne runnere og ser nettverkstrafikken som kommer inn i hvert bygg, så SBOM-en lister opp det jobben faktisk hentet, inkludert transitive og skjulte avhengigheter, ikke det et manifest sier at den burde trenge.
Det er ved cacher at registrering under bygget blir vanskelig. En pakke som gjenopprettes fra en cache, berører aldri et pakkeregister, så en proxy alene ville gått glipp av den. CRACI tar med seg dokumentasjonen for avhengighetene i cachen, så pakker gjenopprettet fra en cache blir værende i SBOM-en til jobben som gjenopprettet dem. Se hva GitHub Actions-cachen skjuler.
Oppdagede økosystemer omfatter npm, PyPI, RubyGems, Cargo, Go, Nix, OCI, apt, apk og Git-kilder, i tillegg til download-presets for Yocto og OpenEmbedded. JFrog Artifactory-speil for npm og PyPI fungerer. Deklarerte lisensmetadata er med i eksporten. SBOM-er eksporteres i CycloneDX og SPDX. Siden om SBOM-generering dekker hele funksjonaliteten.
Å se trafikken fungerer også i den andre retningen. Et bygg trenger pakker fra kjente kilder og publiserer utdataene til kjente steder. Egress-policyen i CRACI tillater bare disse og blokkerer alle andre utgående tilkoblinger umiddelbart, så skadevare som prøver å sende hemmelighetene dine til en angripers server, mislykkes. Fordi policyen tillater det bygget trenger i stedet for å se etter kjente ondsinnede verter, holder den selv om du er det første målet for et angrep ingen har sett før, slik som med Shai-Hulud. Se hvordan en egress-policy stopper eksfiltrering.
SBOM-er for containere og Docker
Det er i container-images forskjellen merkes mest. De vanlige måtene å få en Docker-SBOM på analyserer alle imaget:
Syft og Trivy skanner det, docker scout sbom indekserer innholdet når imaget ikke har noen SBOM-attestasjon,
og BuildKits SBOM-attestasjon, som slås på med --sbom=true, kjører en Syft-basert skanner
over det siste image-stadiet som standard. Den eldre pluginen docker sbom er avviklet til fordel for
docker scout sbom.
Alle disse leser det ferdige imaget, så de ser det som fortsatt kan gjenkjennes i lagene. De ser ikke det bygget hentet underveis. CRACI registrerer jobben som bygger imaget: Imagene og pakkene jobben henter fra OCI-registre og pakkekilder, går inn i samme SBOM som resten av bygget. For et image du ikke har bygget, er skanning fortsatt det praktiske alternativet. Se hva SBOM-er for Docker-images går glipp av.
Fullstendighet, angitt per jobb
En registrert SBOM er bare så god som registreringen. I stedet for å presentere hver SBOM som fullstendig, angir CRACI fullstendigheten for hver jobb og hver cache, med én av fem statuser:
- Complete. CRACI observerte fullstendig dokumentasjon for jobben, og hver gjenopprettede cache var fullstendig.
- Complete with connections. Kravene ble oppfylt, men jobben brukte én eller flere egendefinerte nettverkstilkoblinger, så det er verdt å gå gjennom hva som kom gjennom dem.
- Incomplete. CRACI identifiserte en tilstand som kan utelate avhengigheter fra SBOM-en.
- Unavailable. CRACI kunne ikke fullføre vurderingen av dokumentasjonen.
- Not recorded. Jobben er eldre enn fullstendighetsrapporteringen.
Fullstendighet er transitiv på tvers av cacher. Hvis en jobb gjenoppretter en ufullstendig cache, er SBOM-en også ufullstendig, og enhver cache jobben produserer, tar med seg den ufullstendige statusen videre. Du vet hvilke SBOM-er du kan stole på, og hvilke som trenger en nærmere titt.
The hard parts: hooks, noise and staying current
Tre problemer foredraget peker på: post-install-hooks som henter ting ingen manifester lister opp, å finne avhengighetene som betyr noe i en lang liste, og å holde SBOM-en oppdatert, som betyr å generere den i CI ved hvert bygg.
Petteri Pulkkinen og Erika Marttinen på Kubernetes Community Days Helsinki 2026, 25:39 til 27:22 av SBOMbastic: Getting Ready for Upcoming EU Cybersecurity Regulation in Software Supply Chains.
Provenance via API-et
SBOM-en er én del av det CRACI registrerer for hver jobb. API-et returnerer SBOM-er, nettverksspor og provenance, alt registrert fra det samme bygget.
Der en skanner fortsatt er det rette verktøyet
Registrering under bygget dekker programvare du bygger. For et image eller en binærfil fra tredjeparter som du ikke har bygget, er en skanner fortsatt det praktiske valget, og verktøyene ovenfor er dyktige og mye brukt. Poenget er ikke at skannere er dårlige. Det er at SBOM-en for dine egne utgivelser bør komme fra bygget som laget dem.
En CRACI-SBOM har også sine egne begrensninger. Den dekker jobber som kjører på CRACI-runnere, og det betyr i dag GitHub Actions på Linux, med andre CI-systemer på veikartet.
Skal du velge mellom verktøy? Se SBOM-verktøy sammenlignet, eller se hvordan SBOM-er fra bygget passer inn i arbeidet med CRA-samsvar. For Syft, Trivy og cdxgen side om side, se hva SBOM-generatorer med åpen kildekode går glipp av.
SBOM-er fra bygget: ofte stilte spørsmål
Hva er en SBOM fra bygget?
En SBOM fra bygget, som CISA kaller en build SBOM, genereres som en del av byggingen av den utgivbare artefakten. I stedet for å rekonstruere komponentlisten fra filer i etterkant beskriver den det selve bygget brukte. CRACI registrerer den ut fra pakkene hver GitHub Actions-jobb faktisk hentet.
Hva er forskjellen på en bygge-SBOM og en analysert SBOM?
En analysert SBOM genereres etter bygget ved å analysere en artefakt, for eksempel en kjørbar fil eller et container-image, og det krever vanligvis heuristikk. En bygge-SBOM genereres under bygget, ut fra informasjon bygget har. Analyserte SBOM-er fungerer uten tilgang til bygget, og det gjør dem til det rette valget for programvare du ikke har bygget.
Hvordan genererer jeg en SBOM for et Docker-image?
For et eksisterende image skanner du det med en generator som Syft, Trivy eller docker scout sbom. BuildKit kan også knytte til en SBOM-attestasjon når du bygger, ved å skanne det endelige imaget. For å registrere hva bygget av et image hentet inn, kjører du bygget på en CRACI-runner: SBOM-en til jobben dekker imagene og pakkene den hentet.
Hva er skjulte avhengigheter?
Alt et bygg henter som ingen lockfile lister opp: kode lastet ned av npm-installasjonshooks, filer som Rust-byggeskript laster ned under bygging, og base-imaget og operativsystemlagene i det i et containerbygg. Verktøy som leser lockfilen eller skanner utdataene, går glipp av dem. CRACI registrerer dem fordi det ser trafikken som kommer inn i bygget.
Hvorfor gir to bygg av samme kode forskjellige SBOM-er?
Fordi de fleste bygg ikke er reproduserbare. Pakkebehandleren løser og installerer pakker i den rekkefølgen svarene kommer, særlig uten lockfile, og byggesteg kan ha tilfeldighet i seg. Bygg samme commit to ganger rett etter hverandre, og det andre bygget kan inneholde andre pakker. Bare SBOM-en registrert under bygget som produserte en utgivelse, beviser hva den utgivelsen inneholder.
Er en SBOM fra bygget alltid fullstendig?
Ikke automatisk. En registrering er bare så god som det den kan observere, så CRACI angir fullstendigheten for hver jobb og hver cache: Complete, Complete with connections, Incomplete, Unavailable eller Not recorded. Du vet hvilke SBOM-er du kan stole på, og hvilke som trenger en nærmere titt.
Erstatter en SBOM fra bygget SBOM-skannere?
For programvaren du bygger, ja: SBOM-en for utgivelsene dine bør komme fra byggene som laget dem. For images og binærfiler fra tredjeparter som du ikke har bygget, er en skanner fortsatt det praktiske valget. SBOM-verktøy sammenlignet går gjennom alternativene.
Hvilken SBOM-generator bruker CRACI?
Ingen. CRACI skanner ikke filer. En pakkebevisst proxy på runnerne registrerer pakkene hver jobb henter fra npm, PyPI, RubyGems, Cargo, Go, Nix, OCI, apt, apk og Git-kilder, i tillegg til download-presets for Yocto og OpenEmbedded, og eksporterer resultatet i CycloneDX eller SPDX.
Sammenlign en SBOM fra ditt eget bygg
Book en demo og kjør en av workflowene dine på CRACI. Sett SBOM-en ved siden av den det nåværende verktøyet ditt produserer, og se hvor de skiller seg.
Book en demo