123% fler rapporterade CVE:er per dag 2026 än förra året.

SBOM

SBOM-exempel

Det snabbaste sättet att förstå en SBOM är att läsa en. Här är samma lilla applikation i CycloneDX och i SPDX, med vad varje fält betyder, hur en svag SBOM ser ut och hur du kontrollerar din egen.

Uppdaterad

Applikationen i exemplen

Båda filerna beskriver example-api 2.4.0, en påhittad Node.js-tjänst med ett direkt beroende, express. Express är i sin tur beroende av accepts, så exemplen visar också ett transitivt beroende. En riktig SBOM av en Express-applikation listar många fler komponenter, men strukturen är densamma.

Exempel på en CycloneDX-SBOM

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.6",
  "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
  "version": 1,
  "metadata": {
    "timestamp": "2026-10-30T09:00:00Z",
    "lifecycles": [{ "phase": "build" }],
    "tools": {
      "components": [
        { "type": "application", "name": "example-sbom-tool", "version": "1.0.0" }
      ]
    },
    "component": {
      "type": "application",
      "bom-ref": "example-api",
      "name": "example-api",
      "version": "2.4.0"
    }
  },
  "components": [
    {
      "type": "library",
      "bom-ref": "pkg:npm/[email protected]",
      "name": "express",
      "version": "4.21.2",
      "purl": "pkg:npm/[email protected]",
      "licenses": [{ "license": { "id": "MIT" } }]
    },
    {
      "type": "library",
      "bom-ref": "pkg:npm/[email protected]",
      "name": "accepts",
      "version": "1.3.8",
      "purl": "pkg:npm/[email protected]",
      "licenses": [{ "license": { "id": "MIT" } }]
    }
  ],
  "dependencies": [
    { "ref": "example-api", "dependsOn": ["pkg:npm/[email protected]"] },
    { "ref": "pkg:npm/[email protected]", "dependsOn": ["pkg:npm/[email protected]"] }
  ]
}
Fält Vad det berättar
specVersion Vilken version av formatet filen använder, så att verktyg kan tolka den.
serialNumber, version Vilken SBOM det här är, och vilken revision av den.
metadata.lifecycles När SBOM:en togs fram. Här, under bygget.
metadata.tools Vilket verktyg som tog fram den. Två verktyg kan rapportera samma commit olika.
metadata.component Produkten som SBOM:en beskriver.
purl Package URL, identifieraren som låter ett verktyg matcha komponenten mot säkerhetsmeddelanden.
licenses Komponentens deklarerade licens.
dependencies Vem som drar in vem. Det är detta som gör accepts synligt som ett transitivt beroende.

Exempel på en SPDX-SBOM

{
  "spdxVersion": "SPDX-2.3",
  "dataLicense": "CC0-1.0",
  "SPDXID": "SPDXRef-DOCUMENT",
  "name": "example-api-2.4.0",
  "documentNamespace": "https://example.com/spdx/example-api-2.4.0",
  "creationInfo": {
    "created": "2026-10-30T09:00:00Z",
    "creators": ["Tool: example-sbom-tool-1.0.0"]
  },
  "packages": [
    {
      "name": "example-api",
      "SPDXID": "SPDXRef-Package-example-api",
      "versionInfo": "2.4.0",
      "downloadLocation": "NOASSERTION"
    },
    {
      "name": "express",
      "SPDXID": "SPDXRef-Package-express",
      "versionInfo": "4.21.2",
      "downloadLocation": "NOASSERTION",
      "licenseDeclared": "MIT",
      "externalRefs": [
        {
          "referenceCategory": "PACKAGE-MANAGER",
          "referenceType": "purl",
          "referenceLocator": "pkg:npm/[email protected]"
        }
      ]
    },
    {
      "name": "accepts",
      "SPDXID": "SPDXRef-Package-accepts",
      "versionInfo": "1.3.8",
      "downloadLocation": "NOASSERTION",
      "licenseDeclared": "MIT",
      "externalRefs": [
        {
          "referenceCategory": "PACKAGE-MANAGER",
          "referenceType": "purl",
          "referenceLocator": "pkg:npm/[email protected]"
        }
      ]
    }
  ],
  "relationships": [
    {
      "spdxElementId": "SPDXRef-DOCUMENT",
      "relationshipType": "DESCRIBES",
      "relatedSpdxElement": "SPDXRef-Package-example-api"
    },
    {
      "spdxElementId": "SPDXRef-Package-example-api",
      "relationshipType": "DEPENDS_ON",
      "relatedSpdxElement": "SPDXRef-Package-express"
    },
    {
      "spdxElementId": "SPDXRef-Package-express",
      "relationshipType": "DEPENDS_ON",
      "relatedSpdxElement": "SPDXRef-Package-accepts"
    }
  ]
}

