Den 19 mars 2026 klockan 17:43 UTC loggade sig hotaktören TeamPCP in med ett enda komprometterat GitHub-token. Tolv dagar senare hade gruppen kapat fem av världens mest använda öppen källkodsverktyg för säkerhetsskanning, bland dem Trivy från Aqua Security, ett verktyg som används i uppskattningsvis 90 procent av alla cloud-native CI/CD-pipelines globalt. Ingen enskild organisation upptäckte intrånget innan skadan var skedd, för de flesta hade ingen komplett bild av vad som faktiskt låg i deras egna byggen. Den här guiden visar hur du bygger den bilden själv: en fullständig materialförteckning (SBOM) för din mjukvara, automatisk sårbarhetsskanning av varje beroende, och kryptografiskt signerade byggartefakter som går att verifiera från källkod till produktion.
Du kommer att sätta upp en fungerande pipeline med Syft för SBOM-generering, Grype för sårbarhetsskanning och Sigstore cosign för signering, allt kopplat till GitHub Actions. Vi går igenom varje steg med kommandon du kan köra direkt, pekar ut vanliga fällor, och avslutar med en färdig, komplett arbetsyta du kan klona rakt av. Guiden riktar sig till utvecklare och DevSecOps-team i Sverige och Norden som redan skriver kod dagligen men aldrig riktigt fått ordning på leveranskedjan.
Varför leveranskedjesäkerhet inte längre är valfritt 2026
OWASP flyttade upp Software Supply Chain Failures till plats A03 i sin uppdaterade Top 10:2025-lista, en position som tidigare tillhörde klassisk injektion. Det är ingen slump. Attackytan har flyttat sig från applikationskoden till allt som byggprocessen litar på utan att verifiera: paket från npm och PyPI, GitHub Actions-workflows, containerbaser och signeringsnycklar. Vår egen genomgång av TeamPCP-kampanjen visade hur en enda felkonfigurerad pull_request_target-regel i en YAML-fil, olöst i fyra månader trots att den flaggats redan i november 2025, öppnade dörren till fem separata ekosystem på tolv dagar.
Regelverket springer ikapp verkligheten. EU:s Cyber Resilience Act (förordning 2024/2847) trädde i kraft redan 10 december 2024, men de skarpa deadlinerna landar nu: från 11 september 2026 måste tillverkare av uppkopplade produkter rapportera aktivt utnyttjade sårbarheter inom 24 timmar, med böter på upp till 15 miljoner euro eller 2,5 procent av global omsättning för den som missar kraven. En SBOM är inte längre en trevlig bilaga till releasedokumentationen, den är den enda praktiska metoden att svara på frågan “använder vi det där paketet, och i så fall var?” inom loppet av en timme, inte en vecka.
Den här guiden bygger en konkret, testbar pipeline runt tre lager av skydd: synlighet (vad innehåller egentligen din mjukvara), verifiering (är något av det sårbart eller skadligt) och bevis (kan du kryptografiskt styrka att artefakten som körs i produktion är samma artefakt som byggdes och godkändes). Utan alla tre lager har du bara en falsk känsla av kontroll.
Förutsättningar och verktygsversioner
Innan du börjar, se till att du har följande på plats. Vi anger de senaste stabila versionerna som var aktuella i skrivande stund (augusti 2026); kör alltid respektive verktygs egen uppdateringskontroll innan produktionsbruk eftersom både Syft och Grype kontrollerar nya versioner automatiskt vid start.
| Verktyg | Senaste stabila version | Utgivningsdatum | Syfte i pipelinen |
|---|---|---|---|
| Syft (Anchore) | v1.42.4 | 8 april 2026 | Genererar SBOM i CycloneDX och SPDX-format |
| Grype (Anchore) | v0.112.0 | Bekräftad i Anchore Data Service 4 juni 2026 | Skannar SBOM och images mot kända sårbarheter |
| cosign (Sigstore) | v3.0.6 | 6 april 2026 | Signerar och verifierar containerimages och artefakter |
| OpenSSF Scorecard | v5.5.0 | 23 april 2026 | Poängsätter säkerhetshygienen hos dina beroendens repon |
| CycloneDX-spec | 1.7 | 21 oktober 2025 (ratificerad som ECMA-424 2:a utgåvan i december 2025) | SBOM-formatet Syft skriver till som standard |
| SLSA-ramverk | v1.2 | Godkänd 12 november 2025 | Nivåer för hur verifierbar din byggprocess är |
Utöver verktygen ovan behöver du: ett GitHub-konto med tillgång till Actions, Docker installerat lokalt för att testa image-byggen, och grundläggande förtrogenhet med YAML och kommandoraden. Du behöver inte vara säkerhetsspecialist, det här är precis den kompetensnivå guiden är skriven för.
Steg 1: Installera Syft och verifiera installationen
Syft är Anchores öppen källkods-verktyg för att skanna kod, containerimages och filsystem och bygga en fullständig lista över allt som ingår, från direkta beroenden till transitiva paket djupt nere i beroendeträdet. Installera det med det officiella skriptet:
curl -sSfL https://get.anchore.io/syft | sudo sh -s -- -b /usr/local/bin
# Verifiera installationen
syft version
Kontrollera att versionen som skrivs ut matchar v1.42.4 eller senare. Syft skriver automatiskt ut en varning vid start om en nyare version finns tillgänglig, så lita på den signalen snarare än att komma ihåg att kolla manuellt.
Steg 2: Generera din första SBOM
Kör Syft mot din projektmapp för att generera en SBOM i CycloneDX-format, som är det format som EU:s regelverk och de flesta moderna verktyg bygger sitt ekosystem runt:
# Skanna hela projektmappen
syft dir:. -o cyclonedx-json=sbom.cdx.json
# Skanna en färdigbyggd containerimage istället
syft packages docker:mitt-projekt:latest -o cyclonedx-json=sbom.cdx.json
# Vill du hellre ha SPDX-format
syft dir:. -o spdx-json=sbom.spdx.json
Öppna sbom.cdx.json i en textredigerare. Du kommer att se en lista med hundratals, ibland tusentals, komponenter: varje npm-paket, varje Python-wheel, varje Debian-paket i basimagen, komplett med versionsnummer, licens och en unik identifierare (PURL). Det här är första gången de flesta team faktiskt ser hela sin attackyta i klartext, snarare än gissar sig till den.
Steg 3: Installera Grype och skanna din SBOM mot sårbarhetsdatabaser
En lista över komponenter är bara halva jobbet. Grype tar samma SBOM och matchar varje post mot flera sårbarhetskällor samtidigt, inklusive NVD och distributionsspecifika databaser.
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
grype version
Viktigt: Anchore stängde ner uppdateringarna för det äldre databasschemat v5 den 6 mars 2026. Kör du en Grype-version äldre än v0.88.0 får du inga nya sårbarhetsdata alls, utan att verktyget nödvändigtvis varnar högljutt om det. Se till att du ligger på v0.88.0 eller senare, vilket automatiskt använder det nyare schemat v6.
Steg 4: Skanna SBOM:en och läs resultatet rätt
# Skanna en tidigare genererad SBOM direkt (snabbast, inget behov av att skanna om)
grype sbom:./sbom.cdx.json
# Eller skanna projektet eller imagen direkt
grype dir:.
grype docker:mitt-projekt:latest
# Få strukturerad output för vidare bearbetning i CI
grype sbom:./sbom.cdx.json -o json > grype-report.json
# Bryt bygget vid kritiska fynd
grype sbom:./sbom.cdx.json --fail-on critical
Standardutskriften listar varje sårbarhet med paketnamn, installerad version, fixad version (om en finns) och allvarlighetsgrad. Flaggan --fail-on critical är den du faktiskt vill använda i CI, eftersom den ger byggsteget en icke-nollretur och stoppar pipelinen om något kritiskt hittas, snarare än att bara skriva ut en varning som ingen läser.
Steg 5: Sätt upp automatisk skanning i GitHub Actions
Manuell skanning fångar problem du redan känner till att leta efter. Automatisk skanning i varje pull request fångar det du inte tänkt på. Lägg till följande workflow i .github/workflows/supply-chain.yml:
name: Leveranskedjekontroll
on:
pull_request:
push:
branches: [main]
jobs:
sbom-and-scan:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- name: Generera SBOM
uses: anchore/sbom-action@v0
with:
path: .
format: cyclonedx-json
output-file: sbom.cdx.json
- name: Skanna SBOM med Grype
uses: anchore/scan-action@v3
with:
sbom: sbom.cdx.json
fail-build: true
severity-cutoff: critical
- name: Ladda upp SBOM som artefakt
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.cdx.json
Notera id-token: write i behörigheterna. Den behövs inte för själva skanningen men förbereder pipelinen för signeringssteget vi lägger till i steg 8, som använder keylös signering via OIDC istället för lagrade hemligheter.
Steg 6: Kör OpenSSF Scorecard mot dina egna beroenden
Grype talar om ifall ett paket har en känd sårbarhet. Scorecard talar om något annat: hur väl underhållet och hur riskabelt paketets eget GitHub-repo är, oavsett om en CVE redan hittats där. Det fångar exakt den typ av risk som TeamPCP-kampanjen utnyttjade, ett repo med svag CI-konfiguration, långsam patchrespons och för många personer med skrivbehörighet.
# Installera med Go
go install github.com/ossf/scorecard/v5@latest
# Kör mot ett specifikt repo
scorecard --repo=github.com/anchore/syft
# Fokusera på leveranskedjerelevanta kontroller
scorecard --repo=github.com/anchore/syft --checks=Pinned-Dependencies,Token-Permissions,Branch-Protection
Scorecard v5.5.0, utgiven 23 april 2026, ger varje repo ett betyg från 0 till 10 uppdelat per kontroll. Ett lågt betyg på Pinned-Dependencies betyder att repot pekar mot rörliga taggar istället för fasta commit-hashar i sina egna workflows, exakt den typ av svaghet som gjorde TeamPCP-kampanjens spridning möjlig mellan de fem komprometterade verktygen.
Steg 7: Installera cosign för signering
En SBOM och en ren skanningsrapport är värdelösa om någon kan byta ut din artefakt mellan bygge och driftsättning utan att det märks. Cosign, en del av Sigstore-projektet, löser det genom att kryptografiskt signera containerimages och andra artefakter.
# macOS
brew install cosign
# Linux
curl -O -L "https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64"
sudo mv cosign-linux-amd64 /usr/local/bin/cosign
sudo chmod +x /usr/local/bin/cosign
cosign version
Bekräfta att du kör v3.0.6 eller senare. Version 2.6.0 och senare stödjer uppladdning och verifiering mot Rekor v2, Sigstores transparensloggar, med matchande klientbibliotek i Go, Python och Java, vilket gör det praktiskt att verifiera signaturer från valfri del av din pipeline, inte bara kommandoraden.
Steg 8: Signera en containerimage keylöst
Den gamla metoden att hantera privata nycklar manuellt är felbenägen; en läckt nyckel underminerar hela poängen. Keylös signering med cosign använder istället kortlivade certifikat utfärdade via OIDC, kopplade till din identitet (till exempel GitHub Actions-jobbets identitet) i stället för en fil på disk.
# Bygg och tagga imagen
docker build -t ghcr.io/dittkonto/mitt-projekt:1.0.0 .
docker push ghcr.io/dittkonto/mitt-projekt:1.0.0
# Signera keylöst (öppnar webbläsare för OIDC-inloggning lokalt)
cosign sign ghcr.io/dittkonto/mitt-projekt:1.0.0
# I GitHub Actions sker det automatiskt via jobbets OIDC-identitet
cosign sign --yes ghcr.io/dittkonto/mitt-projekt:1.0.0
Flaggan --yes hoppar över den interaktiva bekräftelsen, vilket krävs i en icke-interaktiv CI-miljö. Signaturen och certifikatet publiceras till Rekors offentliga transparenslogg, så att signeringen går att verifiera i efterhand av vem som helst, inte bara ditt eget system.
Steg 9: Verifiera signaturen innan driftsättning
Signering utan verifiering är teater. Verifieringssteget måste sitta i din driftsättningspipeline, inte bara finnas tillgängligt om någon råkar tänka på att köra det manuellt.
cosign verify ghcr.io/dittkonto/mitt-projekt:1.0.0 \
--certificate-identity-regexp "https://github.com/dittkonto/.*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
Om verifieringen lyckas returnerar cosign certifikatets metadata, inklusive exakt vilket GitHub Actions-workflow som signerade imagen och när. Om den misslyckas avbryts kommandot med ett tydligt felmeddelande. Bygg in det här steget som en gate i din driftsättningspipeline (Kubernetes admission controllers som Kyverno eller Sigstore Policy Controller kan göra det automatiskt för hela klustret).
Steg 10: Bifoga SBOM som en attesterad del av imagen
Istället för att bara ladda upp SBOM:en som en separat fil, kan du binda den kryptografiskt till imagen med en attestering. Då kan ingen senare byta ut SBOM-filen utan att signaturen bryts.
cosign attest --yes \
--predicate sbom.cdx.json \
--type cyclonedx \
ghcr.io/dittkonto/mitt-projekt:1.0.0
# Verifiera attesteringen och hämta ut SBOM:en igen
cosign verify-attestation \
--type cyclonedx \
--certificate-identity-regexp "https://github.com/dittkonto/.*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
ghcr.io/dittkonto/mitt-projekt:1.0.0
Nu kan vem som helst med tillgång till imagen hämta ut en signerad, oförfalskningsbar kopia av SBOM:en direkt från registryt, utan att lita på en separat fildelning som kan bli inaktuell eller manipulerad.
Steg 11: Bygg ett SLSA-uppfyllande bygge
SLSA (Supply-chain Levels for Software Artifacts), där version 1.2 godkändes 12 november 2025, definierar fyra nivåer av hur verifierbar din byggprocess är, från “ingen kontroll” på nivå 0 till “byggen sker i en isolerad, reproducerbar miljö med signerad proveniens” på nivå 3. GitHubs officiella SLSA-generator ger dig nivå 3 utan att du behöver bygga infrastrukturen själv:
jobs:
build:
permissions:
id-token: write
contents: read
actions: read
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
with:
image: ghcr.io/dittkonto/mitt-projekt
digest: ${{ needs.build.outputs.digest }}
Resultatet är ett proveniensdokument som beskriver exakt vilken källkod, vilket workflow och vilka indata som gick in i bygget, signerat på samma sätt som imagen själv. Kombinerat med SBOM:en och sårbarhetsrapporten från Grype har du nu ett fullständigt, verifierbart bevisspår från källkodsrad till driftsatt artefakt.
Steg 12: Automatisera med policykontroller och notifieringar
Den sista biten är att göra kontrollerna kontinuerliga snarare än en engångsövning. Sätt upp en schemalagd omskanning eftersom nya sårbarheter upptäcks i redan skrivna paket varje dag, oavsett om du ändrat din egen kod:
on:
schedule:
- cron: '0 6 * * *' # varje dag klockan 06:00 UTC
workflow_dispatch:
jobs:
daily-rescan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Ladda ner senaste SBOM
run: syft dir:. -o cyclonedx-json=sbom.cdx.json
- name: Skanna mot dagens sårbarhetsdata
run: grype sbom:./sbom.cdx.json --fail-on high
Koppla jobbet till ett Slack- eller Teams-webhook vid fel, så att ett nyupptäckt högriskfynd i ett paket du inte rört på sex månader ändå landar i någons inkorg samma dag, snarare än att upptäckas nästa gång ni råkar köra en manuell granskning.
Verktygsjämförelse: Syft och Grype mot alternativen
Syft och Grype är inte de enda verktygen på marknaden, och det är rimligt att fråga varför just den här kombinationen valdes för guiden. Trivy från Aqua Security gör i praktiken samma jobb i ett enda binärfil, medan Docker Scout är inbyggt direkt i Docker Desktop och Docker Hub för team som redan lever i det ekosystemet. Skillnaderna handlar mindre om vilket verktyg som är “bäst” i absoluta tal och mer om var i er befintliga pipeline verktyget passar naturligast in.
| Verktyg | SBOM-format | Fristående binär | Bäst lämpad för |
|---|---|---|---|
| Syft + Grype | CycloneDX, SPDX | Ja, två separata verktyg | Team som vill separera SBOM-generering från skanning för flexibilitet i CI |
| Trivy | CycloneDX, SPDX | Ja, allt-i-ett | Team som redan använder Aqua Securitys ekosystem eller vill ha ett enda verktyg för både SBOM och skanning |
| Docker Scout | SPDX (SaaS-baserat, med lokalt CLI-läge) | Delvis, kräver Docker-inloggning för fullt utbud | Team som redan använder Docker Hub som centralt image-register |
Poängen med att just TeamPCP-kampanjen lyckades kompromettera Trivy i mars 2026 är inte att verktyget i sig var dåligt konstruerat, utan att sårbarheten satt i projektets egen CI-konfiguration, inte i själva skanningslogiken. Samma risk gäller vilket verktyg ni än väljer: verktyget skyddar er kod, men någon måste fortfarande skydda verktygets egen leveranskedja med samma rigör som ni kräver av era egna beroenden. Praktiskt betyder det att pinna exakta versioner av GitHub Actions med commit-hash snarare än rörlig tagg, oavsett om ni kör anchore/scan-action@v3 eller motsvarande från ett annat projekt.
Så rullar du ut det här i ett befintligt team utan att stoppa releaser
Det vanligaste misstaget när team inför SBOM- och signeringskrav är att sätta --fail-on critical på hela kodbasen från dag ett. Resultatet blir ofta att tiotals pull requests plötsligt blockeras samtidigt av gamla, redan kända sårbarheter som ingen hunnit åtgärda, vilket får utvecklare att uppfatta hela initiativet som ett hinder snarare än ett skydd. En stegvis utrullning fungerar bättre i praktiken.
Börja med att köra skanningen i observationsläge under två till tre veckor: generera SBOM och kör Grype i varje pull request, men låt jobbet alltid returnera framgång oavsett fynd. Samla resultaten i en delad kanal så att teamet vänjer sig vid att läsa rapporterna innan de får konsekvenser. När ni har en baslinje över hur många kända sårbarheter som redan finns i kodbasen, sätt ett datum för när --fail-on critical aktiveras för nya sårbarheter som introduceras efter det datumet, samtidigt som redan existerande fynd hanteras som en separat saneringslista med egna deadlines.
Signering och SLSA-proveniens bör införas i en liknande ordning: aktivera signering och attestering för alla nya byggen omedelbart (det stör aldrig en befintlig release eftersom det bara lägger till metadata), men vänta med att göra verifiering obligatorisk vid driftsättning tills ni bekräftat att signeringssteget fungerat felfritt i minst en fullständig release-cykel. Att låsa driftsättningspipelinen mot en signeringsprocess som ännu inte är stabil skapar precis den typen av friktion som får säkerhetsinitiativ avskaffade sex månader senare.
Slutligen, utse en tydlig ägare för sårbarhetstriage. Utan en namngiven person eller ett roterande ansvar hamnar Grype-rapporterna i en kanal som ingen faktiskt läser, vilket i praktiken gör hela pipelinen till teater snarare än skydd. Det behöver inte vara en heltidsroll, men det måste vara någons uttalade ansvar under given vecka.
Fem vanliga fallgropar
- Att skanna källkoden men glömma containerbasen. En SBOM byggd med
syft dir:.ser bara ditt eget projekts filer. Om din Dockerfile bygger ovanpå en tre år gammal Alpine-image med föråldrade systempaket, missar du hela det lagret om du inte körsyft packages docker:mot den färdiga imagen. - Att ignorera transitiva beroenden. Ditt
package.jsonkanske listar 40 paket, men den fullständiga SBOM:en kan innehålla över 1 000 poster när varje beroendes beroenden räknas med. Det är just dessa djupt liggande, sällan granskade paket som oftast blir måltavlor, eftersom ingen tittar på dem. - Att köra Grype mot en föråldrad databas utan att veta om det. Efter att schema v5 slutade uppdateras 6 mars 2026 fortsatte äldre Grype-versioner att köra utan felmeddelande, bara med tystnat sårbarhetsdata. Lägg alltid till en explicit versionskontroll i CI-jobbet.
- Att signera efter att sårbarheter redan flaggats. Signering bevisar att artefakten inte manipulerats, inte att den är säker. Ordningen spelar roll: skanna, åtgärda eller acceptera risken medvetet, signera sist.
- Att lagra privata signeringsnycklar i CI-hemligheter. Det återskapar exakt den typ av central, stjälbar hemlighet som keylös signering är designad för att eliminera. Om du redan har nyckelbaserad signering i produktion, planera en migrering till OIDC-baserad keylös signering snarare än att lägga till fler lager av nyckelrotation ovanpå problemet.
Exempel på output: så ser en verklig skanning ut
Så här kan en typisk körning av grype sbom:./sbom.cdx.json se ut mot ett medelstort Node.js-projekt:
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY
axios 1.6.2 1.7.4 npm GHSA-8hc4-vh64 High
lodash 4.17.15 4.17.21 npm CVE-2021-23337 High
minimist 1.2.5 1.2.6 npm CVE-2021-44906 Critical
openssl 3.0.9 3.0.13 deb CVE-2024-0727 Medium
[0000] INFO grype hittade 4 sårbarheter (1 kritisk, 2 höga, 1 medel)
Med --fail-on critical aktiverat hade det här bygget stoppats direkt på grund av minimist-fyndet, innan imagen ens hann pushas till registryt. Det är precis den typen av tidig, automatisk broms som gör skillnaden mellan att fixa ett problem på fem minuter i en pull request och att felsöka det i produktion en vecka senare.
Avancerade tips för mognare pipelines
- Differentiell SBOM-jämförelse. Spara varje SBOM som byggartefakt och diffa den mot föregående release för att se exakt vilka paket som lagts till, tagits bort eller uppgraderats mellan två versioner, användbart både för säkerhetsgranskning och för att snabbt hitta orsaken när något går sönder efter en uppdatering.
- VEX för att hantera falska positiva. Grype stödjer numera CSAF VEX-transformering, vilket låter dig formellt dokumentera att en viss sårbarhet inte är exploaterbar i just din kontext (till exempel för att den sårbara kodvägen aldrig anropas), istället för att bara ignorera varningen tyst.
- Poängsätt dina leverantörer, inte bara dina egna repon. Kör Scorecard mot varje kritiskt beroende innan ni lägger till det i projektet, inte bara mot er egen kodbas. Ett lågt betyg är inte en absolut spärr, men det är en anledning att lägga till extra granskning eller en pinnad, granskad version.
- Bygg in SBOM-krav i inköpsprocessen. Kräv en CycloneDX- eller SPDX-SBOM från externa leverantörer och underkonsulter som en del av avtalet, särskilt med Cyber Resilience Act:s rapporteringskrav från 11 september 2026 i åtanke. Att be om det efteråt är betydligt svårare.
Felsökning: 8 vanliga problem och lösningar
| Problem | Trolig orsak | Lösning |
|---|---|---|
| Syft hittar noll paket i en containerimage | Imagen bygger på en distroless-bas utan paketmetadata | Skanna byggsteget istället för den slutgiltiga distroless-imagen, eller använd flerstegsbygge och skanna mellansteget |
| Grype rapporterar orimligt många kritiska fynd över en natt | Sårbarhetsdatabasen uppdaterades med nya CVE:er, inte er kod | Kontrollera CVE-publiceringsdatum mot senaste körningen innan ni misstänker en regression i egen kod |
| cosign sign fastnar och väntar på webbläsarinloggning i CI | Jobbet saknar korrekt OIDC-behörighet | Lägg till id-token: write under permissions i workflow-filen och kör med --yes |
| cosign verify misslyckas trots att bygget signerades korrekt | Fel eller för generellt --certificate-identity-regexp | Kontrollera exakt repo-sökväg och gren i certifikatets identitetsfält med cosign verify --output json |
| SBOM-filen är flera hundra megabyte | Skanning av en monorepo eller en image med många basskikt utan filtrering | Begränsa skanningen till relevanta kataloger med syft dir:./src eller exkludera testfixturer |
| Scorecard-jobbet timar ut mot stora beroendeträd | GitHub API-hastighetsgränsen nås vid granskning av hundratals repon | Använd en autentiserad token med högre gräns och begränsa till --checks ni faktiskt bryr er om |
| Attesteringen går att skapa men inte verifiera | Fel --type-flagga vid verifiering jämfört med attestering | Se till att cosign attest och cosign verify-attestation använder identiskt --type-värde |
| Daglig omskanning genererar för mycket brus | Alla fynd, även låg allvarlighetsgrad, notifieras lika | Sätt --fail-on high för byggblockering men logga allt annat separat utan att larma |
Komplett arbetsyta: allt ihopsatt
Så här ser en fullständig, fungerande workflow-fil ut när alla stegen ovan kombineras till en enda pipeline som körs vid varje push till huvudgrenen:
name: Fullständig leveranskedjepipeline
on:
push:
branches: [main]
permissions:
contents: read
id-token: write
packages: write
jobs:
build-sign-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Bygg och pusha image
run: |
docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} .
docker push ghcr.io/${{ github.repository }}:${{ github.sha }}
- name: Generera SBOM
uses: anchore/sbom-action@v0
with:
image: ghcr.io/${{ github.repository }}:${{ github.sha }}
format: cyclonedx-json
output-file: sbom.cdx.json
- name: Skanna med Grype
uses: anchore/scan-action@v3
with:
sbom: sbom.cdx.json
fail-build: true
severity-cutoff: critical
- name: Installera cosign
uses: sigstore/cosign-installer@v3
- name: Signera imagen keylöst
run: cosign sign --yes ghcr.io/${{ github.repository }}:${{ github.sha }}
- name: Bifoga SBOM som attestering
run: |
cosign attest --yes \
--predicate sbom.cdx.json \
--type cyclonedx \
ghcr.io/${{ github.repository }}:${{ github.sha }}
- name: Verifiera hela kedjan
run: |
cosign verify ghcr.io/${{ github.repository }}:${{ github.sha }} \
--certificate-identity-regexp "https://github.com/${{ github.repository }}/.*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
Med den här filen på plats sker fyra saker automatiskt vid varje push till huvudgrenen: imagen byggs och publiceras, en fullständig SBOM genereras och bifogas, imagen skannas mot aktuella sårbarheter med byggblockering vid kritiska fynd, och hela paketet signeras keylöst så att ingen kan byta ut det senare utan att det upptäcks. Det är precis den kombinationen som saknades i de fem verktygen TeamPCP kom åt under mars 2026.
Hur SBOM-arbetet kopplar till OWASP Top 10:2025
Att bygga den här pipelinen är inte ett fristående projekt, det är direkt svar på en namngiven riskkategori. I OWASP:s uppdaterade Top 10:2025-lista beskrivs A03:2025 Software Supply Chain Failures som en utökning av den gamla kategorin “sårbara och föråldrade komponenter” från 2021, breddad till att även omfatta byggpipelines, CI/CD-konfiguration och signeringsintegritet, precis de områden den här guiden täcker. Om ni redan arbetat igenom vår tidigare guide till OWASP Top 10 i Node.js-miljö är den här artikeln det naturliga nästa steget: från att identifiera enskilda sårbarhetsklasser i applikationskoden till att bygga kontinuerlig, verifierbar kontroll över hela leveranskedjan.
Det finns också en tydlig koppling till hur ni redan prioriterar patchning. Om ni följer vår guide till CISA:s katalog över kända exploaterade sårbarheter (KEV) för att avgöra vad som ska åtgärdas först, blir SBOM:en den datakälla som gör den processen faktiskt genomförbar i stor skala. Utan en maskinläsbar lista över exakt vilka komponenter och versioner som finns i varje system måste ni manuellt korsreferera KEV-katalogen mot en mental bild av arkitekturen, vilket i praktiken betyder att ni missar saker.
Vad Cyber Resilience Act faktiskt kräver av er SBOM-process
För nordiska tillverkare av uppkopplade produkter, allt från nätverksutrustning till smarta hemenheter och industriell styrutrustning, är tidslinjen konkret. Den första hårda deadlinen passerade 11 juni 2026 när medlemsstaterna skulle ha anmält sina organ för bedömning av överensstämmelse. Nästa, betydligt allvarligare deadline infaller 11 september 2026: från det datumet måste tillverkare rapportera aktivt utnyttjade sårbarheter i sina produkter inom 24 timmar efter upptäckt. Böterna för den som missar kraven kan uppgå till 15 miljoner euro eller 2,5 procent av global årsomsättning, beroende på vilket belopp som är högst.
En automatiserad SBOM- och skanningspipeline av den typ vi byggt i den här guiden är i praktiken den enda rimliga vägen att uppfylla den 24-timmarsgränsen. Utan den måste ett team manuellt utreda om en nyupptäckt sårbarhet i ett tredjepartsbibliotek påverkar en given produktlinje, ett arbete som lätt tar dagar snarare än timmar när det görs för hand mot dokumentation som redan är inaktuell.
Mät framgång: nyckeltal värda att följa över tid
En pipeline som bara körs utan att någon tittar på trenderna ger falsk trygghet. Fyra mätetal ger en ärligare bild av om arbetet faktiskt förbättrar säkerheten över tid, snarare än att bara producera fler rapporter.
Medeltid till åtgärd (MTTR) för kritiska fynd. Mät tiden från att Grype flaggar en kritisk sårbarhet till att en fix är driftsatt. Om det tar veckor snarare än dagar fungerar triage-processen inte, oavsett hur bra själva skanningen är. Koppla gärna det här måttet till samma prioriteringslogik som KEV-katalogen bygger på: sårbarheter med känd, aktiv exploatering ska alltid gå före sårbarheter som bara är teoretiskt allvarliga enligt CVSS-poäng.
Andel byggen med fullständig attestering. Räkna hur stor andel av era produktionsdriftsättningar som faktiskt har en verifierbar SBOM och signatur kopplad till sig, inte bara hur många pipelines som har stegen konfigurerade. Ett vanligt glapp är att signeringssteget finns i workflow-filen men tyst hoppas över vid manuella hotfix-driftsättningar som kringgår den normala pipelinen.
Scorecard-poäng för kritiska beroenden över tid. Spara Scorecard-resultaten för era mest centrala beroenden månad för månad. Ett sjunkande betyg för ett paket ni redan använder är en tidig varningssignal, ofta månader innan en faktisk sårbarhet eller ett intrång rapporteras offentligt, eftersom det speglar underliggande underhållskvalitet snarare än enskilda incidenter.
Antal transitiva beroenden per release. En stadigt växande SBOM utan motsvarande affärsvärde är ofta ett tecken på att beroenden läggs till utan granskning. Att helt enkelt visualisera hur SBOM:ens storlek förändras release för release gör det lättare att ställa frågan “behöver vi verkligen det här paketet” innan det blir en permanent del av attackytan.
Vanliga frågor om SBOM och leveranskedjesäkerhet
Måste jag välja mellan CycloneDX och SPDX?
Nej, Syft kan generera båda formaten från samma skanning utan extra arbete. CycloneDX 1.7, utgivet 21 oktober 2025 och ratificerat som ECMA-424 andra utgåvan i december 2025, har blivit standardvalet i de flesta CI/CD-verktyg tack vare starkare stöd för sårbarhets- och signeringsdata direkt i formatet. Många regulatoriska ramverk accepterar dock båda, så välj utifrån vad era nedströms-verktyg redan förväntar sig.
Räcker det att bara köra Grype, utan att signera med cosign?
Det ger er halva bilden. Grype talar om vad som är sårbart just nu, men säger ingenting om huruvida artefakten som faktiskt driftsätts är samma artefakt som skannades och godkändes. Utan signering och verifiering kan en angripare i teorin byta ut en godkänd image mot en manipulerad version mellan skanning och driftsättning, exakt det scenario signering är utformat för att förhindra.
Kostar de här verktygen något?
Syft, Grype, cosign, Sigstore och OpenSSF Scorecard är samtliga öppen källkod och gratis att använda, inklusive i kommersiella pipelines. Anchore erbjuder en betald Enterprise-produkt ovanpå de öppna verktygen med extra funktioner som central policyhantering över flera team, men grundverktygen som beskrivs i den här guiden kostar ingenting.
Hur ofta bör jag skanna om befintliga, oförändrade images?
Minst en gång per dygn för allt som körs i produktion. Nya sårbarheter publiceras i redan existerande paket löpande, oberoende av om ni själva ändrat något i er kod. En image som var helt ren vid byggtillfället kan bli sårbar redan nästa vecka utan att en enda rad kod ändrats hos er.
Vad gör jag om Grype flaggar en sårbarhet jag vet är oexploaterbar i vårt fall?
Använd VEX-dokumentation (Vulnerability Exploitability eXchange) för att formellt notera bedömningen istället för att ignorera eller undertrycka varningen tyst. Grype stödjer CSAF VEX-transformering, vilket gör att bedömningen blir spårbar och granskningsbar av andra i teamet eller av en extern revisor, snarare än att bli tyst kunskap hos en enskild utvecklare.
Fungerar det här upplägget för Python- och Java-projekt, eller bara för Node.js?
Syft och Grype är språkagnostiska och stödjer paketformat för bland annat npm, PyPI, Maven, Go-moduler, RubyGems, samt operativsystempaket från Debian, Alpine och RHEL-familjen. Kommandona i den här guiden fungerar identiskt oavsett vilket språk projektet är skrivet i, eftersom skanningen sker mot filsystemet eller den byggda imagen, inte mot en specifik pakethanterare.
Bryter SLSA nivå 3 mot vårt befintliga byggsystem?
Inte nödvändigtvis. GitHubs officiella SLSA-generator är designad att läggas till som ett extra steg ovanpå ett befintligt byggjobb snarare än att ersätta det. Ni behöver dock separera själva byggsteget från publicerings- och signeringsstegen om de idag ligger i samma odelade jobb, eftersom proveniensen kräver ett verifierbart, isolerat byggsteg för att räknas som nivå 3.
Vad händer om vi inte hinner uppfylla Cyber Resilience Act:s deadlines?
Böterna kan bli betydande, upp till 15 miljoner euro eller 2,5 procent av global årsomsättning beroende på överträdelsens karaktär. Det praktiska rådet är att inte vänta till deadline 11 september 2026 för att börja bygga SBOM-processen, eftersom en fungerande pipeline av det slag den här guiden beskriver tar veckor att sätta upp och ytterligare tid att integrera i befintliga produktlinjer och leverantörskedjor.
Vad gör jag när Grype flaggar en sårbarhet utan tillgänglig fix?
Det händer regelbundet, särskilt för äldre eller mindre aktivt underhållna paket. Första steget är att kontrollera om det finns en alternativ, mer underhållen ersättare med samma funktionalitet, vilket ofta är den mest hållbara lösningen på lång sikt. Finns ingen ersättare, dokumentera risken med en VEX-post och lägg till kompenserande kontroller, till exempel nätverkssegmentering som begränsar vad den sårbara komponenten faktiskt kan nå, och sätt ett datum för nästa granskning istället för att låta fyndet ligga obevakat på obestämd tid.
Relaterad läsning
- TeamPCP 2026: 5 säkerhetsverktyg hackade på 12 dagar
- OWASP Top 10 i Node.js: 12 steg, 30 min [2026]
- CISA KEV Patchhantering: 12 Steg, 45 Min [2026]
- Cyber Resilience Act: 15 M€ i böter [2026]
- NIS2-incidentplan: 12 Steg, 3-5 Dagar [2026]
- Helmet.js i Node.js: 12 Steg för HTTP-säkerhetshuvuden [2026]
Läs mer säkerhetsjournalistik och fler djupdykningar på shattered.io:s säkerhetssektion.




