Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Leitfaden für Plugin-Entwickler
In diesem Handbuch wird erklärt, wie Sie Amazon Inspector SBOM Generator (inspector-sbomgen) mit benutzerdefinierten Lua-Plugins erweitern. Mit Plugins können Sie Unterstützung für neue Paket-Ökosysteme hinzufügen, ohne den Quellcode von sbomgen zu ändern oder neu kompilieren zu müssen.
Den vollständigen Funktionskatalog finden Sie im. Plugin-API-Referenz Anleitungen zum Schreiben von Tests finden Sie imLeitfaden zum Testen von Plugins.
-Übersicht
Sbomgen-Plugins sind in Lua geschrieben und folgen einer zweistufigen Pipeline:
-
Discovery — scannt die Dateiliste des Artefakts und meldet, welche Dateien für Ihr Ökosystem relevant sind.
-
Sammlung — analysiert jede entdeckte Datei und überträgt die Ergebnisse des Pakets in die SBOM.
Plugin-Ereignismodell
Discovery-Plugins benötigen eine Möglichkeit, Sammlungs-Plugins mitzuteilen, dass Dateien, die Paketmetadaten enthalten, in dem Artefakt im Inventar entdeckt wurden. Um diesen Datenaustausch zu erleichtern, definieren Discovery-Plugins einen Ereignisnamen und geben eine Liste von Dateipfaden zurück. Sammlungs-Plugins abonnieren dieses Ereignis und empfangen jeden passenden Dateipfad. Dadurch wird die Dateierkennung vom Parsen entkoppelt — Sie können ein Discovery-Plugin für mehrere Collectors verwenden (Fan-Out-Muster). Jedes Discovery-Plugin muss jedoch einen eindeutigen Eventnamen haben, und jedes Collection-Plugin muss einen eindeutigen Collector-Namen haben. Details dazu finden Sie unter Kollisionsregeln für Plugins.
Entwickler erkennen dies möglicherweise als das Observer-Entwurfsmuster.
Dieses Design ermöglicht es einem einzigen Discovery-Plugin, mehrere unabhängige Analysen auf performante Weise auszulösen. Ein Discovery-Plugin kann beispielsweise alle Elemente requirements.txt in einem Artefakt lokalisieren und dann Folgendes einspeisen:
-
Ein Paket-Collector, der jede Zeile nach SBOM-Ergebnissen () analysiert.
name==version -
Ein Secrets-Collector, der Zeilen mit API-Schlüsseln oder Token, die versehentlich angeheftet wurden, als Versionen kennzeichnet.
-
Ein Richtliniensammler, der unverankerte Versionsbezeichner oder Wildcard-Versionsbezeichner meldet.
Jeder Collector wird unabhängig von derselben Dateiliste ausgeführt, ohne dass das Dateisystem des Artefakts erneut durchsucht werden muss. Auf diese Weise können Plugin-Autoren auch neue Sammlungs-Plugins hinzufügen, die bestehende Ereignisse abonnieren, ohne das entsprechende Discovery-Plugin ändern zu müssen.
Schnellstart: Neue Plugins erstellen
Der schnellste Weg, ein neues Plugin zu erstellen, ist die Verwendung des integrierten Scaffolding-Befehls:
inspector-sbomgen plugin new
Der Befehl fordert zur Eingabe eines Plugin-Namens und eines Projektverzeichnisses auf. Durch Drücken der Eingabetaste wird die in Klammern angegebene Standardeinstellung akzeptiert:
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]:
Sie können Argumente auch direkt übergeben:
inspector-sbomgen plugin new --name cmake --path /tmp/custom-plugins
Beginnend mit einem funktionierenden Beispiel
Wenn du mit Plugins experimentieren möchtest, bevor du deine eigene Logik schreibst, erstelle ein neues Plugin mit dem --with-example Flag:
inspector-sbomgen plugin new --with-example
Dadurch wird ein voll funktionsfähiges Plugin-Projekt mit einem Beispiel-Lockfile-Parser, Testdaten und bestandenen Tests generiert. Das Beispiel-Plugin erkennt example.lock Dateien, analysiert name==version Einträge und überträgt Pakete in die SBOM. Sie können die Tests sofort ausführen, um das Plugin-System in Aktion zu sehen, und dann den Code so ändern, dass er auf Ihr aktuelles Ökosystem abzielt.
Für fortgeschrittenes Gerüst, das alle optionalen Override-Funktionen (get_scanner_name, get_event_nameget_scanner_groups, Erkennung mehrerer Ereignisse usw.) beinhaltet, verwende das --with-overrides Flag (dazu später mehr):
inspector-sbomgen plugin new --with-overrides
Vervollständigen Sie Ihr Plugin
Nach dem Aufbau des Gerüsts enthalten die generierten Plugin-Dateien TODO Markierungen, die angeben, wo Sie Ihre ökosystemspezifische Logik hinzufügen müssen. Arbeiten Sie sich durch diese Markierungen, um aus dem Gerüst ein funktionierendes Plugin zu machen:
-
Ersetze alle
TODOMarkierungen durch deine tatsächlichen Werte -
Aktualisieren Sie das Dateimuster so
discover(), dass es Ihren Zieldateien entspricht -
Implementieren Sie die Parsing-Logik in jedem
collect()Paket und rufen Siesbomgen.push_package()es auf
Testen Sie Ihr Plugin
Es gibt zwei Möglichkeiten, deine Plugins zu testen:
1. Integrierter Test-Harness — Wird verwendetinspector-sbomgen plugin test, um die Plugin-Logik während der Entwicklung zu validieren. Dadurch werden Ihre init_test.lua Testdateien ausgeführt, ohne dass ein echtes Artefakt zum Scannen erforderlich ist:
inspector-sbomgen plugin test --path ./my-plugins
Einzelheiten Leitfaden zum Testen von Plugins zum Schreiben von Testdateien und zur Verwendung der API finden Sie imtesting.*.
2. End-to-endscan — Rufe dein Plugin mit Standardbefehlen von sbomgen auf, um zu überprüfen, ob es gegen echte Artefakte funktioniert. Für diesen Ansatz musst du sowohl ein Artefakt angeben, das die Dateien enthält, auf die dein Plugin abzielt (z. B. ein Verzeichnis mit requirements.txt oder ein gleichwertiges Verzeichnis), als auch den Pfad zu deinem Plugin-Verzeichnis:
inspector-sbomgen directory \ --path /path/to/test/dir \ --plugin-dir ./my-plugins \ --disable-native-scanners \ -o sbom.json
Das --disable-native-scanners Flag stellt sicher, dass nur Ihre Lua-Plugins ausgeführt werden, was das Testen ohne Ausgabe der integrierten (nativen) Scanner erleichtert.
IDE-Setup
Sbomgen bietet Codevervollständigung, Typprüfung und Inline-Dokumentation für die gesamte sbomgen.* API in VS Code.
VS-Code mit Lua Language Server
-
Öffne eine beliebige Datei in deinem Plugin-Projekt
.lua
Das war's! Der plugin new Befehl generiert .vscode/settings.json und library/sbomgen.lua wird automatisch vom Lua Language Server erkannt. Sie erhalten sofort:
-
Code-Vervollständigung für alle
sbomgen.*Funktionen -
Parameterhinweise mit Typen
-
Hover-Dokumentation
-
Typüberprüfung
Struktur des Plugin-Verzeichnisses
Plug-ins zur Erkennung und Sammlung von Sbomgen müssen der folgenden Verzeichnisstruktur entsprechen:
{plugin-dir}/ ├── discovery/ │ └── {platform}/ │ └── {category}/ │ └── {ecosystem}/ │ └── init.lua # REQUIRED entrypoint └── collection/ └── {platform}/ └── {category}/ └── {ecosystem}/ └── init.lua # REQUIRED entrypoint
Diese Verzeichnisnamen haben eine semantische Bedeutung — sbomgen verwendet sie, um Standardmetadaten für Ihr Plugin abzuleiten, einschließlich des Scannernamens, des Ereignisnamens, der Scannergruppen und der Plattformfilterung. Das reduziert die Menge an Standardtexten, die Entwickler sonst schreiben müssten. Durch die Auswahl der richtigen Werte wird sichergestellt, dass Ihr Plugin ordnungsgemäß in das Scanner-Auswahl- und Ausführungsmodell von sbomgen integriert wird.
In den folgenden Abschnitten wird die Verzeichnisstruktur detaillierter untersucht und Hinweise zur semantischen Bedeutung und zu den Konventionen gegeben.
Plattform
Das Plattformverzeichnis steuert, auf welchen Betriebssystemen Ihr Plugin läuft.
| Wert | Wann sollte dies verwendet werden? |
|---|---|
cross-platform |
Das Plugin funktioniert auf jedem Betriebssystem (die meisten Plugins) |
linux |
Linux-spezifische Erkennungslogik |
windows |
Windows-spezifische Erkennungslogik |
macos |
macOS-spezifische Erkennungslogik |
Kategorie
Das Kategorienverzeichnis bestimmt die Standard-Scanner-Gruppen, die Ihrem Plugin zugewiesen sind. Dadurch wird gesteuert, ob es standardmäßig ausgeführt wird oder ob eine ausdrückliche Anmeldung erforderlich ist. Erfahren SieAuswahl des Scanners, wie sich Gruppen auf die Ausführung auswirken.
| Wert | Standardgruppen | Wann sollte dies verwendet werden? |
|---|---|---|
proglang |
programming-language-packages, pkg-scanner |
Programmiersprachenpakete (pip, npm, maven usw.) |
os |
os, pkg-scanner |
Betriebssystem-Paketmanager (dpkg, rpm, apk usw.) |
extra-ecosystems |
extra-ecosystems, pkg-scanner |
Anwendungen und Laufzeiten (Nginx, Curl, Wordpress usw.) |
Wenn Sie einen Kategorienamen verwenden, der keinem der oben genannten Punkte entspricht, wird der Kategoriename selbst als Gruppe verwendet.
Ökosystem
Ein Name für das spezifische Paket-Ökosystem (z. B.python-pip,,python-poetry,debian-dpkg,curl). Namen mit Bindestrich sind eine übliche Konvention, aber keine strikte Anforderung.
Der Scanner-Name und der Collector-Name werden direkt vom Namen des Ökosystem-Verzeichnisses abgeleitet.
Paarung von Ereignisnamen
Discovery- und Collection-Plug-ins im selben Verzeichnispfad werden automatisch gepaart. Beispielsweise verbindet sich ein Discovery-Plug-In at discovery/cross-platform/proglang/python-pip/ automatisch mitcollection/cross-platform/proglang/python-pip/.
Sie können dies überschreiben, indem Sie get_event_name() und subscribe_to_event() in Ihren Plugins definieren.
Discovery-Plugins
Ein Discovery-Plugin benötigt nur die discover() Funktion. Alle anderen Funktionen sind optional — Standardwerte werden aus dem Verzeichnispfad abgeleitet.
Die meisten Discovery-Plugins funktionieren, indem sie Dateien lokalisieren, deren Namen oder Pfade ein bestimmtes Ökosystem identifizieren — zum Beispiel requirements.txt für Python pip, package.json für npm oder Cargo.lock für Rust Cargo. Die sbomgen.find_files_by_* Funktionen führen diesen Abgleich außerhalb der Lua-VM durch, wodurch sie deutlich schneller sind als die Iteration der vollständigen Dateiliste 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()muss eine Lua-Tabelle (ein Array) mit Zeichenketten zurückgeben. Wenn keine Dateien gefunden werden, wird eine leere Tabelle {} zurückgegeben.
Allgemeine Erkennungsmuster
| Ziel | Empfohlene Funktion |
|---|---|
| Ordnen Sie einen oder mehrere exakte Dateinamen zu | sbomgen.find_files_by_name({names}) |
| Ordnen Sie Dateinamen ohne Berücksichtigung der Groß- und Kleinschreibung zu | sbomgen.find_files_by_name_icase({names}) |
Nach Pfadsuffix abgleichen (z. B.) /pom.properties |
sbomgen.find_files_by_suffix({suffixes}) |
| Nach vollständigem Pfadausdruck abgleichen | sbomgen.find_files_by_path_regex({patterns}) |
Übereinstimmung mit Basisnamen im Glob-Stil (z. B.) *.lock |
sbomgen.glob_find_files(pattern) |
Wenn Ihre Logik eine Nachfilterung erfordert — zum Beispiel Dateien behalten, die einem Suffix entsprechen, aber keine Build-Output-Verzeichnisse ausschließen — kombinieren Sie einen Aufruf mit einer Lua-Schleife: 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
Vermeiden Sie sbomgen.get_file_list() die Erkennung, es sei denn, es passt kein anderer Matcher — es kopiert jeden Pfad in die Lua-VM und kann bei großen Artefakten mehrere Sekunden dauern. Einzelheiten finden Sie in derPlugin-API-Referenz.
Erkennung mehrerer Ereignisse
Standardmäßig discover() werden alle von zurückgegebenen Dateien in einem einzigen Ereignis (vonget_event_name()) veröffentlicht. Wenn Ihr Scanner verschiedene Dateien an verschiedene Collectors weiterleiten muss, geben Sie stattdessen eine verschlüsselte Tabelle zurück:
function discover() return { EventNameFoundCurl = sbomgen.find_files_by_name({"curl", "curl.exe"}), EventNameFoundLibcurl = sbomgen.find_files_by_name({"curlver.h"}), } end
Wenn eine Tabelle mit Zeichenkettenschlüsseln discover() zurückgegeben wird, wird jeder Schlüssel als separater Ereignisname behandelt und sein Wert (eine Tabelle mit Dateipfaden) wird für dieses Ereignis veröffentlicht. Sammlungs-Plugins abonnieren bestimmte Ereignisse subscribe_to_event() wie gewohnt.
Dies ist abwärtskompatibel — die Rückgabe einer sequentiellen Tabelle funktioniert {"file1", "file2"} weiterhin im Einzelereignismodus. Die Erkennung erfolgt automatisch: Bei Tabellen mit beliebigen Zeichenkettenschlüsseln handelt es sich um mehrere Ereignisse, bei Tabellen mit nur Integer-Schlüsseln (oder leeren Schlüsseln) handelt es sich um Einzelereignisse.
Bei Verwendung von Mehrfachereignissen get_event_name() wird diese Option nicht für die Veröffentlichung verwendet (die Namen der Ereignisse stammen aus den zurückgegebenen Tabellenschlüsseln). Es wird jedoch immer noch beim Laden des Plugins zur Kollisionserkennung aufgerufen, daher sollte es einen eindeutigen Wert zurückgeben oder weggelassen werden, um die Standardeinstellung zu verwenden.
Optionale Erkennungsfunktionen
All diese haben vernünftige Standardwerte, die sich aus dem Verzeichnispfad ergeben. Definieren Sie sie nur, wenn Sie Folgendes überschreiben müssen:
| Funktion | Standard | Überschreiben wenn... |
|---|---|---|
get_scanner_name() |
{ecosystem}(z. B.python-pip) |
Sie möchten einen benutzerdefinierten Scanner-Namen |
get_scanner_description() |
"Lua discovery plugin: {ecosystem}" |
Sie möchten eine benutzerdefinierte Beschreibung |
get_scanner_groups() |
Abgeleitet aus dem Kategorieverzeichnis | Sie benötigen nicht standardmäßige Gruppen |
get_event_name() |
Abgeleitet vom Verzeichnispfad | Sie benötigen ein benutzerdefiniertes Event-Routing |
get_localhost_scan_paths() |
Keine | Ihr Plugin benötigt bestimmte Pfade, die während der localhost Scans gescannt werden |
Localhost-Scanpfade
Wenn sbomgen einen localhost Scan ausführt, durchsucht es benutzerdefinierte Verzeichnisse sowie alle von Scannern deklarierten Standardpfade. Standardmäßig liefern Lua-Discovery-Plugins keine Pfade, sodass Dateien außerhalb der vom Benutzer angegebenen Verzeichnisse nicht in der Dateiliste erscheinen.
Definiertget_localhost_scan_paths(), dass Verzeichnisse oder Dateipfade zurückgegeben werden, die der Localhost Walker enthalten soll:
function get_localhost_scan_paths() return { "/usr/bin", "/usr/local/bin", } end
Die zurückgegebenen Pfade werden nur bei localhost Scans an die Scanliste des Walkers angehängt — sie haben keine Auswirkung auf containerdirectory, oder archive Scans.
Plattformspezifische Scanpfade
Wenn sich die Dateien, die Ihnen wichtig sind, unter Windows, macOS und Linux an unterschiedlichen Speicherorten befinden, verzweigen Sie sich sbomgen.get_platform() und geben Sie die entsprechenden Pfade für den Host zurück:
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
Verwenden Sie unter Windows, sbomgen.get_system_drive() um den Systemlaufwerksbuchstaben aufzulösen (z. B."C:"), anstatt ihn fest zu codieren. Bei Pfaden, die von Umgebungsvariablen wie LOCALAPPDATA oder abgeleitet sindPROGRAMFILES, iterieren Sie sbomgen.get_env_vars() und suchen Sie den Wert nach Schlüsseln. Einzelheiten finden Sie Plugin-API-Referenz unter.
Plugins für die Sammlung
Ein Sammlungs-Plugin benötigt nur die collect() Funktion. Alle anderen Funktionen sind optional.
collect(file_path)wird einmal pro Datei aufgerufen, die vom gekoppelten Discovery-Plugin entdeckt wird. Das typische Muster ist:
-
Lesen Sie den Inhalt der Datei mit
sbomgen.read_file()(für kleine Dateien, die in den Speicher geladen werden) odersbomgen.open_file()(für große Dateien lesen line-by-line). -
Analysieren Sie den Inhalt — Zeichenkettenabgleich für einfache Manifeste,
sbomgen.json_decode()für JSON,sbomgen.xml_decode()für XML odersbomgen.search_binary()für kompilierte Binärdateien. -
Veröffentlichen Sie jedes entdeckte Paket, indem Sie es
sbomgen.push_package()mit den Metadaten des Pakets aufrufen.
-- 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()gibt keinen Wert zurück. Jeder push_package() Aufruf erfordertname,purl_type, undcomponent_type. Alle unterstützten Felder finden Sie unter. Plugin-API-Referenz
Metadaten an Komponenten anhängen
Sbomgen unterstützt zwei Möglichkeiten, Metadaten an eine Paketkomponente anzuhängen: PURL-Qualifizierer und CyclonedX-Eigenschaften. Sie dienen unterschiedlichen Zwecken, und die Wahl zwischen ihnen hat Auswirkungen darauf, wie Amazon Inspector Sicherheitslücken in der resultierenden SBOM identifiziert.
| Mechanismus | Wo es erscheint | Verwenden Sie für |
|---|---|---|
qualifiers |
Innerhalb der Paket-URL (z. B.pkg:deb/debian/curl@7.88.1?arch=amd64) |
Daten, die Teil der Paketidentität sind |
properties |
Im Array der SBOM components[].properties |
Beschreibende Metadaten, die nichts daran ändern, wie das Paket identifiziert wird |
Empfehlung: Bevorzugen Sie CyclonedX-Eigenschaften (unter Ihrem eigenen Namespace) für benutzerdefinierte Metadaten. Eigenschaften ändern nicht die Identität einer Komponente, sodass sie sich nicht auf die Identifizierung von Sicherheitslücken durch Amazon Inspector auswirken können. Reservieren Sie PURL-Qualifier für Fälle, in denen der PURL-Typ Ihres Ökosystems sie erfordert.
PURL-Qualifikatoren
Einige PURL-Qualifier haben für Amazon Inspector eine semantische Bedeutung und beeinflussen die Identifizierung von Sicherheitslücken. Bei deb Komponenten verwendet Inspector beispielsweise Qualifikatoren wie arch und, distro um den richtigen Schwachstellenfeed auszuwählen, bei generic Komponenten für kompilierte Binärdateien Kennzeichner wie go_toolchain oder rust_toolchain identifizieren die verwendete Toolchain. Das Setzen eines Qualifikators, den Inspector nicht erkennt, oder das Auslassen eines erwarteten Kennzeichners kann dazu führen, dass Sicherheitslücken übersehen oder falsch zugeordnet werden.
Weitere Informationen finden Sie unter Was ist eine Paket-URL? im Amazon Inspector Inspector-Benutzerhandbuch finden Sie Informationen zu den Qualifier-Konventionen, die Inspector pro PURL-Typ erkennt.
Legen Sie die Qualifikatoren über die Tabelle fest aufqualifiers: 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", }, })
Legen Sie Qualifikatoren nur fest, wenn sie den Erwartungen von Inspector für den PURL-Typ entsprechen. Wenn Sie Metadaten aufzeichnen müssen, die nicht Teil der Paketidentität sind, verwenden Sie stattdessen die CyclonedX-Eigenschaften.
CyclonedX-Eigenschaften
CyclonedX-Eigenschaften sind Anmerkungen zu Schlüsselwerten, die im Array der SBOM erscheinen. components[].properties Sie beschreiben eine Komponente, ohne zu beeinflussen, wie sie identifiziert wird, und sind daher die sichere Wahl für Plugin-definierte Metadaten.
Die amazon:inspector:* Namespaces sind Amazon Inspector vorbehalten. Das heißt:
-
amazon:inspector:sbom_generator:*— reserviert für sbomgen und seine eingebauten Scanner. -
amazon:inspector:sbom_scanner:*— reserviert für die Amazon Inspector Scan API.
Plugin-Autoren dürfen keine Schlüssel innerhalb dieser reservierten Namespaces ausgeben. Das Schreiben in sie kann das Verhalten von Inspector beeinträchtigen und kann überschrieben werden. Die vollständige Liste der reservierten Schlüssel finden Sie unter Verwenden von CyclonedX-Namespaces mit Amazon Inspector.
Verwenden Sie Ihren eigenen Namespace (normalerweise Ihre Organisations- oder Plugin-ID), wenn Sie Eigenschaften definieren:
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", }, })
Wichtige Benennungsregeln
Eigenschaftsschlüssel werden von sbomgen wie folgt verarbeitet:
-
Ein Schlüssel, der einen Doppelpunkt enthält, wird in der SBOM wörtlich verwendet. Fügen Sie immer mindestens einen Doppelpunkt in Ihre Schlüssel ein, damit Sie den Namespace kontrollieren können.
-
Einem Schlüssel, der keinen Doppelpunkt enthält, wird automatisch ein Präfix vorangestellt, sodass er im reservierten Inspector-Namespace platziert wird.
amazon:inspector:sbom_generator:Vermeiden Sie diese Form für benutzerdefinierte Eigenschaften.
properties = { ["acme:my_plugin:detected_via"] = "lockfile", -- used as-is (recommended) detected_via = "lockfile", -- becomes "amazon:inspector:sbom_generator:detected_via" (avoid) }
Die sbomgen.properties.* Konstanten existieren, sodass offizielle Scanner konsistente Schlüssel innerhalb des reservierten Namespaces ausgeben. Sie sind keine Erweiterungspunkte für benutzerdefinierte Plugins — verwenden Sie stattdessen Ihren eigenen Namespace.
Eigenschaften und Qualifizierer für untergeordnete Komponenten
Verschachtelt children sind unabhängige Komponenten. Jedes untergeordnete Element hat seine eigenen properties qualifiers Tabellen. Metadaten, die für das übergeordnete Element festgelegt sind, werden nicht auf Kinder übertragen. Legen Sie Werte explizit für jedes Kind fest, das sie benötigt.
Optionale Sammlungsfunktionen
| Funktion | Standard | Überschreiben, wenn... |
|---|---|---|
get_collector_name() |
{ecosystem}(z. B.python-pip) |
Sie möchten einen benutzerdefinierten Collector-Namen |
get_collector_description() |
leere Zeichenfolge | Sie möchten eine Beschreibung |
subscribe_to_event() |
Abgeleitet vom Verzeichnispfad | Sie benötigen ein benutzerdefiniertes Event-Routing |
Deine Plugins ausführen
Damit Plugins Paket-Metadaten erzeugen können, muss sbomgen ein Artefakt zum Scannen erhalten, das die Dateien enthält, auf die Ihr Plugin abzielt (z. B. ein Verzeichnis mit requirements.txtpackage.json, oder gleichwertige Paketmanifestdateien).
Grundlegende Verwendung
inspector-sbomgen <artifact type> <arguments> --plugin-dir /path/to/plugins
Beispiel:
inspector-sbomgen directory --path /target -o /tmp/sbom.json --plugin-dir /path/to/plugins
Bei deaktivierten nativen Scannern (nur LUA-Modus)
inspector-sbomgen directory --path /target --plugin-dir /path/to/plugins --disable-native-scanners -o sbom.json
Mit ausführlicher Protokollierung
inspector-sbomgen directory --path /target --plugin-dir /path/to/plugins --verbose -o sbom.json
Verfügbare Scanner auflisten
Dient list-scanners zum Anzeigen aller für sbomgen verfügbaren Scanner. Dazu gehören die integrierten nativen Scanner, alle offiziellen Lua-Plugins, die im Lieferumfang von sbomgen enthalten sind, und alle benutzerdefinierten Lua-Plugins, die Sie bereitgestellt haben über: --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 │ └─────────────────────┴────────┴───────────────────────────────┴─────────────────────────────┘
Die Spalte SOURCE zeigt, woher die einzelnen Scanner stammen:
| Quelle | Bedeutung |
|---|---|
native |
Integrierter Scanner, der im Lieferumfang von sbomgen enthalten ist |
official |
Mit sbomgen gebündelte Lua-Plugins |
custom |
Vom Benutzer bereitgestelltes Lua-Plugin, geladen über --plugin-dir |
Running list-scanners without beinhaltet --plugin-dir immer noch native sowohl official Scanner als auch Scanner — diese sind immer verfügbar. Die --plugin-dir Flagge fügt Ihre custom Scanner zur Liste hinzu.
Um nur Lua-Scanner ohne native Scanner aufzulisten:
inspector-sbomgen list-scanners --plugin-dir /path/to/plugins --disable-native-scanners
Auswahl des Scanners
Lua-Discovery-Plugins verwenden dasselbe Scanner-Auswahlmodell wie die integrierten nativen Scanner. Standardmäßig führt sbomgen alle Scanner aus, deren Gruppen den Standardscannergruppen für den Artefakttyp entsprechen. Sie können dies mit drei Flags überschreiben:
Nur bestimmte Scanner ausführen
Wird verwendet--scanners, um nur die genannten Scanner auszuführen. Alle anderen Scanner sind ausgeschlossen:
inspector-sbomgen directory --path /target \ --plugin-dir /path/to/plugins \ --scanners python-requirements \ -o sbom.json
Dadurch wird nur der python-requirements Scanner ausgeführt. Sie können mehrere durch Kommas getrennte Scannernamen oder einen Scanner-Gruppennamen (z. B.programming-language-packages) übergeben, um jeden Scanner zu aktivieren, der zu dieser Gruppe gehört.
Schließen Sie bestimmte Scanner aus
Wird verwendet--skip-scanners, um benannte Scanner auszuschließen, während alles andere ausgeführt wird:
inspector-sbomgen directory --path /target \ --plugin-dir /path/to/plugins \ --skip-scanners python-poetry \ -o sbom.json
Damit werden alle Standardscanner ausgeführt, außerpython-poetry. Ebenso akzeptiert dieses Flag auch Gruppennamen, sodass durch das Übergeben alle Scanner in dieser Gruppe --skip-scanners programming-language-packages deaktiviert werden. --scanners
Anmerkung
--scannersund schließen --skip-scanners sich gegenseitig aus. Wenn beide übergeben werden, tritt ein Fehler auf.
Fügen Sie Scanner aus nicht standardmäßigen Gruppen hinzu
Das Standard-Scanner-Set hängt vom Artefakttyp ab, der gescannt wird (siehe die Matrix Wie wirken sich Gruppen auf die Auswahl aus unten). Ein Scanner, dessen Gruppen nicht Teil des Standardsatzes für den Artefakttyp sind, kann nur ausgeführt werden, wenn Sie ihn aktivieren. Verwenden Sie diese --additional-scanners Option, um Scanner an den Standardsatz anzuhängen, ohne ihn zu ersetzen:
inspector-sbomgen directory --path /target \ --plugin-dir /path/to/plugins \ --additional-scanners my-extra-scanner \ -o sbom.json
Dadurch werden alle Standardscanner für den Artefakttyp ausgeführt, plus. my-extra-scanner Das Flag akzeptiert eine kommagetrennte Liste von Scannernamen oder Gruppennamen und stapelt sich mit dem Standardsatz, anstatt ihn zu ersetzen. Wird verwendetlist-scanners, um zu überprüfen, zu welchen Gruppen ein Scanner gehört.
Wie wirken sich Gruppen auf die Auswahl aus
Die get_scanner_groups() Funktion in Ihrem Discovery-Plugin bestimmt, zu welchen Gruppen der Scanner gehört. Ob ein Scanner standardmäßig ausgeführt wird, hängt sowohl von seinen Gruppen als auch vom Artefakttyp ab, der gescannt wird. Die folgende Matrix zeigt, welche Gruppen im Standard-Scanner-Set für jeden Artefakttyp enthalten sind:
| Group (Gruppieren) | directory / archive |
container |
localhost |
volume |
binary |
|---|---|---|---|---|---|
os |
— | ✓ | ✓ | ✓ | — |
programming-language-packages |
✓ | ✓ | ✓ | ✓ | — |
binary |
✓ | ✓ | — | — | ✓ |
extra-ecosystems |
— | ✓ | ✓ | ✓ | — |
dockerfile |
✓ | ✓ | — | — | — |
custom |
✓ | ✓ | ✓ | ✓ | ✓ |
certificate |
— | — | — | — | — |
machine-learning |
— | — | — | — | — |
pkg-scanner |
— | — | — | — | — |
Ein ✓ bedeutet, dass jeder Scanner in dieser Gruppe standardmäßig für diesen Artefakttyp ausgeführt wird. A — bedeutet, dass die Gruppe nicht in der Standardeinstellung enthalten ist, sodass ihre Scanner nur ausgeführt werden, wenn sie explizit über --scanners oder --additional-scanners ausgewählt wurden.
Bemerkenswerte Details:
-
customist immer in der Standardeinstellung — benutzerdefinierte Plugins, die über geladen werden, erhalten--plugin-dirautomatisch diecustomGruppe, sodass sie standardmäßig unabhängig vom Artefakttyp ausgeführt werden. -
extra-ecosystemsist Standard fürcontainerlocalhost, undvolumescannt, aber nicht fürdirectory,archive, oderbinaryscannt. Für diese Typen müssen Sie die Daten--additional-scanners(nach Namen oderextra-ecosystemsGruppe) angeben, um sie einzubeziehen. -
pkg-scannerist informativ — es kennzeichnet einen Scanner als Paketsammler für die Anzeigelist-scanners, veranlasst aber nicht automatisch, dass der Scanner ausgeführt wird. Kombinieren Sie ihn mit einer Ausführungsgruppe (z. B.programming-language-packages) inget_scanner_groups().
Beispielsweise {sbomgen.groups.EXTRA_ECOSYSTEMS, sbomgen.groups.PACKAGE_COLLECTOR} wird ein Plugin, das zurückkehrt, standardmäßig bei Container-, Localhost- und Volume-Scans ausgeführt, erfordert aber --additional-scanners (oder--scanners) bei Verzeichnis-, Archiv- und Binärscans.
Kollisionsregeln für Plugins
Sbomgen erzwingt eindeutige Metadaten für alle geladenen Plugins, um unbemerktes Überschreiben zu verhindern und die Integrität der SBOMs zu gewährleisten. Wenn eine Kollision erkannt wird, wird das spätere Plugin übersprungen und eine Warnung wird protokolliert.
Was wird geprüft
| Metadaten | Scope | Bei Kollision |
|---|---|---|
Name des Erkennungsereignisses (get_event_name) |
Alle Discovery-Plugins | Zweites Plugin wurde übersprungen |
Name des Scanners () get_scanner_name |
Alle Discovery-Plugins | Zweites Plugin wurde übersprungen |
Name des Sammlers () get_collector_name |
Alle Sammlungs-Plugins | Zweites Plugin wurde übersprungen |
Was ist erlaubt
Mehrere Sammlungs-Plugins können dieselbe Veranstaltung abonnieren übersubscribe_to_event(). Dies ist das beabsichtigte Fan-Out-Muster — ein Discovery-Plugin kann mehrere Sammler versorgen, die jeweils unterschiedliche Dinge tun (z. B. extrahiert einer Pakete, ein anderer entdeckt Geheimnisse).
Kollisionen vermeiden
Wenn zwei Plugins denselben Scanner-Namen, Ereignisnamen oder Collector-Namen verwenden, wird das zweite geladene Plug-in übersprungen. Um Kollisionen zu lösen, benennen Sie die widersprüchlichen Metadaten um, indem Sie die entsprechende Override-Funktion in Ihrem Plugin definieren (get_scanner_name()get_event_name(), oder). get_collector_name()
Beispiel einer Kollisionswarnung
[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.
Die Warnung sagt dir, welches Plugin übersprungen wurde, was kollidiert ist, welches Plugin diesen Namen bereits besitzt und welche Funktion geändert werden muss.
Debuggen
Protokollierung in der Konsole
Plugins können mithilfe der folgenden Funktionen Nachrichten an die Konsolenausgabe von sbomgen ausgeben:
| Funktion | Stufe | Standardmäßig sichtbar? |
|---|---|---|
sbomgen.log_debug(message) |
DEBUG | Nein — erfordert --verbose |
sbomgen.log_info(message) |
INFO | Ja |
sbomgen.log_warn(message) |
WARN | Ja |
sbomgen.log_error(message) |
ERROR | Ja |
Jeder Protokollausgabe eines Plugins wird automatisch die Quelle und der Pfad des Plugins vorangestellt (z. B.[custom:python-pip]), sodass Nachrichten von verschiedenen Plugins leicht zu unterscheiden sind. log_infolog_warn, und druckt log_error immer; druckt log_debug nur, wenn sbomgen mit aufgerufen wird. --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
Breakpoints
Verwenden Sie diese sbomgen.breakpoint() Option, um die Ausführung des Plugins anzuhalten und zu blockieren, bis Sie die Eingabetaste drücken. Dies funktioniert wie ein einfacher Debugger — kombinieren Sie ihn mit Protokollanweisungen, um den Status an bestimmten Punkten zu überprüfen.
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
Die Breakpoint-Nachricht wird auf stderr ausgegeben. Die Ausführung wird angehalten, bis Sie die EINGABETASTE drücken, sodass Sie Zeit haben, die Protokollausgabe zu überprüfen.
Häufige Probleme
| Symptom | Ursache | Korrigieren |
|---|---|---|
| Das Plugin wurde nicht geladen | init.lua fehlt |
Stellen Sie sicher, dass der Einstiegspunkt in der richtigen Verzeichnistiefe existiert |
| „fehlende erforderliche Funktion“ | Tippfehler im Funktionsnamen | Prüfen Sieget_scanner_name, obget_scanner_description,,get_scanner_groups,discover,get_event_name,,get_localhost_scan_paths,get_collector_name,collect, definiert subscribe_to_event sind |
| Das Sammlungs-Plugin wurde nie aufgerufen | Der Name des Ereignisses stimmt nicht überein | Überprüfen Sie die gleiche get_event_name() Zeichenfolge und subscribe_to_event() geben Sie sie zurück |
| Keine Pakete in SBOM | push_packagenicht aufgerufen oder Pflichtfelder fehlen |
Stellen Sie sicher namepurl_type, dass, und bei jedem push_package Anruf (auch bei Kindern) angegeben component_type sind. Verwenden Sie sbomgen.component_types.* Konstanten. |
| Laufzeitfehler im Plugin | Lua-Fehler bei der Ausführung | Suchen Sie in der Ausgabe von sbomgen nach Warnmeldungen mit den Fehlerdetails |
| „SKIPPED: Der Name des Erkennungsereignisses... ist bereits registriert“ | Ein anderes Plugin verwendet denselben Eventnamen | Benennen get_event_name() Sie es in einen eindeutigen Wert um |
| „SKIPPED: Scannername... ist bereits registriert“ | Ein anderes Plugin verwendet denselben Scanner-Namen | Benennen get_scanner_name() Sie es in einen eindeutigen Wert um |
| „SKIPPED: Der Name des Kollektors... ist bereits registriert“ | Ein anderes Plugin verwendet denselben Collector-Namen | Benennen get_collector_name() Sie es in einen eindeutigen Wert um |
API-Referenz
Der vollständige Funktionskatalog ist in einem Begleitdokument enthalten:
Die API-Referenz deckt alle sbomgen.* Funktionen (Datei-I/O, binäre Hilfsprogramme, Paketausgabe, Regex, strukturiertes Parsing, Windows-Registrierung, Protokollierung, Debugging), die in Testdateien verfügbare testing.* API, alle integrierten Konstanten (,, properties groupscomponent_types,platform) und die globalen Plugin-Lebenszykluswerte ab.
Fehlerbehandlung
API-Funktionen, die fehlschlagen können, geben zwei Werte zurück:. value, err Bei Erfolg err istnil. Bei einem Fehler ist nil und err ist der erste Wert eine Fehlerzeichenfolge.
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
Wenn ein Plugin einen unbehandelten Lua-Fehler auslöst, protokolliert sbomgen eine Warnung und fährt mit der nächsten Datei oder dem nächsten Plugin fort. Andere Plugins sind nicht betroffen.
Sandbox-Einschränkungen
Plugins werden in einer Sandbox-Lua-VM mit eingeschränktem Zugriff auf die Standardbibliothek ausgeführt:
| Bibliothek | Verfügbar | Hinweise |
|---|---|---|
base |
✓ | dofile,, werden entfernt loadfile loadstring |
string |
✓ | Vollständige Bearbeitung von Zeichenketten |
table |
✓ | Vollständige Tabellenmanipulation |
math |
✓ | Vollständige Mathe-Bibliothek |
package |
✓ | require()auf das Plugin-Verzeichnis beschränkt |
io |
✗ | Verwenden Sie stattdessen sbomgen.* I/O Funktionen |
os |
✗ | Aus Sicherheitsgründen gesperrt |
debug |
✗ | Blockiert, um VM-Introspektion zu verhindern |
coroutine |
✗ | Nicht geladen |
Direkter Dateisystemzugriff über io.open oder os.execute ist nicht verfügbar. Alle Dateioperationen müssen über die sbomgen API abgewickelt werden. Dadurch wird ein konsistentes Verhalten aller Artefakttypen gewährleistet und Plugins daran gehindert, auf Dateien außerhalb des Artefakts zuzugreifen.
require()kann Module nur aus dem eigenen Verzeichnisbaum des Plugins laden. Das Durchqueren von übergeordneten Verzeichnissen wie z. B. ist blockiert. require("../shared")
Code zwischen Plugins teilen
Sie können require() es verwenden, um Hilfsmodule aus dem Verzeichnis Ihres Plugins zu laden:
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
Unterverzeichnisse mit init.lua werden ebenfalls unterstützt:
my-ecosystem/ ├── init.lua └── parsers/ └── init.lua
local parsers = require("parsers")
require()ist auf das Verzeichnis Ihres Plugins beschränkt. Sie können keine Module von anderen Plugins oder Systempfaden laden. Lua-Bibliotheken von Drittanbietern (z. B. von LuaRocks) werden nicht unterstützt — nur lokale Hilfsmodule innerhalb des Plugin-Verzeichnisses können geladen werden.