Hvorfor CI
Derfor hører forsyningskædesikkerhed hjemme i din CI
Den software, du leverer, er det, dit CI-build producerede, ud fra det, det downloadede i det øjeblik. Det build er det ene sted, hvor du kan se, hvad der gik ind, beslutte, hvad der må komme ind, og registrere, hvad der gik ind i releasen.
Opdateret
What software supply chain security means
Foredragets arbejdsdefinition: din software er din egen kode plus alt, den afhænger af, og forsyningskæden er hvert trin, der får de dele ind i en release.
Petteri Pulkkinen og Erika Marttinen ved Kubernetes Community Days Helsinki 2026, 2:35 til 4:28 af SBOMbastic: Getting Ready for Upcoming EU Cybersecurity Regulation in Software Supply Chains.
Dit produktionsbuild er ikke buildet på din laptop
De fleste teams går ud fra, at den kode, de testede lokalt, er den kode, der bliver leveret. Kilden er den samme, men softwaren er det ofte ikke. Et build er kildekode plus alt, hvad det henter, og alt omkring det, på det tidspunkt, det kører, og meget lidt af det ligger fast.
Ikke-fastlåste afhængigheder resolves forskelligt
Versionsintervaller for afhængigheder er normen. I npm accepterer ^1.0.4 enhver senere 1.x-release, så den samme package.json installerer forskellige versioner på forskellige dage. En lockfile fastlåser dem, men kun hvis den er committet, og buildet følger den: npm ci fejler, når lockfilen og package.json ikke stemmer overens, mens npm install stille og roligt kan opdatere lockfilen. Mange projekter committer slet ikke nogen. Express 5.2.1, et meget brugt webframework, gør det ikke.
Selv en fastlåst version er et navn, ikke en fil. pips dokumentation forklarer, at versionsfastlåsning alene ikke forhindrer et pakkeindeks i at levere forskellige filer for den samme version, og derfor tilbyder pip en tilstand med tjek af hashes.
Tiden ændrer inputtene
Registries ændrer sig mellem builds. Nye versioner udgives, gamle trækkes tilbage, og et interval, der blev resolvet sikkert mandag, kan samle en kompromitteret release op tirsdag. Container-tags flytter sig også: Dockers egen dokumentation advarer om, at image-tags kan ændres, så en udgiver kan opdatere et tag til at pege på et nyt image, og derfor er FROM node:20 ikke det samme base-image fra den ene måned til den næste, medmindre du fastlåser det med en digest.
Tiden ender også inde i outputtet. Projektet Reproducible Builds kalder tidsstempler den største kilde til problemer med reproducerbarhed, fordi så mange værktøjer skriver den aktuelle dato og det aktuelle klokkeslæt ind i det, de bygger.
Miljøet er anderledes
- Styresystem og arkitektur. En laptop med macOS og ARM og en CI-runner med Linux og x86-64 installerer forskellige færdigbyggede binærfiler for den samme pakke. Mange npm-værktøjer leveres nu som platformspecifikke pakker, der pakker en kompileret binærfil ind.
- Toolchains. Versioner af compilere, runtimes og pakkehåndteringer glider fra hinanden mellem maskiner, medmindre hver eneste af dem er fastlåst.
- Caches. Din maskine og din CI gendanner forskellige caches, bygget på forskellige tidspunkter ud fra forskellige resolutions.
- Install-scripts og build-trin. Post-install-hooks, setup-actions og build-scripts downloader værktøjer og data under buildet. Intet af det optræder i et manifest.
- Konfiguration. Miljøvariabler, build-flag og secrets findes i CI og ingen andre steder.
Projektet Reproducible Builds definerer et reproducerbart build som et, hvor enhver ud fra samme kildekode, build-miljø og build-instruktioner kan genskabe bit-for-bit-identiske kopier af alle angivne artefakter. Den definition viser, hvor meget der skal holdes konstant. De fleste teams' builds når ikke dertil, og dem, der gør, har arbejdet hårdt for det. Indtil du er der, er den eneste pålidelige beretning om det leverede den, der blev registreret, mens det build, der blev leveret, kørte.
A software supply chain, walked end to end
Petteri Pulkkinen og Erika Marttinen ved Kubernetes Community Days Helsinki 2026, 15:20 til 16:38 af SBOMbastic: Getting Ready for Upcoming EU Cybersecurity Regulation in Software Supply Chains.
Hvor du kan tjekke, og hvad hvert sted kan se
Sikkerhedstjek kan køre fire steder. Hvert sted har sin opgave, men kun ét af dem ser det build, der faktisk producerede din release.
| Funktion | I CI-buildet | Udviklermaskine | Repository-scanning | Artefakt-scanning |
|---|---|---|---|---|
| Ser de versioner, produktion faktisk fik | Registreret, når de hentes | En anden installation | Kun hvis en lockfile fastlåser dem | Det, den kan genkende |
| Ser transitive pakker og pakker gendannet fra cache | Sin egen cache, ikke CI's | Kun lockfile | ||
| Ser, hvad install-scripts downloader | ||||
| Kan stoppe et ondsindet udgående kald | Egress-politik på runneren | |||
| Fanger problemer, før koden pushes | På pull requests |
- Inkluderet
- Delvist
- Ikke inkluderet
En scanning af repositoriet rapporterer, hvad projektet deklarerer. En scanning af det færdige artefakt rapporterer, hvad den kan genkende inde i det. Ingen af dem så buildet ske. Express 5.2.1 committer ingen lockfile, så en scanner, der peges på en ren checkout, ikke har nogen af projektets npm-afhængigheder at resolve og rapporterer det, den ellers genkender. Peg det samme værktøj på en installeret kopi af det samme repository, og ét cataloger-flag ændrer svaret igen. Hvad der kommer tilbage, afhænger af, hvad der var installeret før scanningen, og det er netop den del, en scanning ikke styrer. Siden om SBOM'er fra buildet gennemgår, hvorfor scanninger er uenige, og hvad registrering af buildet ændrer.
Pipelinen er et mål i sig selv
CI er der, hvor kildekode, afhængigheder og secrets mødes, og det gør det værd at angribe.
- tj-actions/changed-files (2025). En meget brugt GitHub Action blev kompromitteret og skrev CI-secrets ud i build-logs.
- Codecov Bash Uploader (2021). Et ændret script, der kørte i kunders CI, sendte miljøvariabler til en angribers server.
- Shai-Hulud-ormen i npm (2025). Kompromitterede pakker stjal legitimationsoplysninger ved installation og brugte dem til at udgive flere kompromitterede pakker.
- xz utils (2024). En bagdør blev gemt i release-tarballs og i selve build-processen, ikke i den synlige kildekode.
Alle disse kørte kode under et build eller en installation. En repository-scanning kørt før dem eller en artefakt-scanning kørt efter dem ville ikke have set, hvad build-processen gjorde. Kontroller, der overvåger og begrænser, hvad et job kan nå, skal sidde der, hvor jobbet kører. Det gælder også interne apps og apps med lav profil: Angreb som disse går efter pipelinen og de pakker, alle apps deler, ikke efter det, en app gør. Se forsyningskædesikkerhed for intern software og software med lav risiko.
Mere kode, flere afhængigheder, færre, der læser dem
AI-kodeagenter skriver og ændrer kode hurtigere, end teams kan gennemgå hver linje, og de tilføjer afhængigheder undervejs. De nævner også pakker, der ikke findes: Et USENIX Security 2025-studie af 576.000 genererede kodeeksempler fandt andele af hallucinerede pakker på mindst 5,2 % for kommercielle modeller og 21,7 % for open source-modeller. Registrerer en angriber et af de navne, bliver angriberens pakke installeret af det næste build, der stoler på det.
Hver ændring, uanset hvem eller hvad der skrev den, passerer gennem buildet på vej til produktion. Det gør buildet til det ene kontrolpunkt, der ikke afhænger af, at nogen har kigget.
Dokumentationen skal beskrive det leverede
Lovgivning og kunder beder om bevis, ikke hensigter. EU's Cyber Resilience Act kræver, at producenter identificerer og dokumenterer komponenterne i deres produkter og håndterer sårbarheder i dem i produktets supportperiode. En SBOM genereret ud fra et manifest beskriver, hvad projektet bad om. En SBOM registreret fra buildet beskriver, hvad der gik ind i den release, du er ansvarlig for. Når en ny sårbarhed offentliggøres, fortæller den sidste dig, hvilke releases der er berørt. Læs hvad CRA kræver.
Hvad "i CI" bør betyde
At køre en scanner som et CI-trin er en start, men den ser stadig på filer, efter at de er ankommet. Gjort ordentligt betyder "i CI":
- Registrér, udled ikke. Registrér hver pakke og download, jobbet faktisk henter, inklusive transitive afhængigheder og alt, der er gendannet fra en cache.
- Sig, hvor komplet registreringen er. En SBOM bør angive, om den dækker alt, hvad jobbet hentede, og ikke bare liste det, den fandt.
- Styr udgående trafik. Bestem, hvilke hosts et job må nå, og stop resten, før en kompromitteret afhængighed kan ringe hjem.
- Bliv ved med at overvåge efter release. Tjek det leverede igen, når nye sårbarheder dukker op, og gør fund til rettelser.
Det er det, CRACI gør. Det er en runner til dine GitHub Actions-jobs, så det registrerer, hvad hvert build henter, anvender egress-politikken og overvåger det, du har leveret. At flytte et workflow er én linje: runs-on: craci. Se sådan virker CRACI.
Hvad CI ikke erstatter
At lægge forsyningskædesikkerhed ind i buildet gør ikke andre lag valgfrie.
- Udviklermaskiner indeholder stadig legitimationsoplysninger og kører install-scripts. Beskyt også dem; en kompromitteret laptop kan pushe kode, før noget build kører.
- Kodegennemgang og statisk analyse finder fejl i din egen kode, hvilket en registrering af afhængigheder ikke gør.
- Fastlåsning, lockfiles og digests er stadig god praksis. De mindsker forskellen mellem builds; registrering af buildet fortæller dig alligevel, hvad der skete.
Buildet er ikke det eneste sted at tjekke. Det er det eneste sted, der ser den software, du faktisk leverer.
Se CRACI i din egen pipeline
Book en demo, så gennemgår vi dine builds, dine SBOM'er og din compliance-dokumentation.
Book en demo