SBOM
Una SBOM dovrebbe descrivere la build che è stata distribuita
Una SBOM in fase di build viene registrata durante l'esecuzione della build, dal traffico effettivamente entrato. La maggior parte dei generatori di SBOM ricostruisce invece l'elenco a posteriori dal lockfile o dall'output, e così non vede le dipendenze nascoste che una build scarica da sola. Ecco perché, e che cosa cambia registrando la build.
Aggiornato il
SBOM di build, SBOM del sorgente, SBOM analizzata
Le indicazioni di CISA sui tipi di SBOM le classificano in base a quando e come vengono prodotte. Tre di questi tipi coprono quasi tutti i generatori di SBOM in uso:
| Tipo | Come viene prodotta | Che cosa può non includere |
|---|---|---|
| Sorgente | Da file sorgente, manifest e lock file, di solito tramite uno strumento SCA | Componenti di runtime, plugin o piattaforma; tutto ciò che non è dichiarato nei file |
| Build | Nell'ambito della build che crea l'artefatto rilasciabile | Tutto ciò che l'ambiente di build non può vedere, ed è per questo che la completezza andrebbe dichiarata |
| Analizzata | Dopo la build, analizzando un eseguibile, un pacchetto o un'immagine container | I componenti che lo strumento non riconosce; i risultati dipendono da euristiche |
CISA elenca due vantaggi di una SBOM di build: maggiore certezza che la SBOM rappresenti correttamente l'artefatto, grazie alle
informazioni disponibili durante la build e il processo CI/CD, e maggiore fiducia, perché lo stesso workflow di build può firmare sia
la SBOM sia l'artefatto. Lo svantaggio indicato è che per generarne una può essere necessario modificare il processo di build. Con
CRACI questa modifica è una riga, runs-on: craci, e la registrazione arriva con il runner.
Scansionare una cartella o registrare una build
La maggior parte dei generatori di SBOM è costituita da scanner. Lo si punta su un albero di sorgenti o su un'immagine container, e lo strumento deduce che cosa, a suo avviso, vi è entrato leggendo manifest, lockfile, pacchetti installati o binari. È utile, e per il software che Lei non ha compilato spesso è l'unica opzione.
Il punto debole è che uno scanner vede solo ciò che ha davanti. Se non è stato eseguito il commit di un lockfile, se le dipendenze non sono state installate prima della scansione o se il prodotto viene distribuito come binario compilato, lo scanner ha meno materiale su cui lavorare di quanto ne avesse la build. Una scansione che non trova alcun componente produce comunque un documento SBOM valido, ed è questo il tranello in cui molti cadono.
CRACI adotta un approccio diverso. Genera la SBOM all'interno del proprio runner CI, quindi l'artefatto distribuito è l'artefatto descritto. Non è una scansione eseguita da qualche parte lì vicino.
SBOM basics: SPDX, CycloneDX and OpenVEX
Che cosa registra una SBOM, in cosa differiscono in pratica i formati SPDX e CycloneDX e che cosa aggiunge OpenVEX sul fatto che una vulnerabilità interessi davvero un prodotto.
Petteri Pulkkinen e Erika Marttinen a Kubernetes Community Days Helsinki 2026, da 16:50 a 22:05 di SBOMbastic: Getting Ready for Upcoming EU Cybersecurity Regulation in Software Supply Chains.
Da che cosa dipende una scansione
Syft, Trivy, cdxgen, il Microsoft SBOM Tool, l'export del dependency graph di GitHub e la Socket CLI ricavano tutti una SBOM da ciò che riescono a leggere. Gli schemi descritti qui sotto derivano dal funzionamento documentato di questi strumenti.
Gli strumenti non concordano su che cosa sia un componente
Ogni generatore decide autonomamente che cosa conta come componente e di quali file fidarsi, quindi lo stesso commit fissato dà a ciascuno un elenco diverso.
In parte è una questione di nomi. Gli strumenti identificano la stessa GitHub Action con tipi di package URL diversi, quindi possono elencare la stessa cosa senza che le voci corrispondano. Anche questo fa parte del problema: una SBOM che usa un identificatore diverso per un componente è più difficile da confrontare con i dati sulle vulnerabilità.
L'aver installato prima può contare più dello strumento
Express 5.2.1 non include alcun lockfile nel repository. Puntato su un checkout pulito, un generatore che risolve le dipendenze da
lock file o da un albero installato non trova né gli uni né l'altro, quindi nessuna delle dipendenze npm dichiarate in
package.json arriva nel documento. Può comunque restituire un elenco, composto da tutto il resto che riconosce, come le
GitHub Actions e i file di workflow che le richiamano. Nessuno strumento qui è difettoso.
Su una copia installata dello stesso repository, un solo flag di Syft cambia di nuovo la risposta. Stesso strumento, stesso albero, stessa versione. Per scelta progettuale, una scansione di directory di Syft riporta ciò che un progetto dichiara, e il cataloger che legge i pacchetti installati non fa parte del suo insieme predefinito per le directory.
Alcuni software non hanno alcun manifest da leggere
Il repository anthropics/claude-code alla v2.1.259 non ha alcun manifest delle dipendenze: nessun package.json, lockfile o
equivalente. Ciò che ogni generatore restituisce viene ricavato da altri tipi di file, quindi la risposta dice più sullo strumento che
sul progetto.
Il pacchetto npm pubblicato non è molto diverso. @anthropic-ai/claude-code dichiara zero dipendenze di runtime e otto pacchetti specifici per piattaforma che incapsulano un
binario precompilato. @openai/codex 0.149.1 ha la stessa forma. Ciò che viene eseguito sulla macchina dello sviluppatore è
un binario compilato al cui interno nessun lettore di manifest può guardare. Non è un difetto di un singolo strumento. È un modello di
distribuzione che la scansione a posteriori non può descrivere.
Versioni e fornitori
Quando due strumenti trovano lo stesso pacchetto, non sempre concordano sulla sua versione. Uno può fissare una GitHub Action a un commit SHA mentre un altro riporta un tag di release. Una ricerca di vulnerabilità basata sulla versione sbagliata dà una risposta sicura e sbagliata.
Il campo supplier, uno degli elementi minimi NTIA, risulta spesso vuoto, perché la maggior parte dei generatori non ha una fonte per ricavarlo.
Dipendenze nascoste: ciò che nessuna scansione può vedere
Tutti gli strumenti citati partono dal lockfile o dall'output della build e ne deducono che cosa vi è entrato. Una build scarica più di questo. Queste dipendenze nascoste non sono elencate in alcun lockfile, quindi una scansione non può trovarle:
-
Hook di installazione. Gli script npm
preinstallepostinstallvengono eseguiti durante l'installazione e possono scaricare altro codice. È così che ha operato il worm Shai-Hulud. - Script di build. Gli script di build di Rust, tra gli altri, scaricano ciò che serve loro in fase di build.
- Immagini base. Una build di container scarica un'immagine base e i suoi layer del sistema operativo, che nessun lockfile di linguaggio elenca.
- Cache e strumenti di build. Anche i pacchetti ripristinati dalle cache CI e gli strumenti installati dai passaggi di setup arrivano al di fuori del lockfile.
Scansionare l'output in seguito non colma la lacuna. Un binario finito, soprattutto codice compilato come Rust, lascia lo scanner a indovinare che cosa vi sia entrato.
Due build, due SBOM
C'è un secondo motivo per cui una scansione non può sostituire la build: la maggior parte delle build non è riproducibile. Compili lo stesso commit due volte, una dopo l'altra, e non c'è alcuna garanzia di ottenere gli stessi pacchetti. I package manager risolvono e installano nell'ordine in cui arrivano le risposte, il che conta soprattutto quando non c'è un lockfile, come in molti progetti Python, e i passaggi di build possono includere elementi casuali propri. Le build riproducibili byte per byte sono possibili, con strumenti come Nix, ma sono rare.
Quindi una SBOM generata in seguito, su un'altra macchina o da un'altra build, descrive una build che potrebbe non essere mai stata distribuita. Solo la SBOM registrata durante la build CI che ha prodotto una release dimostra che cosa c'è in produzione.
Che cosa cambia registrando la build
CRACI vede il traffico; gli scanner no. Esegue i Suoi job GitHub Actions sui propri runner e vede il traffico di rete in ingresso in ogni build, quindi la SBOM elenca ciò che il job ha effettivamente scaricato, comprese le dipendenze transitive e nascoste, e non ciò di cui un manifest dice che dovrebbe avere bisogno.
Le cache sono il punto in cui la registrazione in fase di build diventa difficile. Un pacchetto ripristinato da una cache non passa mai da un registry di pacchetti, quindi un proxy da solo non lo vedrebbe. CRACI porta con la cache le evidenze sulle dipendenze, così i pacchetti ripristinati da una cache restano nella SBOM del job che li ha ripristinati. Veda che cosa nasconde la cache di GitHub Actions.
Gli ecosistemi rilevati comprendono npm, PyPI, RubyGems, Cargo, Go, Nix, OCI, apt, apk e sorgenti Git, oltre ai preset di download di Yocto e OpenEmbedded. I mirror npm e PyPI di JFrog Artifactory funzionano. I metadati delle licenze dichiarate sono inclusi nell'esportazione. Le SBOM si esportano in CycloneDX e SPDX. La pagina sulla generazione di SBOM descrive la funzionalità completa.
Vedere il traffico funziona anche nell'altra direzione. Una build ha bisogno di pacchetti da sorgenti note e pubblica il proprio output in posizioni note. La policy di egress di CRACI consente solo queste e blocca immediatamente ogni altra connessione in uscita, quindi il malware che tenta di inviare i Suoi secret al server di un attaccante fallisce. Poiché la policy consente ciò di cui la build ha bisogno invece di cercare host noti come malevoli, regge anche se Lei è il primo bersaglio di un attacco mai visto prima, come nel caso di Shai-Hulud. Veda come una policy di egress ferma l'esfiltrazione.
SBOM di container e Docker
Le immagini container sono il caso in cui la differenza si nota di più. I metodi abituali per ottenere una SBOM Docker analizzano tutti
l'immagine: Syft e Trivy la scansionano, docker scout sbom ne indicizza il contenuto quando l'immagine non ha un'attestazione
SBOM, e l'attestazione SBOM di BuildKit, attivata con --sbom=true, esegue per impostazione predefinita uno scanner basato su
Syft sulla fase finale dell'immagine. Il vecchio plugin docker sbom è deprecato a favore di
docker scout sbom.
Ciascuno di questi legge l'immagine finita, quindi vede ciò che è ancora riconoscibile nei layer. Non vede ciò che la build ha scaricato lungo il percorso. CRACI registra il job che compila l'immagine: le immagini e i pacchetti che il job scarica dai registry OCI e dalle sorgenti dei pacchetti finiscono nella stessa SBOM del resto della build. Per un'immagine che Lei non ha compilato, la scansione resta l'opzione pratica. Veda che cosa non vedono le SBOM delle immagini Docker.
Completezza, dichiarata per job
Una SBOM registrata vale quanto la registrazione. Invece di presentare ogni SBOM come completa, CRACI indica la completezza di ogni job e di ogni cache, in uno di cinque stati:
- Complete. CRACI ha osservato evidenze complete del job e ogni cache ripristinata era completa.
- Complete with connections. I requisiti sono stati soddisfatti, ma il job ha usato una o più connessioni di rete personalizzate, quindi vale la pena verificare che cosa è passato da lì.
- Incomplete. CRACI ha individuato una condizione che potrebbe lasciare fuori delle dipendenze dalla SBOM.
- Unavailable. CRACI non è riuscito a completare la valutazione delle evidenze.
- Not recorded. Il job è precedente all'introduzione del rapporto sulla completezza.
La completezza si trasmette attraverso le cache. Se un job ripristina una cache incompleta, anche la sua SBOM è incompleta, e qualsiasi cache prodotta da quel job porta con sé lo stato di incompletezza. Lei sa quali SBOM sono affidabili e quali richiedono una seconda verifica.
The hard parts: hooks, noise and staying current
Tre problemi che il talk mette in evidenza: gli hook post-install che scaricano cose che nessun manifest elenca, trovare le dipendenze che contano in un lungo elenco e mantenere aggiornata la SBOM, il che significa generarla nella CI a ogni build.
Petteri Pulkkinen e Erika Marttinen a Kubernetes Community Days Helsinki 2026, da 25:39 a 27:22 di SBOMbastic: Getting Ready for Upcoming EU Cybersecurity Regulation in Software Supply Chains.
La provenance tramite l'API
La SBOM è solo una parte di ciò che CRACI registra per ogni job. L'API restituisce SBOM, tracce di rete e provenance, tutte registrate dalla stessa build.
Quando uno scanner è ancora lo strumento giusto
La registrazione in fase di build copre il software che Lei compila. Per un'immagine o un binario di terze parti che non ha compilato Lei, uno scanner resta la scelta pratica, e gli strumenti citati sono validi e ampiamente usati. Il punto non è che gli scanner siano cattivi. È che la SBOM delle Sue release dovrebbe provenire dalla build che le ha prodotte.
Anche una SBOM di CRACI ha i propri limiti. Copre i job eseguiti sui runner CRACI, il che oggi significa GitHub Actions su Linux, con altri sistemi CI in roadmap.
Deve scegliere tra gli strumenti? Veda gli strumenti SBOM a confronto, oppure scopra come le SBOM in fase di build si inseriscono nel lavoro di conformità al CRA. Per un confronto diretto tra Syft, Trivy e cdxgen, veda che cosa sfugge ai generatori di SBOM open source.
SBOM in fase di build: domande frequenti
Che cos'è una SBOM in fase di build?
Una SBOM in fase di build, che CISA chiama build SBOM, viene generata nell'ambito della build dell'artefatto rilasciabile. Invece di ricostruire a posteriori l'elenco dei componenti dai file, descrive ciò che la build stessa ha usato. CRACI la registra dai pacchetti effettivamente scaricati da ciascun job GitHub Actions.
Qual è la differenza tra una SBOM di build e una SBOM analizzata?
Una SBOM analizzata viene generata dopo la build analizzando un artefatto, come un eseguibile o un'immagine container, il che richiede in genere euristiche. Una SBOM di build viene generata durante la build, dalle informazioni di cui la build dispone. Le SBOM analizzate funzionano senza accesso alla build, e questo le rende la scelta giusta per il software che Lei non ha compilato.
Come si genera una SBOM per un'immagine Docker?
Per un'immagine esistente, la scansioni con un generatore come Syft, Trivy o docker scout sbom. BuildKit può anche allegare un'attestazione SBOM durante la build, scansionando l'immagine finale. Per registrare ciò che la build di un'immagine ha introdotto, esegua la build su un runner CRACI: la SBOM del job copre le immagini e i pacchetti che ha scaricato.
Che cosa sono le dipendenze nascoste?
Tutto ciò che una build scarica e che nessun lockfile elenca: il codice scaricato dagli hook di installazione npm, i file che gli script di build di Rust scaricano in fase di build e l'immagine base con i suoi layer del sistema operativo in una build di container. Gli strumenti che leggono il lockfile o scansionano l'output non le vedono. CRACI le registra perché vede il traffico in ingresso nella build.
Perché due build dello stesso codice danno SBOM diverse?
Perché la maggior parte delle build non è riproducibile. Il package manager risolve e installa i pacchetti nell'ordine in cui arrivano le risposte, soprattutto senza un lockfile, e i passaggi di build possono includere elementi casuali. Compili lo stesso commit due volte, una dopo l'altra, e la seconda build può contenere pacchetti diversi. Solo la SBOM registrata durante la build che ha prodotto una release dimostra che cosa contiene quella release.
Una SBOM in fase di build è sempre completa?
Non automaticamente. Una registrazione vale quanto ciò che riesce a osservare, per questo CRACI indica la completezza di ogni job e di ogni cache: Complete, Complete with connections, Incomplete, Unavailable o Not recorded. Lei sa quali SBOM sono affidabili e quali richiedono una seconda verifica.
Una SBOM in fase di build sostituisce gli scanner SBOM?
Per il software che compila Lei, sì: la SBOM delle Sue release dovrebbe provenire dalle build che le hanno prodotte. Per le immagini e i binari di terze parti che non ha compilato Lei, uno scanner resta la scelta pratica. Strumenti SBOM a confronto illustra le opzioni.
Quale generatore di SBOM usa CRACI?
Nessuno. CRACI non scansiona file. Un proxy sui suoi runner che riconosce i pacchetti registra i pacchetti che ogni job scarica da npm, PyPI, RubyGems, Cargo, Go, Nix, OCI, apt, apk e sorgenti Git, oltre ai preset di download di Yocto e OpenEmbedded, ed esporta il risultato in CycloneDX o SPDX.
Confronti una SBOM della Sua build
Prenoti una demo ed esegua uno dei Suoi workflow su CRACI. Metta la sua SBOM accanto a quella prodotta dal Suo strumento attuale e veda dove differiscono.
Prenota una demo