Hoppa till huvudinnehållet

SBOM:er (Software Bill of Materials)

En SBOM (Software Bill of Materials) är ingredienslistan för ett bygge: varje direkt och transitivt beroende som byggts in i en artefakt, med versioner och hashar. fremforge lagrar de SBOM:er som din CI tar fram, så att inventeringen finns kvar över byggen, rotationer av images och glidning i beroenden.

När SBOM:er genereras automatiskt

Det finns inget att installera. fremforge genererar centralt en SBOM i CycloneDX 1.6 för varje pull request, på sina egna runners, och knyter den SBOM:en till en release när du publicerar en: vilken tagg som helst, inklusive de vanliga semver-/calver-formerna (v1.2.3, v2026.06).

Vi skannar medvetet inte om vid release. En SBOM är en funktion av källträdet, och trädet du släpper har redan skannats som head för den pull request som mergade det, så en andra generering skulle ge en byte-identisk fil. När du publicerar en release markeras i stället den SBOM som redan finns för exakt den commiten som releasens SBOM. Två följder som är bra att känna till:

  • Det sker direkt. Inget bygge körs, så releasens SBOM finns tillgänglig så snart releasen är publicerad.
  • Kopplingen görs på serversidan. fremforge löser upp din tagg till dess commit via Forgejo och matchar på den commiten, så inget i ett bygge kan göra anspråk på en release-SBOM som det inte har förtjänat.

Om du publicerar en release för en commit som aldrig gått genom en pull request (en tagg på en mycket gammal commit, eller ett repo vars historik är äldre än skanningen) finns det ingen SBOM att knyta. Den releasen rapporteras som otäckt i stället för att tyst hoppas över; kör om en skanning på commiten för att täcka den.

Utlös en SBOM genom att tagga en release

Från kommandoraden:

git tag v1.2.3
git push origin v1.2.3

Från Forgejos gränssnitt: öppna repot → Utgåvor → Ny utgåva, ange ett taggnamn som börjar med v (t.ex. v1.2.3) och klicka på Publish.

En engångs-SBOM för en godtycklig commit finns också via fliken Actions → SBOM (Syft) → Run workflow.

Varför binds bara en release? En SBOM genereras för varje pull request, men bara den för en commit som släpps blir en release-SBOM: revisorer vill ha SBOM:en “i det ögonblick vi levererade release X”. Att binda vid en release håller antalet release-SBOM:er i proportion till hur ofta du faktiskt släpper releaser.

Vad fremforge accepterar

fremforge genererar SBOM:er i både CycloneDX 1.6 och SPDX 2.3, och accepterar båda vid inläsning:

  • CycloneDX JSON (1.6): inventeringen som varje fremforge-funktion läser (koppling till release, kontrollen av tom inventering, översikten). Det bredare ekosystemet av verktyg (Trivy, Syft, anchore) skriver CycloneDX direkt.
  • SPDX JSON (2.3): genereras bredvid av samma Syft-körning vid varje PR-skanning och lagras under samma bygge, så att sidan med SBOM:er erbjuder båda nedladdningarna för en release. Dina egna uppladdningar kan vara CycloneDX 1.5–1.7 eller SPDX 2.x/3.x; inläsningen validerar specVersion / spdxVersion innan de lagras.

SPDX-dokumentet är ett exportformat som genereras i mån av möjlighet: för ett mycket stort repo vars två dokument tillsammans skulle överskrida leveransgränsen på 14 MiB lagras bara CycloneDX-SBOM:en, så att inventeringen aldrig går förlorad för att ge plats åt det andra formatet.

Varje SBOM lagras med:

  • SHA-256-digesten för SBOM-filen. Den som laddar upp skickar den och servern räknar om den, så en avkortad eller ändrad uppladdning avvisas.
  • Ett valfritt in-toto-attesteringspaket (JSONL), signerat med Cosign när ditt arbetsflöde signerar SBOM:en. Inläsningen validerar JSONL-formen + in-toto-fälten på varje rad innan det lagras.
  • Artefaktens namn + version, exakt som ditt arbetsflöde namnger den. Används för nyckeln för deduplicering (samma digest + namn + version = en rad, inte många).

