Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Guida per sviluppatori di plugin
Questa guida spiega come estendere Amazon Inspector SBOM Generator (inspector-sbomgen) con plugin Lua personalizzati. I plugin consentono di aggiungere il supporto per nuovi ecosistemi di pacchetti senza modificare il codice sorgente di sbomgen o doverlo ricompilare.
Per il catalogo completo delle funzioni, vedi. Riferimento all'API del plugin Per indicazioni sui test di scrittura, vedere ilGuida al test dei plugin.
Panoramica di
I plugin Sbomgen sono scritti in Lua e seguono una pipeline in due fasi:
-
Discovery: scansiona l'elenco dei file dell'artefatto e segnala quali file sono rilevanti per il tuo ecosistema.
-
Raccolta: analizza ogni file scoperto e inserisci i risultati del pacchetto nello SBOM.
Modello di eventi del plugin
I plugin Discovery necessitano di un modo per comunicare ai plugin di raccolta che i file contenenti i metadati dei pacchetti sono stati scoperti nell'artefatto sotto inventario. Per facilitare questa condivisione dei dati, i plugin di discovery definiscono un nome di evento e restituiscono un elenco di percorsi di file. I plugin di raccolta si iscrivono a quell'evento e ricevono ogni percorso di file corrispondente. Questo separa il rilevamento dei file dall'analisi: puoi fare in modo che un plugin di discovery alimenti più raccoglitori (modello fan-out). Tuttavia, ogni plug-in di scoperta deve avere un nome di evento univoco e ogni plug-in di raccolta deve avere un nome di raccoglitore univoco. Per informazioni dettagliate, vedi Regole di collisione dei plugin.
Gli sviluppatori potrebbero riconoscerlo come il modello di progettazione dell'osservatore.
Questo design consente a un singolo plug-in di rilevamento di attivare più analisi indipendenti in modo efficiente. Ad esempio, un plugin di scoperta può localizzare ogni elemento requirements.txt in un artefatto, quindi alimentare:
-
Un raccoglitore di pacchetti che analizza ogni riga in risultati SBOM ().
name==version -
Un raccoglitore di segreti che contrassegna le righe contenenti chiavi API o token aggiunti accidentalmente come versioni.
-
Un raccoglitore di policy che riporta gli identificatori di versione non bloccati o con caratteri jolly.
Ogni raccoglitore viene eseguito in modo indipendente sullo stesso elenco di file senza dover ripercorrere il file system dell'elemento. Ciò consente inoltre agli autori di plug-in di aggiungere nuovi plug-in di raccolta che sottoscrivono eventi esistenti senza dover modificare il plug-in di rilevamento corrispondente.
Avvio rapido: creazione di nuovi plugin
Il modo più veloce per creare un nuovo plugin è utilizzare il comando scaffolding integrato:
inspector-sbomgen plugin new
Il comando richiede il nome del plugin e la directory del progetto. Premendo Invio si accetta l'impostazione predefinita mostrata tra parentesi:
Plugin name (identifies the software ecosystem your plugin will inventory, e.g. debian-dpkg, rhel-rpm, python-pip, cmake) [my-custom-ecosystem]: cmake Project directory [my-sbomgen-plugins]:
Puoi anche passare direttamente gli argomenti:
inspector-sbomgen plugin new --name cmake --path /tmp/custom-plugins
A partire da un esempio funzionante
Se vuoi sperimentare con i plugin prima di scrivere la tua logica, crea un nuovo plugin usando il --with-example flag:
inspector-sbomgen plugin new --with-example
Questo genera un progetto di plugin completamente funzionante con un parser di lockfile di esempio, dati di test e test di superamento. Il plugin di esempio scopre example.lock i file, analizza le name==version voci e inserisce i pacchetti nella SBOM. Puoi eseguire immediatamente i test per vedere il sistema di plugin in azione, quindi modificare il codice per adattarlo al tuo ecosistema attuale.
Per uno scaffolding avanzato che include tutte le funzioni di override opzionali (get_scanner_name,get_event_name,get_scanner_groups, multi-event discovery, ecc.), usa il --with-overrides flag (ne parleremo più avanti):
inspector-sbomgen plugin new --with-overrides
Completamento del plugin
Dopo lo scaffolding, i file dei plugin generati contengono dei TODO marcatori che indicano dove aggiungere la logica specifica dell'ecosistema. Usa questi marker per trasformare lo scaffold in un plugin funzionante:
-
Sostituisci tutti i
TODOmarker con i tuoi valori effettivi -
Aggiorna il modello del file in
discover()modo che corrisponda ai file di destinazione -
Implementa la logica di analisi
collect()e richiamasbomgen.push_package()ogni pacchetto
Metti alla prova il tuo plugin
Esistono due modi per testare i tuoi plugin:
1. Cablaggio di test integrato: utilizzato inspector-sbomgen plugin test per convalidare la logica del plug-in durante lo sviluppo. Questo esegue i file di init_test.lua test senza bisogno di un vero artefatto da scansionare:
inspector-sbomgen plugin test --path ./my-plugins
Vedi i dettagli sulla scrittura Guida al test dei plugin di file di test e sull'utilizzo dell'API. testing.*
2. End-to-endscan: richiama il plugin usando i comandi sbomgen standard per verificare che funzioni su artefatti reali. Per questo approccio, è necessario fornire sia un artefatto contenente i file a cui è destinato il plugin (ad esempio, una directory con requirements.txt o equivalente) sia il percorso della directory del plugin:
inspector-sbomgen directory \ --path /path/to/test/dir \ --plugin-dir ./my-plugins \ --disable-native-scanners \ -o sbom.json
Il --disable-native-scanners flag garantisce il funzionamento solo dei plugin Lua, facilitando il test senza l'output degli scanner integrati (nativi).
Configurazione IDE
Sbomgen fornisce il completamento del codice, il controllo del tipo e la documentazione in linea per l'intera sbomgen.* API in VS Code.
VS Code con Lua Language Server
-
Apri qualsiasi file nel tuo progetto di plugin
.lua
Sono state completate tutte le operazioni! Il plugin new comando genera .vscode/settings.json e library/sbomgen.lua viene rilevato automaticamente dal Lua Language Server. Otterrai immediatamente:
-
Completamento del codice per tutte le
sbomgen.*funzioni -
Suggerimenti sui parametri con tipi
-
Documentazione Hover
-
Controllo dei tipi
Struttura delle cartelle dei plugin
I plugin di scoperta e raccolta di Sbomgen devono rispettare la seguente struttura di directory:
{plugin-dir}/ ├── discovery/ │ └── {platform}/ │ └── {category}/ │ └── {ecosystem}/ │ └── init.lua # REQUIRED entrypoint └── collection/ └── {platform}/ └── {category}/ └── {ecosystem}/ └── init.lua # REQUIRED entrypoint
Questi nomi di directory hanno un significato semantico: sbomgen li usa per ricavare i metadati predefiniti per il plugin, tra cui il nome dello scanner, il nome dell'evento, i gruppi di scanner e il filtraggio della piattaforma. Ciò riduce la quantità di testo standard che gli sviluppatori dovrebbero altrimenti scrivere. La scelta dei valori corretti assicura che il plugin si integri correttamente con il modello di selezione ed esecuzione dello scanner di sbomgen.
Le sezioni seguenti esplorano la struttura delle directory in modo più dettagliato, fornendo indicazioni sul significato e sulle convenzioni semantiche.
Platform (Piattaforma)
La directory della piattaforma controlla i sistemi operativi su cui viene eseguito il plug-in.
| Valore | Quando usare |
|---|---|
cross-platform |
Il plugin funziona su qualsiasi sistema operativo (la maggior parte dei plugin) |
linux |
Logica di rilevamento specifica per Linux |
windows |
Logica di rilevamento specifica per Windows |
macos |
Logica di rilevamento specifica per macOS |
Categoria
La directory delle categorie determina i gruppi di scanner predefiniti assegnati al plug-in, che controlla se viene eseguito per impostazione predefinita o richiede un consenso esplicito. Scoprite come Selezione dello scanner i gruppi influiscono sull'esecuzione.
| Valore | Gruppi predefiniti | Quando usare |
|---|---|---|
proglang |
programming-language-packages, pkg-scanner |
Pacchetti di linguaggi di programmazione (pip, npm, maven, ecc.) |
os |
os, pkg-scanner |
Gestori di pacchetti del sistema operativo (dpkg, rpm, apk, ecc.) |
extra-ecosystems |
extra-ecosystems, pkg-scanner |
Applicazioni e runtime (nginx, curl, wordpress, ecc.) |
Se si utilizza un nome di categoria che non corrisponde a nessuno dei nomi precedenti, il nome della categoria stesso viene utilizzato come gruppo.
Ecosistema
Un nome per l'ecosistema di pacchetti specifico (ad esempiopython-pip,python-poetry,,debian-dpkg,curl). I nomi con trattino sono una convenzione comune ma non un requisito rigoroso.
Il nome dello scanner e il nome del raccoglitore derivano direttamente dal nome della directory dell'ecosistema.
Associazione dei nomi degli eventi
I plugin di scoperta e raccolta nello stesso percorso di directory vengono associati automaticamente. Ad esempio, un plug-in di rilevamento in si accoppia discovery/cross-platform/proglang/python-pip/ automaticamente con. collection/cross-platform/proglang/python-pip/
Puoi sovrascriverlo definendo get_event_name() e subscribe_to_event() nei tuoi plugin.
Plugin Discovery
Un plugin di scoperta richiede solo la discover() funzione. Tutte le altre funzioni sono opzionali: le impostazioni predefinite derivano dal percorso della directory.
La maggior parte dei plugin di discovery funziona localizzando file i cui nomi o percorsi identificano un ecosistema specifico, ad esempio per requirements.txt Python pip, package.json per npm o per Rust cargo. Cargo.lock Le sbomgen.find_files_by_* funzioni eseguono questa corrispondenza all'esterno della macchina virtuale Lua, il che le rende significativamente più veloci rispetto all'iterazione dell'elenco completo dei file in Lua:
-- REQUIRED: Scans the artifact and returns a table of file paths. function discover() return sbomgen.find_files_by_name({"requirements.txt"}) end
discover()deve restituire una tabella Lua (array) di stringhe. Se non viene trovato alcun file, restituisci una tabella vuota. {}
Schemi di scoperta comuni
| Obiettivo | Funzione consigliata |
|---|---|
| Corrisponde a uno o più nomi di file esatti | sbomgen.find_files_by_name({names}) |
| Abbina i nomi dei file senza distinzione tra maiuscole e minuscole | sbomgen.find_files_by_name_icase({names}) |
Corrispondenza per suffisso di percorso (ad es.) /pom.properties |
sbomgen.find_files_by_suffix({suffixes}) |
| Corrispondenza per espressione regolare a percorso completo | sbomgen.find_files_by_path_regex({patterns}) |
Corrispondenza del nome di base in stile Glob (ad es.) *.lock |
sbomgen.glob_find_files(pattern) |
Quando la tua logica richiede un post-filtraggio, ad esempio, mantenendo i file corrispondenti a un suffisso ma escludendo le directory di output di compilazione, combina una chiamata con un ciclo Lua: find_files_by_*
function discover() local found = {} for _, f in ipairs(sbomgen.find_files_by_suffix({".conda-meta.json"})) do if not f:match("[/\\]%.cache[/\\]") then table.insert(found, f) end end return found end
Evita di effettuare il discovery sbomgen.get_file_list() a meno che non sia adatto a nessun altro matcher: copia ogni percorso nella macchina virtuale Lua e può richiedere diversi secondi su artefatti di grandi dimensioni. Vedi per i dettagli. Riferimento all'API del plugin
Scoperta di più eventi
Per impostazione predefinita, tutti i file restituiti da discover() vengono pubblicati in un singolo evento (daget_event_name()). Se lo scanner deve indirizzare file diversi a raccoglitori diversi, restituisci invece una tabella con chiavi:
function discover() return { EventNameFoundCurl = sbomgen.find_files_by_name({"curl", "curl.exe"}), EventNameFoundLibcurl = sbomgen.find_files_by_name({"curlver.h"}), } end
Quando discover() restituisce una tabella con chiavi di stringa, ogni chiave viene trattata come un nome di evento separato e il relativo valore (una tabella di percorsi di file) viene pubblicato in quell'evento. I plugin di raccolta si iscrivono a eventi specifici subscribe_to_event() come di consueto.
È retrocompatibile: la restituzione di una tabella sequenziale funziona {"file1", "file2"} ancora come modalità a evento singolo. Il rilevamento è automatico: le tabelle con qualsiasi chiave di stringa sono multievento, le tabelle con solo chiavi intere (o vuote) sono a evento singolo.
Quando si utilizza un evento multiplo, non get_event_name() viene utilizzato per la pubblicazione (i nomi degli eventi provengono dalle chiavi della tabella restituite). Tuttavia, viene ancora chiamato durante il caricamento del plugin per il rilevamento delle collisioni, quindi dovrebbe restituire un valore univoco o essere omesso per utilizzare l'impostazione predefinita.
Funzioni di rilevamento opzionali
Tutti questi hanno valori predefiniti validi derivati dal percorso della directory. Definiscili solo se devi sovrascrivere:
| Funzione | Impostazione predefinita | Sostituisci quando... |
|---|---|---|
get_scanner_name() |
{ecosystem}(ad esempio,python-pip) |
Desideri un nome personalizzato per lo scanner |
get_scanner_description() |
"Lua discovery plugin: {ecosystem}" |
Vuoi una descrizione personalizzata |
get_scanner_groups() |
Derivato dalla directory delle categorie | Sono necessari gruppi non standard |
get_event_name() |
Derivato dal percorso della directory | È necessario un routing degli eventi personalizzato |
get_localhost_scan_paths() |
Nessuno | Il tuo plugin necessita di percorsi specifici scansionati durante le scansioni localhost |
Percorsi di scansione Localhost
Quando sbomgen esegue una localhost scansione, percorre le directory specificate dall'utente e tutti i percorsi predefiniti dichiarati dagli scanner. Per impostazione predefinita, i plugin di scoperta Lua non forniscono alcun percorso, quindi i file al di fuori delle directory specificate dall'utente non verranno visualizzati nell'elenco dei file.
Definire get_localhost_scan_paths() di restituire le directory o i percorsi dei file che il localhost walker deve includere:
function get_localhost_scan_paths() return { "/usr/bin", "/usr/local/bin", } end
I percorsi restituiti vengono aggiunti all'elenco di scansione del walker solo durante le localhost scansioni e non hanno alcun effetto su, o sulle scansioni. container directory archive
Percorsi di scansione specifici della piattaforma
Quando i file che ti interessano risiedono in posizioni diverse su Windows, macOS e Linux, esegui il branch sbomgen.get_platform() e restituisci i percorsi appropriati per l'host:
function get_localhost_scan_paths() local platform = sbomgen.get_platform() if platform == sbomgen.platform.WINDOWS then local drive = sbomgen.get_system_drive() return { drive .. "/Program Files/MyApp/myapp.exe", drive .. "/Program Files (x86)/MyApp/myapp.exe", } end if platform == sbomgen.platform.DARWIN then return {"/Applications/MyApp.app/Contents/MacOS/myapp"} end -- Linux return { "/usr/bin/myapp", "/usr/local/bin/myapp", } end
In Windows, utilizzatela sbomgen.get_system_drive() per risolvere la lettera dell'unità di sistema (ad esempio"C:") anziché codificarla. Per i percorsi derivati da variabili di ambiente come LOCALAPPDATA orPROGRAMFILES, iterate sbomgen.get_env_vars() e cercate il valore per chiave. Vedi Riferimento all'API del plugin per i dettagli.
Plugin di raccolta
Un plugin di raccolta richiede solo la collect() funzione. Tutte le altre funzioni sono opzionali.
collect(file_path)viene chiamato una volta per file scoperto dal plug-in di rilevamento associato. Lo schema tipico è:
-
Leggi il contenuto del file usando
sbomgen.read_file()(per file di piccole dimensioni caricati in memoria) osbomgen.open_file()(per file di grandi dimensioni letti line-by-line). -
Analizza il contenuto: la corrispondenza delle stringhe per i manifesti semplici,
sbomgen.json_decode()per JSON, per XML osbomgen.xml_decode()sbomgen.search_binary()per i binari compilati. -
Pubblica ogni pacchetto scoperto chiamando
sbomgen.push_package()con i metadati del pacchetto.
-- REQUIRED: Called once per discovered file. -- Parse the file and call sbomgen.push_package() for each package found. function collect(file_path) local content, err = sbomgen.read_file(file_path) if err or not content then return end for line in content:gmatch("[^\r\n]+") do local name, version = line:match("^([%w%-%_%.]+)==(.+)$") if name and version then sbomgen.push_package({ name = name, version = version, purl_type = "pypi", component_type = sbomgen.component_types.LIBRARY, }) end end end
collect()non restituisce un valore. Ogni push_package() chiamata richiede namepurl_type, ecomponent_type. Consulta la sezione Riferimento all'API del plugin per tutti i campi supportati.
Allegare metadati ai componenti
Sbomgen supporta due modi per allegare i metadati a un componente del pacchetto: i qualificatori PURL e le proprietà CyclonedX. Servono a scopi diversi e la scelta tra di essi ha implicazioni sul modo in cui Amazon Inspector identifica le vulnerabilità nella SBOM risultante.
| Meccanismo | Dove appare | Utilizzare per |
|---|---|---|
qualifiers |
All'interno dell'URL del pacchetto (ad esempio,pkg:deb/debian/curl@7.88.1?arch=amd64) |
Dati che fanno parte dell'identità del pacchetto |
properties |
Nell'array della SBOM components[].properties |
Metadati descrittivi che non modificano il modo in cui il pacchetto viene identificato |
Raccomandazione: preferisci le proprietà CyclonedX (con il tuo spazio dei nomi) per i metadati personalizzati. Le proprietà non alterano l'identità di un componente, quindi non possono influire sull'identificazione delle vulnerabilità di Amazon Inspector. Riserva i qualificatori PURL nei casi in cui il tipo PURL del tuo ecosistema li richieda.
Qualificatori PURL
Alcuni qualificatori PURL hanno un significato semantico per Amazon Inspector e influenzano l'identificazione delle vulnerabilità. Ad esempio, sui deb componenti Inspector utilizza qualificatori come arch e distro per selezionare il feed di vulnerabilità corretto; sui generic componenti per i file binari compilati, qualificatori come o identificano la toolchain utilizzata. go_toolchain rust_toolchain L'impostazione di un qualificatore che Inspector non riconosce o l'omissione di uno previsto può far sì che le vulnerabilità non vengano riconosciute o attribuite erroneamente.
Vedi Cos'è l'URL di un pacchetto? nella guida per l'utente di Amazon Inspector per le convenzioni di qualificazione riconosciute da Inspector per tipo di PURL.
Imposta i qualificatori tramite la tabella su: qualifiers sbomgen.push_package()
sbomgen.push_package({ name = "curl", version = "7.88.1", purl_type = "deb", namespace = "debian", component_type = sbomgen.component_types.LIBRARY, qualifiers = { arch = "amd64", distro = "debian-12", }, })
Imposta i qualificatori solo quando sono in linea con le aspettative di Inspector per il tipo PURL. Se devi registrare metadati che non fanno parte dell'identità del pacchetto, usa invece le proprietà CyclonedX.
proprietà CyclonedX
Le proprietà CyclonedX sono annotazioni chiave-valore che appaiono nell'array di SBOM. components[].properties Descrivono un componente senza influire sul modo in cui viene identificato, quindi sono la scelta sicura per i metadati definiti dal plug-in.
I amazon:inspector:* namespace sono riservati ad Amazon Inspector. Nello specifico:
-
amazon:inspector:sbom_generator:*— riservato a sbomgen e ai suoi scanner integrati. -
amazon:inspector:sbom_scanner:*— riservato all'API Amazon Inspector Scan.
Gli autori dei plugin non devono emettere chiavi all'interno di questi namespace riservati. La scrittura in essi può interferire con il comportamento di Inspector e può essere sovrascritta. Per l'elenco completo delle chiavi riservate, consulta Utilizzo degli spazi dei nomi CyclonedX con Amazon Inspector.
Usa il tuo spazio dei nomi (in genere l'identificatore dell'organizzazione o del plug-in) per definire le proprietà:
sbomgen.push_package({ name = "requests", version = "2.28.1", purl_type = "pypi", component_type = sbomgen.component_types.LIBRARY, properties = { ["acme:python:manifest_path"] = file_path, ["acme:python:pinned"] = "true", ["acme:python:source"] = "requirements.txt", }, })
Regole di denominazione chiave
Le chiavi di proprietà vengono elaborate da sbomgen come segue:
-
Una chiave che contiene i due punti viene usata letteralmente in SBOM. Includi sempre almeno un punto nelle chiavi in modo da controllare lo spazio dei nomi.
-
Una chiave che non contiene i due punti viene automaticamente preceduta da
amazon:inspector:sbom_generator:— inserendola all'interno dello spazio dei nomi riservato Inspector. Evita questa forma per le proprietà personalizzate.
properties = { ["acme:my_plugin:detected_via"] = "lockfile", -- used as-is (recommended) detected_via = "lockfile", -- becomes "amazon:inspector:sbom_generator:detected_via" (avoid) }
Le sbomgen.properties.* costanti esistono in modo che gli scanner ufficiali emettano chiavi coerenti all'interno dello spazio dei nomi riservato. Non sono punti di estensione per plugin personalizzati: usa invece il tuo spazio dei nomi.
Proprietà e qualificatori sui componenti secondari
I componenti annidati children sono indipendenti. Ogni figlio ha le proprie properties qualifiers tabelle; i metadati impostati sul genitore non si propagano ai figli. Imposta i valori in modo esplicito per ogni bambino che ne ha bisogno.
Funzioni di raccolta opzionali
| Funzione | Impostazione predefinita | Sostituisci quando... |
|---|---|---|
get_collector_name() |
{ecosystem}(ad esempio,python-pip) |
Vuoi un nome da collezionista personalizzato |
get_collector_description() |
Stringa vuota | Vuoi una descrizione |
subscribe_to_event() |
Derivato dal percorso della directory | È necessario un routing degli eventi personalizzato |
Esecuzione dei plugin
Affinché i plugin producano i metadati dei pacchetti, a sbomgen deve essere assegnato un artefatto da scansionare che contenga i file a cui sono destinati i plugin (ad esempio, una directory con requirements.txtpackage.json, o file manifest del pacchetto equivalenti).
Utilizzo di base
inspector-sbomgen <artifact type> <arguments> --plugin-dir /path/to/plugins
Esempio:
inspector-sbomgen directory --path /target -o /tmp/sbom.json --plugin-dir /path/to/plugins
Con gli scanner nativi disabilitati (modalità solo LUA)
inspector-sbomgen directory --path /target --plugin-dir /path/to/plugins --disable-native-scanners -o sbom.json
Con registrazione dettagliata
inspector-sbomgen directory --path /target --plugin-dir /path/to/plugins --verbose -o sbom.json
Elenco degli scanner disponibili
Usa list-scanners per vedere tutti gli scanner disponibili per sbomgen. Ciò include gli scanner nativi integrati, tutti i plugin Lua ufficiali forniti in bundle con sbomgen e tutti i plugin Lua personalizzati che hai fornito tramite: --plugin-dir
inspector-sbomgen list-scanners --plugin-dir /path/to/plugins
┌─────────────────────┬────────┬───────────────────────────────┬─────────────────────────────┐ │ SCANNER NAME │ SOURCE │ GROUPS │ DESCRIPTION │ ├─────────────────────┼────────┼───────────────────────────────┼─────────────────────────────┤ │ curl │ custom │ extra-ecosystems │ Discovers curl version │ │ │ │ pkg-scanner │ header files (curlver.h) │ ├─────────────────────┼────────┼───────────────────────────────┼─────────────────────────────┤ │ python-requirements │ custom │ pkg-scanner │ Discovers requirements*.txt │ │ │ │ programming-language-packages │ files for Python pip │ │ │ │ │ packages │ └─────────────────────┴────────┴───────────────────────────────┴─────────────────────────────┘
La colonna SOURCE mostra la provenienza di ogni scanner:
| Origine | Significato |
|---|---|
native |
Scanner integrato fornito in dotazione con sbomgen |
official |
Plugin Lua in bundle con sbomgen |
custom |
Plugin Lua fornito dall'utente caricato tramite --plugin-dir |
Running list-scanners without include --plugin-dir ancora entrambi native official gli scanner, che sono sempre disponibili. La --plugin-dir bandiera aggiunge custom gli scanner all'elenco.
Per elencare solo gli scanner Lua senza scanner nativi:
inspector-sbomgen list-scanners --plugin-dir /path/to/plugins --disable-native-scanners
Selezione dello scanner
I plugin Lua Discovery rientrano nello stesso modello di selezione degli scanner nativi integrati. Per impostazione predefinita, sbomgen esegue tutti gli scanner i cui gruppi corrispondono ai gruppi di scanner predefiniti per il tipo di artefatto. Puoi sovrascriverlo con tre flag:
Esegui solo scanner specifici
Utilizzare --scanners per eseguire solo gli scanner indicati. Sono esclusi tutti gli altri scanner:
inspector-sbomgen directory --path /target \ --plugin-dir /path/to/plugins \ --scanners python-requirements \ -o sbom.json
Questo fa funzionare solo lo python-requirements scanner. È possibile passare più nomi di scanner separati da virgole o passare il nome di un gruppo di scanner (ad esempioprogramming-language-packages) per abilitare tutti gli scanner che appartengono a quel gruppo.
Escludi scanner specifici
Usa --skip-scanners per escludere gli scanner con nome mentre esegui tutto il resto:
inspector-sbomgen directory --path /target \ --plugin-dir /path/to/plugins \ --skip-scanners python-poetry \ -o sbom.json
Questo esegue tutti gli scanner predefiniti trannepython-poetry. Ad esempio--scanners, questo flag accetta anche nomi di gruppo, quindi il passaggio --skip-scanners programming-language-packages disabilita tutti gli scanner di quel gruppo.
Nota
--scannerse si --skip-scanners escludono a vicenda. Il passaggio di entrambi produce un errore.
Aggiungere scanner da gruppi non predefiniti
Il set di scanner predefinito dipende dal tipo di artefatto da scansionare (vedi la matrice riportata di seguito). In che modo i gruppi influiscono sulla selezione Uno scanner i cui gruppi non fanno parte del set predefinito per il tipo di artefatto non funzionerà a meno che non venga attivato. --additional-scannersUtilizzatelo per aggiungere gli scanner al set predefinito senza sostituirlo:
inspector-sbomgen directory --path /target \ --plugin-dir /path/to/plugins \ --additional-scanners my-extra-scanner \ -o sbom.json
Questo esegue tutti gli scanner predefiniti per il tipo di artefatto, e in più. my-extra-scanner Il flag accetta un elenco separato da virgole di nomi di scanner o nomi di gruppi e si sovrappone all'impostazione predefinita anziché sostituirla. Si usa list-scanners per controllare a quali gruppi appartiene uno scanner.
In che modo i gruppi influiscono sulla selezione
La get_scanner_groups() funzione del plugin di scoperta determina a quali gruppi appartiene lo scanner. Il funzionamento predefinito di uno scanner dipende sia dai suoi gruppi che dal tipo di artefatto sottoposto a scansione. La matrice seguente mostra quali gruppi sono inclusi nel set di scanner predefinito per ogni tipo di artefatto:
| Group (Gruppo) | directory / archive |
container |
localhost |
volume |
binary |
|---|---|---|---|---|---|
os |
— | ✓ | ✓ | ✓ | — |
programming-language-packages |
✓ | ✓ | ✓ | ✓ | — |
binary |
✓ | ✓ | — | — | ✓ |
extra-ecosystems |
— | ✓ | ✓ | ✓ | — |
dockerfile |
✓ | ✓ | — | — | — |
custom |
✓ | ✓ | ✓ | ✓ | ✓ |
certificate |
— | — | — | — | — |
machine-learning |
— | — | — | — | — |
pkg-scanner |
— | — | — | — | — |
A ✓ indica che ogni scanner di quel gruppo viene eseguito per impostazione predefinita per quel tipo di artefatto. A — significa che il gruppo non è incluso nel set predefinito, quindi i suoi scanner funzionano solo se selezionati esplicitamente tramite o. --scanners --additional-scanners
Dettagli importanti:
-
customè sempre nel set predefinito: i plugin personalizzati caricati tramite ricevono--plugin-dirautomaticamente ilcustomgruppo, quindi vengono eseguiti per impostazione predefinita indipendentemente dal tipo di artefatto. -
extra-ecosystemsè l'impostazione predefinita percontainerlocalhost, evolumescansiona, ma non perdirectory,archiveo scansiona.binaryPer questi tipi è necessario passare--additional-scanners(per nome o perextra-ecosystemsgruppo) per includerli. -
pkg-scannerè informativo: contrassegna lo scanner come raccoglitore di pacchetti in cui visualizzarlolist-scanners, ma di per sé non causa il funzionamento dello scanner. Associalo a un gruppo di esecuzione (ad esempio,programming-language-packages) in.get_scanner_groups()
Ad esempio, un plug-in che restituisce {sbomgen.groups.EXTRA_ECOSYSTEMS, sbomgen.groups.PACKAGE_COLLECTOR} verrà eseguito per impostazione predefinita sulle scansioni di contenitori, localhost e volumi, ma richiederà --additional-scanners (o--scanners) sulle scansioni di directory, archivi e binarie.
Regole di collisione dei plugin
Sbomgen applica metadati unici su tutti i plugin caricati per prevenire sovrascritture silenziose e garantire l'integrità SBOM. Quando viene rilevata una collisione, il plugin successivo viene ignorato e viene registrato un avviso.
Cosa viene controllato
| Metadati | Scope (Ambito) | In caso di collisione |
|---|---|---|
Nome dell'evento Discovery () get_event_name |
Tutti i plugin di scoperta | Il secondo plugin è stato ignorato |
Nome dello scanner () get_scanner_name |
Tutti i plugin di scoperta | Il secondo plugin è stato ignorato |
Nome del collezionista () get_collector_name |
Tutti i plugin di raccolta | Il secondo plugin è stato ignorato |
Cosa è permesso
Più plugin di raccolta possono iscriversi allo stesso evento tramitesubscribe_to_event(). Questo è lo schema di fan-out previsto: un plugin di discovery può alimentare più raccoglitori, ognuno dei quali fa cose diverse (ad esempio, uno estrae pacchetti, un altro rileva segreti).
Evitare le collisioni
Se due plugin utilizzano lo stesso nome di scanner, nome di evento o nome di raccoglitore, il secondo plugin caricato viene saltato. Per risolvere le collisioni, rinomina i metadati in conflitto definendo la funzione di override appropriata nel tuo plugin (,, or). get_scanner_name() get_event_name() get_collector_name()
Esempio di avviso di collisione
[custom:python-pip] SKIPPED: discovery event name "EventNameFoundPythonRequirements" is already registered by [official:python-pip]. Each discovery plugin must have a unique event name. Rename get_event_name() in your plugin to use a unique name.
L'avviso indica quale plugin è stato ignorato, cosa è entrato in collisione, quale plugin possiede già quel nome e quale funzione modificare.
Debug
Registrazione di log della console
I plugin possono inviare messaggi all'output della console di sbomgen usando le seguenti funzioni:
| Funzione | Livello | Visibile per impostazione predefinita? |
|---|---|---|
sbomgen.log_debug(message) |
DEBUG | No, richiede --verbose |
sbomgen.log_info(message) |
INFO | Sì |
sbomgen.log_warn(message) |
WARN | Sì |
sbomgen.log_error(message) |
ERRORE | Sì |
Tutti gli output di log di un plugin sono automaticamente preceduti dall'origine e dal percorso del plugin (ad esempio,[custom:python-pip]), in modo che i messaggi provenienti da diversi plugin siano facili da distinguere. log_infolog_warn, e stampa log_error sempre; stampa log_debug solo quando viene invocato sbomgen. --verbose
function discover() sbomgen.log_info("starting discovery") local files = sbomgen.find_files_by_name({"requirements.txt"}) sbomgen.log_debug(string.format("matched %d files", #files)) if #files == 0 then sbomgen.log_warn("no requirements.txt files found") end return files end
Punti di interruzione
Si usa sbomgen.breakpoint() per mettere in pausa l'esecuzione del plugin e bloccarlo finché non si preme Invio. Funziona come un semplice debugger: combinalo con le istruzioni di registro per ispezionare lo stato in punti specifici.
function discover() local files = sbomgen.find_files_by_name({"requirements.txt"}) sbomgen.log_info(string.format("about to inspect %d files", #files)) sbomgen.breakpoint("before file inspection — press Enter to continue") local found = {} for _, f in ipairs(files) do if not f:match("[/\\]tests[/\\]") then table.insert(found, f) end end sbomgen.log_info(string.format("kept %d files after filtering", #found)) sbomgen.breakpoint("after filtering — press Enter to continue") return found end
Il messaggio di breakpoint viene stampato su stderr. L'esecuzione si interrompe finché non si preme Invio, dandovi il tempo di esaminare l'output del registro.
Problemi comuni
| Sintomo | Causa | Correggere |
|---|---|---|
| Plugin non caricato | init.lua mancante |
Assicurati che il punto di ingresso esista alla profondità corretta della directory |
| «funzione richiesta mancante» | Errore di battitura nel nome della funzione | Verifica cheget_scanner_name,get_scanner_description,get_scanner_groups,discover,get_event_name,get_localhost_scan_paths, get_collector_namecollect, subscribe_to_event siano definiti |
| Il plugin di raccolta non è mai stato chiamato | Mancata corrispondenza del nome dell'evento | Verifica get_event_name() e subscribe_to_event() restituisci la stessa stringa |
| Nessun pacchetto in SBOM | push_packagecampi non chiamati o obbligatori mancanti |
Assicurati name e purl_type component_type sono impostati in ogni push_package chiamata (bambini compresi). Usa le sbomgen.component_types.* costanti. |
| Errore di runtime nel plugin | Errore Lua durante l'esecuzione | Controlla l'output di sbomgen per i messaggi di avviso con i dettagli dell'errore |
| «SKIPPED: il nome dell'evento di scoperta... è già registrato» | Un altro plugin utilizza lo stesso nome di evento | Rinomina get_event_name() con un valore univoco |
| «SKIPPED: il nome dello scanner... è già registrato» | Un altro plugin utilizza lo stesso nome dello scanner | Rinomina get_scanner_name() con un valore univoco |
| «SKIPPED: il nome del collezionista... è già registrato» | Un altro plugin utilizza lo stesso nome del raccoglitore | Rinomina con un get_collector_name() valore univoco |
Documentazione di riferimento delle API
Il catalogo completo delle funzioni è conservato in un documento complementare:
→ Riferimento all'API del plugin
Il riferimento all'API copre ogni sbomgen.* funzione (I/O dei file, utilità binarie, output dei pacchetti, regex, analisi strutturata, registro di Windows, registrazione, debug), l'testing.*API disponibile nei file di test, tutte le costanti integrate (,,,) e i dati globali del ciclo di vita dei properties plug-ingroups. component_types platform
Gestione errori
Le funzioni API che possono fallire restituiscono due value, err valori:. In caso di successo, err ènil. In caso di errore, il primo valore è nil ed err è una stringa di errore.
local content, err = sbomgen.read_file(path) if err then sbomgen.log_error("failed to read " .. path .. ": " .. err) return end -- content is safe to use here
Se un plugin genera un errore Lua non gestito, sbomgen registra un avviso e continua con il file o il plugin successivo. Gli altri plugin non sono interessati.
Restrizioni Sandbox
I plugin vengono eseguiti in una macchina virtuale Lua in modalità sandbox con accesso limitato alla libreria standard:
| Libreria | Disponibilità | Note |
|---|---|---|
base |
✓ | dofileloadfileloadstring,, vengono rimossi |
string |
✓ | Manipolazione completa delle stringhe |
table |
✓ | Manipolazione completa della tabella |
math |
✓ | Libreria matematica completa |
package |
✓ | require()limitato alla directory dei plugin |
io |
✗ | Usa invece sbomgen.* I/O le funzioni |
os |
✗ | Bloccato per motivi di sicurezza |
debug |
✗ | Bloccato per impedire l'introspezione delle VM |
coroutine |
✗ | Non caricato |
L'accesso diretto al file system tramite io.open o non os.execute è disponibile. Tutte le operazioni sui file devono passare attraverso l'sbomgenAPI, che garantisce un comportamento coerente tra i tipi di artefatti e impedisce ai plugin di accedere ai file esterni all'artefatto.
require()può caricare i moduli solo dall'interno dell'albero di directory del plugin. L'attraversamento della directory principale, ad esempio è bloccato. require("../shared")
Condivisione del codice tra plugin
Puoi usare require() per caricare i moduli di supporto dall'interno della directory del tuo plugin:
my-ecosystem/ ├── init.lua └── helpers.lua
-- helpers.lua local M = {} function M.parse_version(s) return string.match(s, "(%d+%.%d+%.%d+)") end return M
-- init.lua local helpers = require("helpers") function subscribe_to_event() return "MyEvent" end function collect(file_path) local content, err = sbomgen.read_file(file_path) if err then return end local version = helpers.parse_version(content) -- ... end
Sono supportate anche le sottodirectory coninit.lua:
my-ecosystem/ ├── init.lua └── parsers/ └── init.lua
local parsers = require("parsers")
require()è limitato alla cartella del tuo plugin. Non è possibile caricare moduli da altri plugin o percorsi di sistema. Le librerie Lua di terze parti (ad esempio, from LuaRocks) non sono supportate: possono essere caricati solo i moduli di supporto locali all'interno della directory dei plugin.