SBOM
SBOM-generering på tværs af udviklingsteams: én politik, alle pipelines
De fleste organisationer har ikke et SBOM-problem; de har seks SBOM-processer. Fastlæg outputtet først: ét format, ét sæt felter, ét tidspunkt for generering, ét lager. Flyt derefter hvert teams pipeline, så den lever op til det, helst med generering inde i release-buildet. Kunder, revisorer og regulatorer som CRA ser på SBOM'en og på processen bag den, ikke på hvilken scanner du har købt.
Opdateret
Hvorfor scannere pr. team ikke bliver til et SBOM-program
Peg fem værktøjer mod det samme produkt, og du får fem SBOM'er. Forskellene er strukturelle, ikke fejl:
- Forskellige input, læst på forskellige tidspunkter. Ét værktøj læser lockfilen, et andet det installerede afhængighedstræ, et tredje container-imaget, et fjerde binærfilen. Hvert af dem ser et forskelligt udsnit af produktet.
- Forskellige navne for det samme. Ét identificerer komponenter med package URL, et andet med CPE, et tredje kun med filnavn. To SBOM'er, der beskriver det samme bibliotek, kan ikke kobles på en fælles nøgle.
- Forskellig dybde. Nogle viser kun direkte afhængigheder, nogle hele det transitive træ, og nogle viser også build-værktøjer. Hvorfor generatorer er uenige om det samme repository, vises i open source SBOM-generatorer.
- Nogle værktøjer besvarer et andet spørgsmål. Sårbarhedsscannere til infrastruktur rapporterer, hvad der er installeret på kørende hosts. Det er nyttigt for driften, og det er ikke en beskrivelse af det produkt, du leverer.
Konsekvensen: Du kan ikke flette, deduplikere eller sammenligne SBOM'er på tværs af produkter, og du kan ikke vise en revisor én proces, for der er ingen.
| Metode | Input, den læser | Hvornår | Hvad den overser | Typisk identifikator |
|---|---|---|---|---|
| Scanner til lockfiler eller manifester | Lockfiler og manifester i checkoutet | Før eller efter buildet | Alt, hvad ingen lockfile viser: install-hooks, downloads fra build-scripts, base-images | Package URL |
| Scanner til container-images | Pakkedatabaser og filer i imaget | Efter buildet | Værktøjer, der kun bruges i buildet, indkompileret kode, alt uden en pakkepost | Package URL for styresystem- og sprogpakker |
| Scanner til binærfiler eller firmware | Strenge og signaturer i binærfilen | Efter buildet | Vished: versioner og komponenter udledes | CPE eller udledt navn |
| Sårbarhedsscanner til hosts | Installeret software på kørende servere | I drift | Produktet, som det leveres til kunderne | CPE eller leverandørens produktnavn |
| Registrering under buildet | Hvad release-buildet hentede | Under buildet | Software, du ikke har bygget; hvad den ikke kunne se, markeres som ufuldstændigt | Package URL |
SBOM-politikken: hvad der skal standardiseres
Standardisér SBOM'en, ikke scanneren. Politikken fastlægger outputtet og processen; hver pipeline lever op til den med den bedste generator, den kan køre. Hver række nedenfor er noget, du kan kontrollere.
| Krav | Reglen | Hvorfor | Sådan kontrollerer du det |
|---|---|---|---|
| Omfang | Hver produktrelease, der leveres til en kunde, inklusive firmware og container-images. Interne værktøjer valgfrit. | Kunder og regulatorer spørger til det, du leverer. | Hver release i release-registret har en SBOM. |
| Format og version | Ét primært format, CycloneDX eller SPDX, med en minimumsversion. Acceptér det andet efter ønske. | Ét format betyder én parser, én validator og ét lager. BSI TR-03183-2 kræver CycloneDX 1.6 eller nyere eller SPDX 3.0.1 eller nyere, et fornuftigt minimum for kunder i EU. | Skemavalideringen rapporterer format og version. |
| Minimumsfelter | En package URL på hver komponent, der har en, kun en CPE hvor der ingen findes, leverandør, version, deklareret licens, afhængighedsrelationer, værktøjets navn og version, tidsstempel og genereringskontekst. | Det er disse felter, matching, licensgennemgang og revisioner bruger. Afstem dem med minimumselementerne på hvad er en SBOM. | Et felttjek i pipelinen tæller manglende værdier. |
| Hvornår den genereres | I det CI-build, der producerer releasen, hver gang. Ikke ved revisionen, ikke på en bærbar. | Et nyt build er ikke det samme build; se SBOM'er fra buildet. | SBOM'ens build-ID matcher releasens build-ID. |
| Dybde | Hele det transitive træ, ikke kun øverste niveau. | CRA's minimum er afhængighederne på øverste niveau; sårbarheder og kunder går dybere. | Der findes afhængighedsrelationer under første niveau. |
| Hvor den gemmes | Sammen med release-artefaktet, så den kan hentes efter produkt og version. | En SBOM, som ingen kan finde, når en advisory lander, er ikke dokumentation. | Hent SBOM'en for en tilfældig release efter produkt og version. |
| Opbevaring | Mindst produktets supportperiode plus den opbevaring af dokumentation, som dine regler kræver. | CRA fastsætter en opbevaringsperiode for teknisk dokumentation, og SBOM'en er en del af den. | Sammenlign politikkens periode med hvert værktøjs opbevaring. |
| Validering | Hver SBOM skemavalideres i pipelinen; en ugyldig får buildet eller release-gaten til at fejle. | Ugyldige SBOM'er fejler lydløst i kundens værktøjer. | Release-gatens log viser et valideringstrin. |
| Ejerskab | Produktteamet ejer genereringen; produktsikkerhed ejer politikken, valideringsreglerne og rapporteringen af dækning. | Generering kræver pipelinens ejer; konsistens kræver én ejer af reglerne. | Hver pipeline har en navngiven ejer. |
| Undtagelser | Et register over navngivne, tidsbegrænsede undtagelser: team, begrundelse, slutdato. | Politikken overlever teams, der endnu ikke kan efterleve den. | Ingen undtagelse har passeret sin slutdato. |
Tjeklisten i bedste praksis for SBOM dækker reglerne for en enkelt SBOM; denne politik er laget over dem. Hvert team erklærer, hvordan dets pipeline lever op til politikken, i en fil ved siden af pipelinen:
# sbom-policy.yaml, one per release pipeline
product: gateway-firmware
owner: team-gateway
format: cyclonedx
spec_version: "1.6"
generated_in: release-build
generator: build-time-recording
store: artifact-registry
validation: schema, fail-on-errors
exception: none
Generér i buildet, ikke pr. team bagefter
Generering under buildet er standarden at sigte efter. Den beskriver det build, der blev leveret, den inkluderer skjulte afhængigheder, som ingen lockfile viser, og én mekanisme producerer SBOM'er med samme form for hvert team på den pipeline. Forskellen er lettest at forklare med et køkken: En scanner smager på suppen og gætter opskriften; en registrering holder øje med, hvad der kommer ind i køkkenet.
En scanner er stadig det rigtige værktøj til images, du ikke har bygget, til binærfiler fra tredjepart og til ældre produkter uden CI. Skriv det i politikken, og registrér genereringskonteksten, så en læser ved, hvad hver SBOM så.
| Situation | Genereringsmetode | Genereringskontekst, der skal registreres |
|---|---|---|
| Release bygget i CI, du selv styrer | Registrér buildet, eller kør en generator inde i release-jobbet | "Registreret under buildet" eller "efter installation, ud fra filer" |
| Container-image bygget i CI | Registrér image-buildet; scan resultatet for dets styresystempakker, hvis registreringen ikke dækker dem | Build-ID og image-digest |
| Image eller appliance fra tredjepart | Image-scanner plus leverandørens SBOM, hvis der er en | "Scannet output, ikke bygget af os" |
| Binærfil fra en leverandør | Bed om leverandørens build-SBOM; binæranalyse som kontrol | Leverandør, version, hvordan den blev anskaffet |
| Ældre produkt uden pipeline | Scan det leverede artefakt; planlæg en pipeline | "Scannet output" og en undtagelse med en slutdato |
Blandet CI: GitHub Actions, GitLab og Jenkins i én organisation
Politikken er bevidst uafhængig af CI: Den definerer outputtet, så en GitLab- eller Jenkins-pipeline kan leve op til den med et generatortrin, og en GitHub Actions-pipeline kan bruge registrering under buildet. Regler for et generatortrin:
- Kør det i release-jobbet, efter installationstrinnet, ikke i et separat job, der installerer igen.
- Fastlås generatorens version, og fastlås CI-actions til et commit, ikke et tag. Hvorfor det især betyder noget for scannere, gennemgås i open source SBOM-generatorer.
- Registrér genereringskonteksten som "efter installation, ud fra filer", så læserne ved, hvad den så.
- Validér outputtet mod det samme skema som alle andre pipelines.
Open source-generatorer som Syft, Trivy og cdxgen kan alle skrive CycloneDX og SPDX, så formatreglen tvinger ikke et bestemt værktøjsvalg igennem. Se SBOM-værktøjer sammenlignet for at sammenligne dem.
CRACI understøtter i dag GitHub Actions; GitLab CI og Jenkins er på roadmappen, uden dato. Konsekvensen for udrulningen: Start registrering under buildet, hvor GitHub Actions bruges, behold generatortrin andre steder, og følg begge i den samme dækningsrapport.
Når en kunde vil have en bestemt formatversion
En kunde beder om CycloneDX 1.6, og dine værktøjer skriver 1.7. Det sker, fordi deres indlæsningsværktøj eller deres egen politik er låst til en version; BSI's minimum er 1.6, så kunder i EU nævner den ofte. Dine muligheder:
- Spørg, om den nyere version accepteres. Det gør den ofte.
- Konvertér med CycloneDX CLI, validér derefter mod målversionen, og kontrollér, hvad der gik tabt: Felter, der kun findes i den nyere specifikation, fjernes.
- Ved en anmodning om SPDX konverterer den samme CLI til og fra SPDX JSON 2.3. Dens dokumentation advarer om, at konvertering mellem SPDX og CycloneDX "kan medføre tab af visse oplysninger".
cyclonedx convert --input-file bom.cdx.json --input-format json \
--output-file bom-1.6.cdx.json --output-format json --output-version v1_6
cyclonedx validate --input-file bom-1.6.cdx.json --input-format json \
--input-version v1_6 --fail-on-errors
Validatoren kontrollerer mod CycloneDX 1.7, medmindre du angiver --input-version. Politikkens regel: Behold den
oprindelige SBOM som registreringen. En konverteret kopi er en afledt levering; gem afledningen (værktøj, version, dato) sammen med
den. Mere om at besvare disse anmodninger i kunders SBOM-anmodninger og om de to
formater i CycloneDX vs SPDX.
Licensdata til juridisk afdeling
Den samme SBOM kan tjene den juridiske afdeling, hvis politikken kræver de rigtige felter. Juridisk afdeling har brug for licensen for hver komponent, forskellen mellem en deklareret licens (hvad pakken angiver) og en konkluderet (hvad nogen har verificeret), copyleft-forpligtelser og en liste over komponenter uden licens. CycloneDX 1.6 markerer licenser som deklarerede eller konkluderede, og SPDX har separate felter til begge.
- Kræv SPDX-licensidentifikatorer eller -udtryk som
MITellerApache-2.0 OR MIT. -
Markér
NOASSERTIONog manglende licenser til gennemgang. I SPDX betyderNOASSERTION, at der ikke blev truffet nogen afgørelse, eller at der ikke blev givet nogen oplysning; det er ikke en licens. - Send copyleft-licenser til juridisk afdeling før releasen, ikke efter.
En SBOM indeholder deklarerede licenser. En gennemgang af licensoverholdelse, med konkluderede licenser, notitser og forpligtelser, er juridisk arbejde eller en opgave for et specialiseret værktøj; se licensoverholdelse for open source.
Udrulning team for team
| Fase | Ejer | Udgangskriterium | Typisk forhindring |
|---|---|---|---|
| 1. Overblik: produkter, pipelines, CI-systemer og nuværende generatorer, én række pr. release-pipeline | Produktsikkerhed | Hvert leveret produkt har en række | Ingen ved, hvilken pipeline der bygger en release |
| 2. Offentliggør politikken med undtagelsesregistret | Produktsikkerhed | Politikken er godkendt og offentliggjort | Debat om, hvilket værktøj der skal påbydes (politikken påbyder ikke noget) |
| 3. Pilot med et eller to teams, der har en grund: en kundeanmodning, en deadline, et produkt, som det nuværende værktøj ikke kan håndtere | Pilotteams | Pilot-releases leveres med SBOM'er, der overholder politikken | Teams uden en presserende grund nedprioriterer det |
| 4. Tilføj valideringsgates i pilotpipelines | Pilotteams | En ugyldig SBOM får releasen til at fejle | Frygt for at blokere releases; start med en advarsel |
| 5. Udvid pr. CI-system; udfas en scanner pr. team først, når erstatningen lever op til politikken | Produktteams | Dækningsmålet er nået pr. CI-system | Pipelines, som ingen ejer |
| 6. Rapportér dækning månedligt | Produktsikkerhed | Rapporten går til ledelsen hver måned | Målinger beregnet i hånden |
Overbliksregnearket i fase 1 bør være det sidste; at komme væk fra regneark gennemgås i SBOM-automatisering. Et Yocto-baseret produkt er en almindelig pilot, fordi generelle scannere har svært ved det; se hvorfor SBOM-scannere overser Yocto-builds.
Måling af dækning
Tallene, som ledelse og revisorer beder om, hver defineret som et forhold:
- Release-dækning: releases leveret med en SBOM, der overholder politikken ÷ leverede releases.
- Produktdækning: produkter med mindst én SBOM, der overholder politikken, i den aktuelle supportperiode ÷ produkter i support.
- Andel beståede valideringer: SBOM'er, der består valideringen ÷ genererede SBOM'er.
- Identifikatordækning: komponenter med en package URL (eller en CPE) ÷ komponenter.
- Licensdækning: komponenter med en deklareret licens ÷ komponenter.
- Fuldstændighed: SBOM'er, hvis generator angiver, at de er komplette ÷ SBOM'er. Kun muligt, hvor værktøjet rapporterer det.
- Tid til SBOM: tiden fra release til tilgængelig SBOM.
Et eksempel på en månedsrapport (illustrative tal):
| Måling | GitHub Actions-pipelines | GitLab- og Jenkins-pipelines | Alle |
|---|---|---|---|
| Release-dækning | 46 / 48 | 19 / 27 | 65 / 75 |
| Andel beståede valideringer | 100% | 92% | 97% |
| Identifikatordækning | 99% | 88% | 95% |
| Åbne undtagelser | 1 | 4 | 5 |
Som dokumentation over for en regulator eller en revisor består sættet af politikken, undtagelsesregistret, dækningsrapporten og nogle eksempler på SBOM'er. Det viser én proces, anvendt og målt. For CRA-siden, se CRA-guiden.
Sådan passer CRACI ind
For GitHub Actions-pipelines er CRACI runneren: Du angiver runs-on: craci, og hvert job får en registreret
SBOM uden et generatortrin. Hver SBOM har en fuldstændighedsstatus, de transitive afhængigheder, en package URL pr.
pakke og hver komponents deklarerede licens, og eksporteres som CycloneDX eller SPDX. Regler for licenspolitik kan blokere et
build, overvågede SBOM'er genevalueres løbende, og build-historikken viser, hvilke builds der indeholdt en sårbar
afhængighed. Det giver de teams politikkens rækker "genereret i release-buildet", "identifikator" og "licens" som
standard. SBOM'er fra tredjepart kan tilføjes, så indkøbte komponenter overvåges sammen med dine builds.
Se SBOM-generering med CRACI og SBOM'er i GitHub Actions.
Når CRACI ikke er svaret
- Teams på GitLab CI eller Jenkins: ikke i dag, det er på roadmappen. Brug et generatortrin, der lever op til politikken.
- GitHub Enterprise Server: understøttes ikke i dag.
- Scanning af infrastruktur og hosts, altså hvad der er installeret på servere, og fejlkonfigurationer: en anden opgave; behold de værktøjer.
- Binær- eller firmwareanalyse af leverandørers images, som du ikke bygger: CRACI registrerer builds og scanner ikke binærfiler.
- Lang opbevaring: CRACI opbevarer build-data i 180 dage som standard, med tilpasset opbevaring på Enterprise. Hvis din politik kræver SBOM'er i længere tid, så eksportér dem til dit eget lager.
SBOM-generering på tværs af teams: ofte stillede spørgsmål
Hvordan standardiserer vi SBOM-generering på tværs af teams, der bruger forskellige værktøjer?
Standardisér outputtet, ikke værktøjet. Skriv én politik, der fastlægger format og version, minimumsfelter, hvornår SBOM'en genereres, hvor den gemmes, hvor længe den opbevares, og hvem der validerer den. Lad hver pipeline leve op til den med den bedste generator, den kan køre, og mål dækningen op mod politikken.
Hvad skal en SBOM-politik indeholde?
Omfang, format og minimumsversion, minimumsfelter (package URL, leverandør, version, deklareret licens, afhængigheder, værktøj, tidsstempel, genereringskontekst), generering i release-buildet, fuld transitiv dybde, opbevaring sammen med releasen, opbevaringsperiode, validering i pipelinen, ejerskab og et register over tidsbegrænsede undtagelser.
Skal hvert team køre sin egen scanner, eller skal SBOM'er komme fra buildet?
Fra buildet, hvor det er muligt. En SBOM fra buildet beskriver det build, der blev leveret, og giver hvert team på den pipeline SBOM'er med samme form. Behold scannere til det, du ikke har bygget: images fra tredjepart, binærfiler fra leverandører og ældre produkter uden pipeline.
En kunde vil have vores SBOM i en ældre CycloneDX-version. Hvad gør vi?
Spørg først, om den nyere version accepteres. Hvis ikke, så konvertér en kopi med CycloneDX CLI (cyclonedx convert med --output-version v1_6), validér den mod den version, og kontrollér, hvilke felter der blev fjernet. Behold originalen som registreringen, og gem, hvordan kopien blev afledt.
Hvordan får vi licensdata fra vores SBOM'er videre til juridisk afdeling?
Kræv SPDX-licensidentifikatorer eller -udtryk i politikken, markér NOASSERTION og manglende licenser til gennemgang, og send copyleft-licenser til juridisk afdeling før releasen. SBOM'en indeholder deklarerede licenser; konkluderede licenser, notitser og forpligtelser kræver en licensgennemgang.
Hvordan måler vi SBOM-dækning på tværs af produkter?
Som forhold: releases leveret med en SBOM, der overholder politikken, produkter i support med en SBOM, der overholder politikken, andel beståede valideringer, komponenter med en package URL, komponenter med en deklareret licens, komplette SBOM'er hvor værktøjet rapporterer det, og tiden fra release til SBOM. Rapportér dem månedligt pr. CI-system.
Hvilken dokumentation skal vi bruge for at vise en revisor, at SBOM-genereringen er konsistent?
Politikken, undtagelsesregistret, den månedlige dækningsrapport og nogle eksempler på SBOM'er med deres genereringskontekst. Tilsammen viser de én proces, anvendt på hver release og målt, og det er det, en revisor eller en kunde kontrollerer.
Afprøv det på én GitHub Actions-pipeline
Book en demo, og kør én release-pipeline på CRACI. Få en SBOM registreret fra buildet, og kontrollér den op mod din politik.
Book en demo