Hårt tak på 5 MiB per SBOM. Inläsningsendpointen returnerar 413 payload-too-large över det; dela upp stora monorepo-SBOM:er per modul om du når taket.

Så pushar du en SBOM från CI

fremforges runner-image levereras med Syft och Trivy, så de flesta arbetsflöden klarar sig med ett kort utdrag:

- name: Generate + push SBOM
  run: |
    syft packages dir:. --output cyclonedx-json=sbom.json
    # The digest is the SHA-256 of the SBOM file itself; the server recomputes it
    # and refuses a mismatch with 400 digest-mismatch.
    DIGEST=$(sha256sum sbom.json | cut -d' ' -f1)
    curl -sS --fail \
      -H "Authorization: Bearer ${{ secrets.FREMFORGE_API_TOKEN }}" \
      -F "sbom=@sbom.json" \
      -F "artifact_name=myapp" \
      -F "artifact_version=${GITHUB_SHA}" \
      -F "sha256_digest=${DIGEST}" \
      -F "format=cyclonedx-json" \
      "https://frem.sh/_app/api/v1/orgs/${ORG}/sboms"

PAT:en behöver scopet sboms:write; skapa en under Organisationens administration → API-token med scopet för SBOM-push ikryssat.

Två valfria fält registrerar var artefakten körs och vilket repo den byggdes från:

  • environment: den miljöklass som artefakten körs i, en av sandbox, development, test eller production. Allt annat avvisas med invalid-environment.
  • source_repo: repot som artefakten byggdes från, som owner/repo. Allt annat avvisas med invalid-source-repo.
      -F "environment=production" \
      -F "source_repo=acme/payments-api" \

Inget av fälten ändrar lagringstiden eller någon spärr. En CycloneDX-SBOM med source_repo lånar också ut sin beroendegraf till det repots beroendevägar, och det är så Maven- och Gradle-repon får dem.

Var SBOM:er visas i administrationsgränssnittet

Organisationens administration → Säkerhet › Komponenter › SBOM:er listar varje inläst SBOM, grupperad per artefakt. Varje rad visar:

  • Artefaktens namn + version + SHA-256-digest
  • Format (CycloneDX / SPDX) + storlek
  • Tidpunkt för inläsning + användaren/PAT:en som pushade den
  • Länken “Verify signature” när en attestering är bifogad

Hur SBOM:er samverkar med andra säkerhetssignaler

  • Scorecard: styr poängen för Dependencies + Vulnerabilities i beräkningen av OpenSSF Scorecard.
  • OSV-rekommendationer: när ett OSV-säkerhetsmeddelande matchar en komponent som listas i en SBOM visas rekommendationen med påverkan förankrad i SBOM:en (“this affects build myapp@v1.2.3 from 2026-05-12”).
  • Cosign: flödet för signering av SBOM:er använder samma förtroenderot för Cosign som signering av images. Se Cosign för verifieringsvägen.

Lagring

Releasers SBOM:er sparas så länge din organisation finns. SBOM:er för byggen som inte släppts raderas efter din lagring av bevis för sbom: 14 dagar som standard, 0 till 3650 dagar. SBOM:en för standardbranchens head, aktuella images SBOM:er och paketfilers SBOM:er sparas oavsett ålder. Inget raderas medan ett rättsligt bevarande gäller. (Fram till 2026-10-08 stod det i det här avsnittet att SBOM:er följde förinställningarna för granskningslagring; det gjorde de aldrig.)

Se även

  • Cosign: signering av images + SBOM:er.
  • OSV-rekommendationer: sårbarheter matchade mot SBOM-komponenter.
  • Scorecard: SBOM:er styr poängen för beroenden + sårbarheter.
  • API-referens: inläsningsendpointen POST /_app/api/v1/orgs/{slug}/sboms.