En SBOM er ikke bare et compliance-dokument; den er et praktisk værktøj til at forstå, hvad dit softwareprodukt reelt består af, og hvordan du vedligeholder det sikkert over tid. I denne artikel får du en konkret forklaring på, hvad en SBOM skal kunne i praksis, hvilke miljøer der typisk mangler den, og hvordan du får den ind som en robust del af din CI/CD.
Du får også en brugbar kobling mellem SBOM og sårbarhedshåndtering: hvordan CVE’er matches, hvordan du prioriterer rigtigt, hvordan patch windows planlægges, og hvordan exceptions håndteres uden at underminere sikkerheden. Undervejs binder vi det til CRA’s fokus på sikkerhed og vedligeholdelse i hele produktets livscyklus.
Hvad er en SBOM, og hvorfor betyder den noget?
En SBOM (Software Bill of Materials) er en maskinlæsbar komponentfortegnelse, der beskriver hvilke biblioteker, pakker og underkomponenter et softwareprodukt indeholder, inklusiv versioner og typisk også licens- og provenance-data. Den betyder noget, fordi den gør det muligt at reagere hurtigt og præcist, når en sårbarhed rammer din leverandørkæde eller dine tredjepartsafhængigheder.
Uden en SBOM gætter du ofte på, om du er påvirket af en given CVE, og du bruger tid på manuelt detektivarbejde i stedet for målrettet patching. En god SBOM reducerer responstid, forbedrer sporbarhed og gør audits langt mere effektive.
Hvad en SBOM skal kunne i praksis
Hvis SBOM’en kun er en fil, der kan eksporteres, men ikke kan bruges til beslutninger, har du ikke løst opgaven. Den skal understøtte både udvikling, drift, sikkerhed og compliance med klare datafelter og klare processer.
Komponentliste og afhængighedsgraf
Det grundlæggende er en komplet komponentliste: direkte og transitive afhængigheder. For moderne stacks er transitive afhængigheder ofte langt flere end de direkte, og de er lige så vigtige, fordi sårbarheder ofte ligger dybt nede i kæden.
Versioner, licenser og leverandørkæde-sporbarhed
SBOM’en skal mindst indeholde præcise versionsangivelser, så du kan afgøre påvirkning og patches. Den bør også indeholde licensinformation, så du kan vurdere juridisk risiko og kompatibilitet, og den bør understøtte leverandørkæde-sporbarhed: hvor komponenten kommer fra, og hvilken build der trak den ind.
- Komponent-identifikatorer (navn, package URL, hash hvor muligt)
- Versions- og build-metadata (semver, commit, build-id)
- Licenser (deklareret og detekteret, inkl. usikkerhed)
- Provenance (repository, registries, leverandørkilde)
- Afhængighedsrelationer (hvem afhænger af hvem)
- Signering og integritet (så SBOM’en kan stoles på)
Mini-konklusion: En SBOM er nyttig, når den kan knytte en konkret komponent til et konkret produkt, en konkret version og en konkret leverancekæde.
Hvilke systemer mangler typisk SBOM, og hvorfor?
Mange organisationer har en SBOM for enkelte applikationer, men store dele af porteføljen står uden. Det skyldes sjældent modvilje; det skyldes kompleksitet, uklare ejerskaber og tooling, der ikke passer til arkitekturen.
Monorepos: mange produkter, samme kodebase
I monorepos bliver det hurtigt uklart, hvad “produktet” er: en mappe, et build target, et deployable artifact eller en feature flag-konfiguration. En klassisk faldgrube er at generere én SBOM for hele repoet, hvilket bliver for bredt til at være handlingsorienteret. Du bør i stedet generere SBOM pr. build-artifact eller pr. release-enhed.
Microservices: mange builds, mange teams
Med microservices kan du i princippet lave SBOM pr. service, men i praksis mangler standarder for format, retention og distribution. Når hvert team gør det “på sin måde”, bliver det umuligt at samle et samlet risikobillede. Her er best practice at have fælles minimumskrav og en central SBOM-registrering, mens genereringen stadig ligger tæt på teamets pipeline.
Embedded og IoT: blanding af firmware, OS og tredjepart
Embedded-produkter har ofte binære blobs, leverandør-SDK’er og komponenter, der ikke kommer fra klassiske pakke-managers. Derudover lever firmware længe i felten, og opdateringsmuligheder kan være begrænsede. Her bliver SBOM’en ekstra vigtig for livscyklus-vedligeholdelse, men også sværere: du skal kunne beskrive både OS-pakker, biblioteker, drivere og eventuelle statisk linkede komponenter.
Mini-konklusion: De miljøer, der har mest brug for SBOM, er ofte dem, hvor den er sværest at få rigtigt på grund af uklare leveranceenheder og komplekse builds.
Sådan genererer du SBOM i CI: hvornår, hvor gemmes den, og hvem ejer den?
SBOM skal være en del af den automatiserede leveranceproces, ikke en manuel aktivitet før en audit. Målet er gentagelighed: samme input giver samme output, og output kan spores til en build.
Hvornår i pipeline?
Generér SBOM efter dependency resolution og build, men før release-artefakter publiceres. På den måde afspejler den den faktiske leverance, og du kan stoppe eller markere builds, der bryder politikker. For container-baserede services giver det ofte mening at generere både en “source/dependency SBOM” og en “image SBOM”, fordi runtime-laget kan indeholde ekstra pakker.
Hvor gemmes den?
SBOM’er skal opbevares som artefakter på linje med build outputs. Praktisk fungerer det godt at gemme dem i artifact repository, container registry som tilknyttede metadata, eller i en dedikeret SBOM-database, så de kan søges og sammenlignes over tid.
Midt i implementeringen støder mange på CRA-krav om sporbarhed og vedligeholdelse, og her er SBOM en central byggesten, fordi den binder release, komponenter og ansvar sammen på en måde, der kan dokumenteres.
Hvem “ejer” SBOM’en?
Ejerskab handler om to ting: hvem producerer den, og hvem er ansvarlig for at reagere på det, den afslører. Typisk bør udviklingsteamet eje genereringen i CI, fordi de kontrollerer builden. Sikkerhed eller platform-teamet kan eje politikker, standardformat, signering, retention og det centrale overblik. Det vigtigste er, at ejerskab ikke bliver diffust, så SBOM’en ender som “noget man også burde”.
- Definér standardformat (fx CycloneDX eller SPDX) og minimumsfelter
- Integrér generering i pipeline for hver release-enhed
- Signér SBOM og knyt den til build-id og commit
- Gem centralt med søgbarhed og versionshistorik
- Automatisér scanning og policy checks ved hver build
- Definér ansvar for triage og remediation pr. produkt
Mini-konklusion: SBOM i CI virker, når den er automatisk, versioneret, signeret og forankret i et klart ansvar pr. release.
SBOM og sårbarhedshåndtering: fra CVE-match til handling
Den store praktiske værdi opstår, når SBOM’en forbindes med sårbarhedsdata, så du kan afgøre påvirkning og prioritere patches. Det kræver god identifikation af komponenter, stabile navne, og en proces for triage.
CVE match: undgå falske positiver og falske negativer
CVE-match sker typisk via package-identifikatorer og versionsintervaller. Hvis din SBOM kun har “navn” uden entydig identifikator, får du støj. Brug derfor standardiserede identifikatorer, og sørg for at medtage transitive dependencies. For embedded kan det også kræve mapping fra binære komponenter til kildemoduler eller leverandørpakker.
Prioritering: kontekst slår rå severity
CVSS alene er sjældent nok. Du bør kombinere severity med eksponering (internet-vendt, intern, offline), udnyttelsesgrad (kendt exploit, aktivt misbrug), og hvor komponenten ligger i systemet. En høj CVSS i en ikke-eksponeret komponent kan være mindre akut end en moderat CVSS i en kritisk gateway.
Mini-konklusion: En SBOM gør triage hurtigere, men kun hvis du beriger den med kontekst om, hvor komponenten bruges.
Patch window, exceptions og governance uden flaskehalse
Når du har match’et CVE’er til konkrete komponenter, kommer den svære del: at få rettet sikkert og hurtigt uden at stoppe forretningen. Her hjælper SBOM’en dig med at se, hvilke produkter der deler samme sårbare komponent, og dermed hvor du kan lave koordinerede opgraderinger.
Patch windows: planlæg efter risiko og release-rytme
Definér patch windows pr. produktkategori: kritiske internet-eksponerede services kan have korte windows, mens interne batch-systemer kan have længere. SBOM’en hjælper dig med at måle, hvor ofte du rammes af kritiske afhængigheder, og om du bør ændre dependency-strategi eller release-kadence.
Exceptions: dokumentér, begræns og udløbssæt
Exceptions er nogle gange nødvendige: måske findes ingen patch, eller opgraderingen bryder kompatibilitet. Men exceptions må ikke blive permanente. Best practice er at knytte exception til en udløbsdato, en kompensationskontrol (fx WAF-regler, feature deaktivering, netværkssegmentering) og et klart ansvar. SBOM’en gør det muligt at se, hvor exceptionen faktisk gælder, og at følge op, når komponenten dukker op i andre produkter.
- Kræv tidsbegrænsede exceptions med udløbsdato
- Knyt exceptions til konkrete komponentversioner, ikke “biblioteket generelt”
- Beskriv kompensationskontroller og verifikationsmetode
- Gennemgå exceptions fast (fx månedligt) og luk dem aktivt
Mini-konklusion: God governance handler ikke om flere møder, men om klare regler, automatisering og konsekvent opfølgning.
Runtime-mapping: når build-SBOM ikke er nok
En hyppig misforståelse er, at SBOM for kildekode eller build automatisk beskriver det, der kører i produktion. Men runtime kan afvige: base images opdateres, hotfixes lægges på, feature flags ændrer loaded moduler, eller en platform injicerer pakker. Derfor bør du koble SBOM til runtime-inventar, især for containere og embedded.
Sådan kobler du til drift
Praktisk kan du knytte SBOM til release-artefakter og derefter mappe deployed versioner via deployment-metadata. For containerplatforme kan du bruge image digest som bro mellem SBOM og runtime. For embedded kan serienummer, firmware-version og build-id fungere som nøgle, så du kan sige: “denne enhed i felten indeholder disse komponenter”.
Uden runtime-mapping risikerer du at patche det forkerte eller overse sårbarheder, der kun findes i driftlaget. Det er også her CRA’s livscyklus-fokus bliver konkret: du skal kunne vedligeholde det, der faktisk er deployed, ikke kun det, du engang byggede.
Hvad koster det, og hvordan kommer du i gang uden at drukne?
Omkostningen ved SBOM består mest af proces og vedligeholdelse, ikke selve filgenereringen. Mange værktøjer kan generere SBOM automatisk, men værdien afhænger af standardisering, datakvalitet, lagring, og integration til sårbarhedsstyring. For en typisk organisation er den første uge ofte brugt på at definere format, felter og ejerskab, og derefter på at få 1-2 pilotprodukter på plads.
En pragmatisk start er at vælge de mest kritiske produkter og få en minimal, men korrekt SBOM i CI, før du udvider. Perfektion fra dag ét forsinker ofte implementeringen. Det vigtigste er, at SBOM’en kan reproduceres, versionsstyres og bruges i triage.
Mini-konklusion: Start småt med højrisiko-produkter, men byg det på en måde, der kan skaleres på tværs af teams og teknologier.
SBOM anti-patterns: sådan fejler implementeringen i praksis
Selv gode intentioner kan ende i en SBOM, der aldrig skaber sikkerhedsværdi. Her er de mest almindelige anti-patterns, og hvordan du undgår dem.
- Genereres én gang og glemmes: løs med automatisk generering ved hver release og tydelig retention-policy
- Ingen mapping til runtime: knyt SBOM til artifacts og deployment-metadata, ellers bliver triage upræcis
- Ingen retention: gem historik, så du kan svare på “hvad kørte vi i marts?” og håndtere lang levetid
- Uklare ejere: placer ansvar hos teamet for generering og hos sikkerhed/platform for politikker og overblik
- For bred SBOM: monorepo-SBOM uden release-scope giver støj; generér pr. leveranceenhed
- Licenser ignoreres: manglende licensdata skaber juridiske overraskelser sent i processen
CRA peger i praksis på, at sikkerhed og vedligeholdelse ikke slutter ved release. En SBOM, der er levende, versionsstyret og koblet til sårbarhedshåndtering, er en af de mest direkte måder at operationalisere det livscyklus-ansvar på.