Informationen är densamma men ordnad på ett annat sätt. SPDX har en packages-lista och anger varje länk mellan objekten i relationships. licenseDeclared är vad paketet säger om sig självt, och downloadLocation kan vara NOASSERTION när verktyget inte vet. För hur de två formaten skiljer sig utöver layouten, se CycloneDX vs SPDX.

Så ser en svag SBOM ut

En fil kan vara giltig och ändå nästan oanvändbar. Se upp med följande:

  • Inga beroenderelationer. En platt lista visar att ett paket finns, men inte vad som drog in det, och det är vad du behöver veta för att åtgärda ett transitivt beroende.
  • Inga package URL:er. Utan en identifierare som en purl faller matchningen av en komponent mot säkerhetsmeddelanden tillbaka på gissningar utifrån namn.
  • Saknade licenser. Många fält som lämnats som NOASSERTION betyder att SBOM:en inte kan besvara licensfrågor.
  • Misstänkt få komponenter. En handfull komponenter för en stor applikation betyder oftast att bara direkta beroenden ingår, eller bara det som en lockfile deklarerade.
  • Inget om när eller hur. Utan ett verktyg och en genereringskontext kan du inte avgöra vad du kan lita på att SBOM:en täcker.
  • Tystnad om luckor. En bra SBOM säger vad den inte kunde se. De flesta filer tar bara slut, och läsaren utgår från att de är kompletta.

Så kontrollerar du din egen SBOM

  1. Validera formatet. Kör den genom en schemavalidator för dess format och version, eftersom ett verktyg som inte kan tolka filen inte heller kan använda den.
  2. Kontrollera fälten. Jämför den med 2026 Minimum Elements eller listan som din kund bad om.
  3. Sök efter något du känner till. Välj ett transitivt beroende, ett paket från din basavbild och ett byggverktyg, och se vilka av dem som finns med.
  4. Jämför två källor. Generera en andra SBOM med en annan metod och titta på skillnaden. Varje extra komponent i den ena filen är en fråga om den andra.

En SBOM från bygget med CRACI

CRACI exporterar samma format. Skillnaden är var innehållet kommer ifrån: CRACI registrerar vad varje GitHub Actions-jobb hämtade, så varje komponent i SBOM:en drogs faktiskt in i bygget, och paket som återställs från CI-cachar markeras som sådana. GitHub Actions som arbetsflödet körde visas också som komponenter, fastlåsta till den commit som användes. Varje jobbs SBOM har dessutom en fullständighetsstatus, så luckorna anges i stället för att lämnas åt dig att hitta. Se SBOM-generering under bygget, eller hur SBOM-verktyg står sig mot varandra.

SBOM-exempel: vanliga frågor

Hur ser en SBOM ut?

Oftast är den en JSON-fil, ibland XML. Den börjar med data om själva SBOM:en, som verktyg och tidsstämpel, listar sedan varje komponent med namn, version, identifierare och licens och beskriver till sist hur komponenterna är beroende av varandra.

Är en SBOM en JSON-fil?

Oftast, eftersom JSON är den mest använda kodningen av både CycloneDX och SPDX. Båda formaten har även andra kodningar, och SPDX har dessutom en tag-value-form i text.

Vad är en purl i en SBOM?

En purl, package URL, är en standardiserad identifierare för ett paket, till exempel pkg:npm/[email protected]. Den anger ekosystem, paket och version i en enda sträng, vilket gör att verktyg kan matcha komponenten mot sårbarhetsdata på ett tillförlitligt sätt.

Hur många komponenter ska en SBOM ha?

Det finns inget rätt antal, men den ska innehålla transitiva beroenden, som oftast är betydligt fler än de direkta. Mycket få komponenter för en stor applikation betyder oftast att verktyget bara såg en del av den.

Går det att se en SBOM för ett open source-projekt?

Ibland. Vissa projekt publicerar SBOM:er med sina releaser, och GitHub kan exportera en från ett repos beroendegraf. Den exporten speglar vad repot deklarerar snarare än vad ett specifikt bygge använde.

Jämför din SBOM med en registrerad

Kör ett GitHub Actions-arbetsflöde på CRACI och se vilka komponenter din nuvarande SBOM inte listar.

Boka en demo