View a markdown version of this page

Leitfaden für Plugin-Entwickler - Amazon Inspector

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 TODO Markierungen durch deine tatsächlichen Werte

  • Aktualisieren Sie das Dateimuster sodiscover(), dass es Ihren Zieldateien entspricht

  • Implementieren Sie die Parsing-Logik in jedem collect() Paket und rufen Sie sbomgen.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

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) oder sbomgen.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 oder sbomgen.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-dir automatisch die custom Gruppe, sodass sie standardmäßig unabhängig vom Artefakttyp ausgeführt werden.

  • extra-ecosystemsist Standard für containerlocalhost, und volume scannt, aber nicht fürdirectory,archive, oder binary scannt. Für diese Typen müssen Sie die Daten --additional-scanners (nach Namen oder extra-ecosystems Gruppe) 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:

Plugin-API-Referenz

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.