

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# プラグイン開発者ガイド
<a name="sbomgen-plugin-developer-guide"></a>

 このガイドでは、カスタム Lua プラグインを使用して Amazon Inspector SBOM Generator (inspector-sbomgen) を拡張する方法について説明します。プラグインを使用すると、sbomgen のソースコードを変更したり、再コンパイルしたりすることなく、新しいパッケージエコシステムのサポートを追加できます。

 関数カタログの詳細については、「」を参照してください[プラグイン API リファレンス](sbomgen-plugin-api-reference.md)。テストの記述に関するガイダンスについては、「」を参照してください[プラグインテストガイド](sbomgen-plugin-testing-guide.md)。

## 概要
<a name="sbomgen-plugin-developer-guide-overview"></a>

 Sbomgen プラグインは Lua で記述され、2 ステップのパイプラインに従います。
+ **検出** — アーティファクトのファイルリストをスキャンし、エコシステムに関連するファイルをレポートします。
+ **コレクション** — 検出された各ファイルを解析し、パッケージの検出結果を SBOM にプッシュします。

### プラグインイベントモデル
<a name="sbomgen-plugin-developer-guide-plugin-event-model"></a>

 検出プラグインには、パッケージメタデータを含むファイルがインベントリのアーティファクトで検出されたことをコレクションプラグインに伝える方法が必要です。このデータ共有を容易にするために、検出プラグインは**イベント名**を定義し、ファイルパスのリストを返します。コレクションプラグインは、そのイベントを**サブスクライブ**し、一致する各ファイルパスを受け取ります。この解析からファイル検出を分離 — 1 つの検出プラグインで複数のコレクターをフィードできます (ファンアウトパターン）。ただし、各検出プラグインには一意のイベント名が必要であり、各コレクションプラグインには一意のコレクター名が必要です。詳細については、「[プラグイン衝突ルール](#sbomgen-plugin-developer-guide-plugin-collision-rules)」を参照してください。

 開発者はこれを**オブザーバー**設計パターンとして認識する場合があります。

 この設計により、単一の検出プラグインが複数の独立した分析をパフォーマンスの高い方法でトリガーできます。たとえば、1 つの検出プラグインがアーティファクト`requirements.txt`内のすべての を見つけ、フィードできます。
+ 各行を SBOM 検出結果 () に解析する**パッケージコレクター**`name==version`。
+ API キーまたはトークンを含む行を誤ってバージョンとしてピン留めする**シークレットコレクター**。
+ ピン留めされていないまたはワイルドカードバージョンの指定子をレポートする**ポリシーコレクター**。

 各コレクターは、アーティファクトのファイルシステムを再歩行することなく、同じファイルリストに対して個別に実行されます。これにより、プラグインの作成者は、対応する検出プラグインを変更することなく、既存のイベントをサブスクライブする新しいコレクションプラグインを追加することもできます。

## クイックスタート: 新しいプラグインの作成
<a name="sbomgen-plugin-developer-guide-quick-start-creating-new-plugins"></a>

 新しいプラグインを作成する最も簡単な方法は、組み込みの足場コマンドを使用することです。

```
inspector-sbomgen plugin new
```

 コマンドは、プラグイン名とプロジェクトディレクトリの入力を求めます。Enter キーを押すと、括弧で囲まれたデフォルトが受け入れられます。

```
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]:
```

 引数を直接渡すこともできます。

```
inspector-sbomgen plugin new --name cmake --path /tmp/custom-plugins
```

### 実例から始める
<a name="sbomgen-plugin-developer-guide-starting-with-a-working-example"></a>

 独自のロジックを記述する前にプラグインを試す場合は、 `--with-example`フラグを使用して新しいプラグインを作成します。

```
inspector-sbomgen plugin new --with-example
```

 これにより、サンプルロックファイルパーサー、テストデータ、および合格テストを含む完全に機能するプラグインプロジェクトが生成されます。サンプルプラグインは、`example.lock`ファイルを検出し、`name==version`エントリを解析して、パッケージを SBOM にプッシュします。テストをすぐに実行してプラグインシステムが動作していることを確認し、実際のエコシステムをターゲットにするようにコードを変更することができます。

 すべてのオプションのオーバーライド関数 (`get_scanner_name`、`get_event_name`、、`get_scanner_groups`マルチイベント検出など) を含む高度なスキャフォールドの場合、 `--with-overrides`フラグを使用します (詳細については後で説明します）。

```
inspector-sbomgen plugin new --with-overrides
```

### プラグインの完了
<a name="sbomgen-plugin-developer-guide-completing-your-plugin"></a>

 スキャフォールド後、生成されたプラグインファイルには、エコシステム固有のロジックを追加する場所を示す`TODO`マーカーが含まれています。これらのマーカーを使用して、足場を動作するプラグインに変換します。
+ すべての`TODO`マーカーを実際の値に置き換える
+ ターゲットファイルと一致する`discover()`ように のファイルパターンを更新する
+ に解析ロジックを実装`collect()`し、パッケージごとに `sbomgen.push_package()`を呼び出す

### プラグインをテストする
<a name="sbomgen-plugin-developer-guide-test-your-plugin"></a>

 プラグインをテストする方法は 2 つあります。

 **1. 組み込みテストハーネス** — 開発中にプラグインロジックを検証`inspector-sbomgen plugin test`するために使用します。これにより、実際のアーティファクトをスキャンせずに`init_test.lua`テストファイルが実行されます。

```
inspector-sbomgen plugin test --path ./my-plugins
```

 テストファイルの書き込みと `testing.*` API [プラグインテストガイド](sbomgen-plugin-testing-guide.md) の使用の詳細については、「」を参照してください。

 **2。End-to-endスキャン** — 標準の sbomgen コマンドを使用してプラグインを呼び出し、実際のアーティファクトに対して機能することを確認します。このアプローチでは、プラグインがターゲットとするファイル ( `requirements.txt`または同等のディレクトリなど) を含むアーティファクトと、プラグインディレクトリへのパスの両方を指定する必要があります。

```
inspector-sbomgen directory \
    --path /path/to/test/dir \
    --plugin-dir ./my-plugins \
    --disable-native-scanners \
    -o sbom.json
```

 `--disable-native-scanners` フラグにより、Lua プラグインのみが実行されるため、組み込み (ネイティブ) スキャナーからの出力なしで簡単にテストできます。

## IDE セットアップ
<a name="sbomgen-plugin-developer-guide-ide-setup"></a>

 Sbomgen は、VS Code の `sbomgen.*` API 全体のコード補完、型チェック、インラインドキュメントを提供します。

### Lua Language Server を使用した VS コード
<a name="sbomgen-plugin-developer-guide-vs-code-with-lua-language-server"></a>
+ Lua 拡張機能のインストール: [sumneko.lua](https://marketplace.visualstudio.com/items?itemName=sumneko.lua)
+ プラグインプロジェクトで任意の`.lua`ファイルを開く

 これで完了です。`plugin new` コマンドは、Lua Language Server によって自動的に検出`library/sbomgen.lua`される `.vscode/settings.json`と を生成します。すぐに以下が取得されます。
+ すべての`sbomgen.*`関数のコード補完
+ タイプのパラメータヒント
+ ホバードキュメント
+ タイプチェック

## プラグインディレクトリ構造
<a name="sbomgen-plugin-developer-guide-plugin-directory-structure"></a>

 Sbomgen 検出プラグインとコレクションプラグインは、次のディレクトリ構造に従う必要があります。

```
{plugin-dir}/
├── discovery/
│   └── {platform}/
│       └── {category}/
│           └── {ecosystem}/
│               └── init.lua          # REQUIRED entrypoint
└── collection/
    └── {platform}/
        └── {category}/
            └── {ecosystem}/
                └── init.lua          # REQUIRED entrypoint
```

 これらのディレクトリ名には意味があります。sbomgen はそれらを使用して、スキャナー名、イベント名、スキャナーグループ、プラットフォームフィルタリングなど、プラグインのデフォルトメタデータを取得します。これにより、開発者が書き込む必要があるボイラープレートの量が減少します。正しい値を選択すると、プラグインが sbomgen のスキャナー選択および実行モデルと適切に統合されます。

 以下のセクションでは、セマンティックの意味と規則に関するガイダンスを提供しながら、ディレクトリ構造について詳しく説明します。

### プラットフォーム
<a name="sbomgen-plugin-developer-guide-platform"></a>

 プラットフォームディレクトリは、プラグインを実行するオペレーティングシステムを制御します。


| **値** | **どのようなときに使うか** | 
| --- | --- | 
| cross-platform | プラグインは任意の OS (ほとんどのプラグイン) で動作します。 | 
| linux | Linux 固有の検出ロジック | 
| windows | Windows 固有の検出ロジック | 
| macos | macOS 固有の検出ロジック | 

### Category
<a name="sbomgen-plugin-developer-guide-category"></a>

 カテゴリディレクトリは、プラグインに割り当てられたデフォルトのスキャナーグループを決定します。これにより、プラグインがデフォルトで実行されるか、明示的なオプトインを必要とするかが制御されます。グループが実行に与える影響[スキャナーの選択](#sbomgen-plugin-developer-guide-scanner-selection)については、「」を参照してください。


| **値** | **デフォルトグループ** | **どのようなときに使うか** | 
| --- | --- | --- | 
| proglang | programming-language-packages, pkg-scanner | プログラミング言語パッケージ (pip、npm、maven など) | 
| os | os, pkg-scanner | OS パッケージマネージャー (dpkg、rpm、apk など) | 
| extra-ecosystems | extra-ecosystems, pkg-scanner | アプリケーションとランタイム (nginx、curl、wordpress など) | 

 上記のいずれとも一致しないカテゴリ名を使用する場合、カテゴリ名自体がグループとして使用されます。

### エコシステム
<a name="sbomgen-plugin-developer-guide-ecosystem"></a>

 特定のパッケージエコシステムの名前 (例: 、`python-pip`、`python-poetry``debian-dpkg`、`curl`)。ハイフン名は一般的な規則ですが、厳密な要件ではありません。

 スキャナー名とコレクター名は、エコシステムディレクトリ名から直接取得されます。

### イベント名のペアリング
<a name="sbomgen-plugin-developer-guide-event-name-pairing"></a>

 同じディレクトリパスにある検出プラグインとコレクションプラグインは自動的にペアリングされます。たとえば、 の検出プラグインは、 と`discovery/cross-platform/proglang/python-pip/`自動的にペアになります`collection/cross-platform/proglang/python-pip/`。

 これを上書きするには、プラグイン`subscribe_to_event()`で `get_event_name()`と を定義します。

## 検出プラグイン
<a name="sbomgen-plugin-developer-guide-discovery-plugins"></a>

 検出プラグインには `discover()`関数のみが必要です。他のすべての関数はオプションです。デフォルトはディレクトリパスから算出されます。

 ほとんどの検出プラグインは、Python `requirements.txt`pip、`package.json`npm、Rust 貨物など、名前またはパスが特定のエコシステムを識別するファイルを見つけることによって機能`Cargo.lock`します。`sbomgen.find_files_by_*` 関数は Lua VM の外部でこのマッチングを実行するため、Lua で完全なファイルリストを繰り返すよりも大幅に高速になります。

```
-- REQUIRED: Scans the artifact and returns a table of file paths.
function discover()
    return sbomgen.find_files_by_name({"requirements.txt"})
end
```

 `discover()` は、文字列の Lua テーブル (配列) を返す必要があります。ファイルが見つからない場合は、空のテーブル を返します`{}`。

### 一般的な検出パターン
<a name="sbomgen-plugin-developer-guide-common-discovery-patterns"></a>


| **目標** | **推奨関数** | 
| --- | --- | 
| 1 つ以上の正確なファイル名と一致する | sbomgen.find\_files\_by\_name({names}) | 
| 大文字と小文字を区別せずにファイル名を一致させる | sbomgen.find\_files\_by\_name\_icase({names}) | 
| パスサフィックスで一致 (例: /pom.properties) | sbomgen.find\_files\_by\_suffix({suffixes}) | 
| フルパス正規表現で一致 | sbomgen.find\_files\_by\_path\_regex({patterns}) | 
| Glob スタイルのベースネーム一致 (例: \*.lock) | sbomgen.glob\_find\_files(pattern) | 

 ロジックでサフィックスと一致するファイルを保持し、ビルド出力ディレクトリを除外するなど、ポストフィルタリングが必要な場合は、`find_files_by_*`呼び出しを Lua ループと組み合わせます。

```
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
```

 他のマッチャーが適合しない限り、検出`sbomgen.get_file_list()`は避けてください。Lua VM へのすべてのパスをコピーし、大きなアーティファクトで数秒かかることがあります。詳細については、[プラグイン API リファレンス](sbomgen-plugin-api-reference.md)「」を参照してください。

### マルチイベント検出
<a name="sbomgen-plugin-developer-guide-multi-event-discovery"></a>

 デフォルトでは、 によって返されるすべてのファイルは 1 つのイベント ( から) に発行`discover()`されます`get_event_name()`。スキャナーが異なるファイルを異なるコレクターにルーティングする必要がある場合は、代わりにキー付きテーブルを返します。

```
function discover()
    return {
        EventNameFoundCurl = sbomgen.find_files_by_name({"curl", "curl.exe"}),
        EventNameFoundLibcurl = sbomgen.find_files_by_name({"curlver.h"}),
    }
end
```

 が文字列キーを含むテーブルを`discover()`返すと、各キーは個別のイベント名として扱われ、その値 (ファイルパスのテーブル) がそのイベントに発行されます。コレクションプラグインは、通常`subscribe_to_event()`どおり を介して特定のイベントをサブスクライブします。

 これは下位互換性があります。シーケンシャルテーブルを返すことは、`{"file1", "file2"}`引き続き単一イベントモードとして機能します。検出は自動です。文字列キーを持つテーブルはマルチイベントで、整数キー (または空) のみを持つテーブルは単一イベントです。

 マルチイベントを使用する場合、 `get_event_name()`は発行には使用されません (イベント名は返されたテーブルキーから取得されます）。ただし、衝突検出のためにプラグインのロード中に呼び出されるため、一意の値を返すか、デフォルトを使用するには省略する必要があります。

### オプションの検出関数
<a name="sbomgen-plugin-developer-guide-optional-discovery-functions"></a>

 これらすべてには、ディレクトリパスから派生した正常なデフォルトがあります。上書きする必要がある場合にのみ定義します。


| **関数** | **デフォルト** | **次の場合に上書きします。** | 
| --- | --- | --- | 
| get\_scanner\_name() | {ecosystem} (例: python-pip) | カスタムスキャナー名が必要 | 
| get\_scanner\_description() | "Lua discovery plugin: {ecosystem}" | カスタム説明が必要 | 
| get\_scanner\_groups() | カテゴリディレクトリから派生 | 非標準グループが必要です | 
| get\_event\_name() | ディレクトリパスから派生 | カスタムイベントルーティングが必要です | 
| get\_localhost\_scan\_paths() | なし | プラグインには、スキャン中にlocalhostスキャンされた特定のパスが必要です | 

### Localhost スキャンパス
<a name="sbomgen-plugin-developer-guide-localhost-scan-paths"></a>

 sbomgen は`localhost`スキャンを実行すると、ユーザー指定のディレクトリとスキャナーによって宣言されたデフォルトパスをウォークします。デフォルトでは、Lua 検出プラグインはパスを提供しないため、ユーザー指定のディレクトリ外のファイルはファイルリストに表示されません。

 localhost walker に含めるディレクトリまたはファイルパスを返`get_localhost_scan_paths()`すように を定義します。

```
function get_localhost_scan_paths()
    return {
        "/usr/bin",
        "/usr/local/bin",
    }
end
```

 返されたパスは、`localhost`スキャン中にのみウォーカーのスキャンリストに追加されます。`container`、`directory`、または `archive`スキャンには影響しません。

### プラットフォーム固有のスキャンパス
<a name="sbomgen-plugin-developer-guide-platform-specific-scan-paths"></a>

 Windows、macOS、Linux のさまざまな場所にファイルが存在する場合は、 でブランチ`sbomgen.get_platform()`し、ホストに適切なパスを返します。

```
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
```

 Windows `sbomgen.get_system_drive()`では、 を使用して、ハードコーディングではなくシステムドライブ文字 ( など`"C:"`) を解決します。`LOCALAPPDATA` や などの環境変数から派生したパスの場合`PROGRAMFILES`、値を反復処理`sbomgen.get_env_vars()`してキーで検索します。詳細については、[プラグイン API リファレンス](sbomgen-plugin-api-reference.md)「」を参照してください。

## コレクションプラグイン
<a name="sbomgen-plugin-developer-guide-collection-plugins"></a>

 コレクションプラグインには `collect()`関数のみが必要です。他のすべての関数はオプションです。

 `collect(file_path)` は、ペアになった検出プラグインによって検出されたファイルごとに 1 回呼び出されます。一般的なパターンは次のとおりです。
+ **(**メモリにロードされた小さなファイル`sbomgen.read_file()`の場合) または `sbomgen.open_file()` (line-by-lineファイルの場合) を使用してファイルの内容を読み込みます。
+ 内容を**解析**する — `sbomgen.json_decode()` 単純なマニフェスト、JSON、`sbomgen.xml_decode()`XML、またはコンパイルされたバイナリ`sbomgen.search_binary()`の文字列マッチング。
+ パッケージのメタデータ`sbomgen.push_package()`を使用して ****を呼び出して、検出された各パッケージを発行します。

```
-- 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()` は値を返しません。すべての`push_package()`呼び出しには、`name`、`purl_type`、および が必要です`component_type`。サポートされているすべてのフィールド[プラグイン API リファレンス](sbomgen-plugin-api-reference.md)については、「」を参照してください。

### コンポーネントへのメタデータのアタッチ
<a name="sbomgen-plugin-developer-guide-attaching-metadata-to-components"></a>

 Sbomgen では、**PURL 修飾子**と **CycloneDX プロパティ**の 2 つの方法でメタデータをパッケージコンポーネントにアタッチできます。これらはさまざまな目的を果たし、それらの選択は、Amazon Inspector が結果の SBOM の脆弱性を特定する方法に影響します。


| **メカニズム** | **表示される場所** | **に を使用する** | 
| --- | --- | --- | 
| qualifiers | パッケージ URL 内 (例: pkg:deb/debian/curl@7.88.1?arch=amd64) | パッケージの ID の一部であるデータ | 
| properties | SBOM の components[].properties配列 | パッケージの識別方法を変更しない説明メタデータ | 

 **推奨事項: カスタムメタデータには CycloneDX プロパティ (独自の名前空間の下) を優先します。**プロパティはコンポーネントの ID を変更しないため、Amazon Inspector の脆弱性識別には影響しません。エコシステムの PURL タイプに必要な場合は、PURL 修飾子を予約します。

#### PURL 修飾子
<a name="sbomgen-plugin-developer-guide-purl-qualifiers"></a>

 一部の PURL 修飾子は Amazon Inspector にとって意味的意味を持ち、脆弱性の特定に影響を与えます。たとえば、`deb`コンポーネントでは Inspector は `arch`や などの修飾子を使用して正しい脆弱性フィード`distro`を選択します。コンパイルされたバイナリの`generic`コンポーネントでは、 `go_toolchain` や などの修飾子を使用して、使用されるツールチェーン`rust_toolchain`を識別します。Inspector の修飾子を設定しても認識されないか、予期される修飾子を省略すると、脆弱性が見逃されたり、誤って帰属されたりする可能性があります。

 [「パッケージ URL とは」を参照してください。](https://docs.aws.amazon.com/inspector/latest/user/sbom-generator-purl-sbom.html) Inspector が PURL タイプごとに認識する修飾子規則については、「Amazon Inspector ユーザーガイド」の「」を参照してください。

 の `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",
    },
})
```

 修飾子は、PURL タイプに対する Inspector の期待と一致する場合にのみ設定します。パッケージのアイデンティティに含まれていないメタデータを記録する必要がある場合は、代わりに CycloneDX プロパティを使用します。

#### CycloneDX プロパティ
<a name="sbomgen-plugin-developer-guide-cyclonedx-properties"></a>

 CycloneDX プロパティは、SBOM の`components[].properties`配列に表示されるキーと値の注釈です。識別方法に影響を与えずにコンポーネントを記述するため、プラグイン定義メタデータの安全な選択肢です。

 **`amazon:inspector:*`名前空間は Amazon Inspector 用に予約されています。**具体的には次のとおりです。
+ `amazon:inspector:sbom_generator:*` — sbomgen とその組み込みスキャナー用に予約されています。
+ `amazon:inspector:sbom_scanner:*` — Amazon Inspector スキャン API 用に予約されています。

 プラグインの作成者は、これらの予約済み名前空間内でキーを出力しないでください。書き込むと Inspector の動作が妨げられ、上書きされる可能性があります。予約キーの完全なリストについては、[Amazon Inspector での CycloneDX 名前空間の使用](https://docs.aws.amazon.com/inspector/latest/user/cyclonedx-namespace.html)」を参照してください。

 プロパティを定義するときは、独自の名前空間 (通常は組織またはプラグイン識別子) を使用します。

```
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",
    },
})
```

#### キー命名規則
<a name="sbomgen-plugin-developer-guide-key-naming-rules"></a>

 プロパティキーは、次のように sbomgen によって処理されます。
+ **コロンを含む**キーは、SBOM で逐語的に使用されます。名前空間を制御するために、キーには必ず少なくとも 1 つのコロンを含めてください。
+ **コロンを含まない**キーには、自動的に というプレフィックスが付けられ、予約された Inspector 名前空間内に`amazon:inspector:sbom_generator:`配置されます。カスタムプロパティでは、このシェイプは避けてください。

```
properties = {
    ["acme:my_plugin:detected_via"] = "lockfile",  -- used as-is (recommended)
    detected_via                   = "lockfile",  -- becomes "amazon:inspector:sbom_generator:detected_via" (avoid)
}
```

 `sbomgen.properties.*` 定数は、公式スキャナーが予約された名前空間内で一貫したキーを出力するように存在します。これらはカスタムプラグインの拡張ポイントではなく、代わりに独自の名前空間を使用します。

#### 子コンポーネントのプロパティと修飾子
<a name="sbomgen-plugin-developer-guide-properties-and-qualifiers-on-child-components"></a>

 ネストは独立したコンポーネント`children`です。各子には独自の テーブル`properties`と `qualifiers`テーブルがあります。親に設定されたメタデータは子には伝達されません。値を必要とする各子に明示的に値を設定します。

### オプションのコレクション関数
<a name="sbomgen-plugin-developer-guide-optional-collection-functions"></a>


| **関数** | **デフォルト** | **次の場合に上書きします。** | 
| --- | --- | --- | 
| get\_collector\_name() | {ecosystem} (例: python-pip) | カスタムコレクター名が必要 | 
| get\_collector\_description() | 空の文字列 | 説明が必要です | 
| subscribe\_to\_event() | ディレクトリパスから派生 | カスタムイベントルーティングが必要です | 

## プラグインの実行
<a name="sbomgen-plugin-developer-guide-running-your-plugins"></a>

 プラグインがパッケージメタデータを生成するには、sbomgen に、プラグインがターゲットとするファイル (、、`requirements.txt``package.json`または同等のパッケージマニフェストファイルを含むディレクトリなど) を含むアーティファクトをスキャンする必要があります。

### 基本的な使用法
<a name="sbomgen-plugin-developer-guide-basic-usage"></a>

```
inspector-sbomgen <artifact type> <arguments> --plugin-dir /path/to/plugins
```

 例: 

```
inspector-sbomgen directory --path /target -o /tmp/sbom.json --plugin-dir /path/to/plugins
```

### ネイティブスキャナーを無効にした場合 (Lua のみモード)
<a name="sbomgen-plugin-developer-guide-with-native-scanners-disabled-lua-only-mode"></a>

```
inspector-sbomgen directory --path /target --plugin-dir /path/to/plugins --disable-native-scanners -o sbom.json
```

### 詳細なログ記録を使用する
<a name="sbomgen-plugin-developer-guide-with-verbose-logging"></a>

```
inspector-sbomgen directory --path /target --plugin-dir /path/to/plugins --verbose -o sbom.json
```

## 使用可能なスキャナーの一覧表示
<a name="sbomgen-plugin-developer-guide-listing-available-scanners"></a>

 を使用して`list-scanners`、sbomgen で使用できるすべてのスキャナーを表示します。これには、組み込みのネイティブスキャナー、sbomgen にバンドルされた公式 Lua プラグイン、 を介して提供したカスタム Lua プラグインが含まれます`--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                    │
└─────────────────────┴────────┴───────────────────────────────┴─────────────────────────────┘
```

 SOURCE 列には、各スキャナーの出所が表示されます。


| **ソース** | **意味** | 
| --- | --- | 
| native | sbomgen にバンドルされた組み込みスキャナー | 
| official | sbomgen にバンドルされた Lua プラグイン | 
| custom | 経由でロードされるユーザー提供の Lua プラグイン --plugin-dir | 

 `list-scanners` なしで実行すると、 スキャナー`native`と `official`スキャナーの両方が`--plugin-dir`引き続き含まれます。これらは常に使用できます。`--plugin-dir` フラグは、`custom`スキャナーをリストに追加します。

 ネイティブスキャナーのない Lua スキャナーのみを一覧表示するには: 

```
inspector-sbomgen list-scanners --plugin-dir /path/to/plugins --disable-native-scanners
```

## スキャナーの選択
<a name="sbomgen-plugin-developer-guide-scanner-selection"></a>

 Lua 検出プラグインは、組み込みのネイティブスキャナーと同じスキャナー選択モデルに参加します。デフォルトでは、sbomgen は、 グループがアーティファクトタイプのデフォルトのスキャナーグループと一致するすべてのスキャナーを実行します。これを 3 つのフラグで上書きできます。

### 特定のスキャナーのみを実行する
<a name="sbomgen-plugin-developer-guide-run-only-specific-scanners"></a>

 名前付きスキャナーのみを実行する`--scanners`には、 を使用します。他のすべてのスキャナーは除外されます。

```
inspector-sbomgen directory --path /target \
    --plugin-dir /path/to/plugins \
    --scanners python-requirements \
    -o sbom.json
```

 これにより、`python-requirements`スキャナーのみが実行されます。複数のスキャナー名をカンマで区切って渡すか、スキャナーグループ名 ( など`programming-language-packages`) を渡して、そのグループに属するすべてのスキャナーを有効にすることができます。

### 特定のスキャナーを除外する
<a name="sbomgen-plugin-developer-guide-exclude-specific-scanners"></a>

 他のすべてを実行中に名前付きスキャナーを除外`--skip-scanners`するには、 を使用します。

```
inspector-sbomgen directory --path /target \
    --plugin-dir /path/to/plugins \
    --skip-scanners python-poetry \
    -o sbom.json
```

 これにより、 を除くすべてのデフォルトスキャナーが実行されます`python-poetry`。と同様に`--scanners`、このフラグはグループ名も受け入れるため、 を渡すと、そのグループ内のすべてのスキャナー`--skip-scanners programming-language-packages`が無効になります。

**注記**  
`--scanners` と `--skip-scanners`は相互に排他的です。両方を渡すとエラーが発生します。

### デフォルト以外のグループからスキャナーを追加する
<a name="sbomgen-plugin-developer-guide-add-scanners-from-non-default-groups"></a>

 デフォルトのスキャナーセットは、スキャンされるアーティファクトタイプによって異なります ([グループが選択に与える影響](#sbomgen-plugin-developer-guide-how-groups-affect-selection)以下の のマトリックスを参照）。グループがアーティファクトタイプのデフォルトセットに含まれていないスキャナーは、オプトインしない限り実行されません。`--additional-scanners` を使用して、スキャナーを置き換えずにデフォルトセットに追加します。

```
inspector-sbomgen directory --path /target \
    --plugin-dir /path/to/plugins \
    --additional-scanners my-extra-scanner \
    -o sbom.json
```

 これにより、アーティファクトタイプのすべてのデフォルトスキャナーと が実行されます`my-extra-scanner`。フラグは、置き換えるのではなく、スキャナー名またはグループ名、デフォルトセットのスタックのカンマ区切りリストを受け入れます。を使用して`list-scanners`、スキャナーが属するグループを確認します。

### グループが選択に与える影響
<a name="sbomgen-plugin-developer-guide-how-groups-affect-selection"></a>

 検出プラグインの `get_scanner_groups()`関数は、スキャナーが属するグループを決定します。スキャナーがデフォルトで実行されるかどうかは、そのグループとスキャンされるアーティファクトタイプの両方によって異なります。以下のマトリックスは、各アーティファクトタイプのデフォルトのスキャナーセットに含まれるグループを示しています。


| **[Group]** (グループ) | **`directory` / `archive`** | **`container`** | **`localhost`** | **`volume`** | **`binary`** | 
| --- | --- | --- | --- | --- | --- | 
| os | — | ✓ | ✓ | ✓ | — | 
| programming-language-packages | ✓ | ✓ | ✓ | ✓ | — | 
| binary | ✓ | ✓ | — | — | ✓ | 
| extra-ecosystems | — | ✓ | ✓ | ✓ | — | 
| dockerfile | ✓ | ✓ | — | — | — | 
| custom | ✓ | ✓ | ✓ | ✓ | ✓ | 
| certificate | — | — | — | — | — | 
| machine-learning | — | — | — | — | — | 
| pkg-scanner | — | — | — | — | — | 

 ✓ は、そのグループ内のすべてのスキャナーがそのアーティファクトタイプに対してデフォルトで実行されることを意味します。`—` は、 グループがデフォルトセットに含まれていないため、そのスキャナーは `--scanners`または を介して明示的に選択された場合にのみ実行されます`--additional-scanners`。

 注目すべき詳細: 
+ **`custom`** は常にデフォルトのセットにあります。 を介してロードされたカスタムプラグインは `custom`グループ`--plugin-dir`を自動的に受信するため、アーティファクトタイプに関係なくデフォルトで実行されます。
+ **`extra-ecosystems`** は、`container`、、`localhost`および `volume`スキャンではデフォルトですが、`directory`、`archive`、または `binary`スキャンではデフォルトではありません。これらのタイプを含めるには`--additional-scanners`、 (名前または`extra-ecosystems`グループで) 渡す必要があります。
+ **`pkg-scanner`** は情報です。スキャナーを に表示するパッケージコレクターとしてマークしますが`list-scanners`、それ自体ではスキャナーが実行されません。で実行グループ ( など`programming-language-packages`) とペアリングします`get_scanner_groups()`。

 たとえば、 が返すプラグイン`{sbomgen.groups.EXTRA_ECOSYSTEMS, sbomgen.groups.PACKAGE_COLLECTOR}`は、コンテナ、localhost、ボリュームスキャンでデフォルトで実行されますが、ディレクトリ、アーカイブ、バイナリスキャンでは `--additional-scanners` (または `--scanners`) が必要です。

## プラグイン衝突ルール
<a name="sbomgen-plugin-developer-guide-plugin-collision-rules"></a>

 Sbomgen は、ロードされたすべてのプラグインに一意のメタデータを適用して、サイレント上書きを防ぎ、SBOM の整合性を確保します。衝突が検出されると、後のプラグインは**スキップ**され、警告がログに記録されます。

### チェック対象
<a name="sbomgen-plugin-developer-guide-what-is-checked"></a>


| **メタデータ** | **スコープ** | **衝突時** | 
| --- | --- | --- | 
| 検出イベント名 (get\_event\_name) | すべての検出プラグイン | 2 番目のプラグインがスキップされました | 
| スキャナー名 (get\_scanner\_name) | すべての検出プラグイン | 2 番目のプラグインがスキップされました | 
| コレクター名 (get\_collector\_name) | すべてのコレクションプラグイン | 2 番目のプラグインがスキップされました | 

### 許可される内容
<a name="sbomgen-plugin-developer-guide-what-is-allowed"></a>

 複数のコレクションプラグインは、 を介して同じイベントにサブスクライブ**できます**`subscribe_to_event()`。これは意図したファンアウトパターンです。1 つの検出プラグインは、それぞれが異なることを行う複数のコレクターにフィードできます (たとえば、1 つはパッケージを抽出し、もう 1 つはシークレットを検出します）。

### 衝突の回避
<a name="sbomgen-plugin-developer-guide-avoiding-collisions"></a>

 2 つのプラグインが同じスキャナー名、イベント名、またはコレクター名を使用している場合、ロードされた 2 番目のプラグインはスキップされます。衝突を解決するには、プラグインで適切なオーバーライド関数 (`get_scanner_name()`、、または ) を定義して`get_event_name()`、競合するメタデータの名前を変更します`get_collector_name()`。

### 衝突警告の例
<a name="sbomgen-plugin-developer-guide-collision-warning-example"></a>

```
[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.
```

 警告は、スキップされたプラグイン、衝突したプラグイン、その名前をすでに所有しているプラグイン、変更する関数を示します。

## デバッグ
<a name="sbomgen-plugin-developer-guide-debugging"></a>

### コンソールのログ記録
<a name="sbomgen-plugin-developer-guide-console-logging"></a>

 プラグインは、次の関数を使用して sbomgen のコンソール出力にメッセージを送信できます。


| **関数** | [**レベル**] | **デフォルトでは表示されますか?** | 
| --- | --- | --- | 
| sbomgen.log\_debug(message) | DEBUG | いいえ — 必須 --verbose | 
| sbomgen.log\_info(message) | 情報 | はい | 
| sbomgen.log\_warn(message) | WARN | はい | 
| sbomgen.log\_error(message) | エラー | はい | 

 プラグインからのすべてのログ出力には、プラグインのソースとパス (例: `[custom:python-pip]`) が自動的にプレフィックス付けされるため、異なるプラグインからのメッセージは簡単に区別できます。`log_info`、`log_warn`、および `log_error`は常に出力します。sbomgen が で呼び出された場合にのみ`log_debug`出力されます`--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
```

### ブレークポイント
<a name="sbomgen-plugin-developer-guide-breakpoints"></a>

 Enter を押すまでプラグインの実行を一時停止してブロック`sbomgen.breakpoint()`するには、 を使用します。これは粗デバッガーとして機能します。ログステートメントと組み合わせて、特定の時点で状態を検査します。

```
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
```

 ブレークポイントメッセージが stderr に出力されます。Enter を押すまで実行が一時停止し、ログ出力を確認する時間を確保します。

### 一般的な問題
<a name="sbomgen-plugin-developer-guide-common-issues"></a>


| **症状** | **原因** | **修正** | 
| --- | --- | --- | 
| プラグインがロードされていません | init.lua がみつかりません | エントリポイントが正しいディレクトリ深度に存在することを確認する | 
| 「必要な関数の欠落」 | 関数名のタイプミス | get\_scanner\_name、get\_scanner\_description、、get\_scanner\_groups、、discover、get\_event\_name、collect、 get\_localhost\_scan\_paths get\_collector\_namesubscribe\_to\_eventが定義されていることを確認します。 | 
| コレクションプラグインが呼び出されない | イベント名の不一致 | 検証get\_event\_name()して同じ文字列をsubscribe\_to\_event()返す | 
| SBOM にパッケージがない | push\_package 呼び出されていないか、必須フィールドがありません | name、purl\_type、 component\_typeがすべてのpush\_package呼び出し (子を含む) で設定されていることを確認します。sbomgen.component\_types.\* 定数を使用します。 | 
| プラグインのランタイムエラー | 実行中の Lua エラー | エラーの詳細を含む警告メッセージの sbomgen 出力を確認する | 
| 「SKIPPED: discovery event name ... is already registered」 | 別のプラグインが同じイベント名を使用する | 名前get\_event\_name()を一意の値に変更する | 
| 「SKIPPED: スキャナー名 ... は既に登録されています」 | 別のプラグインが同じスキャナー名を使用する | 名前get\_scanner\_name()を一意の値に変更する | 
| 「SKIPPED: collector name ... is already registered」 | 別のプラグインが同じコレクター名を使用する | 名前get\_collector\_name()を一意の値に変更する | 

## API リファレンス
<a name="sbomgen-plugin-developer-guide-api-reference"></a>

 完全な関数カタログは、コンパニオンドキュメントに保持されます。

 **→ [プラグイン API リファレンス](sbomgen-plugin-api-reference.md)** 

 API リファレンスは、すべての`sbomgen.*`関数 (ファイル I/O、バイナリユーティリティ、パッケージ出力、regex、構造化解析、Windows レジストリ、ログ記録、デバッグ）、テストファイルで使用できる `testing.*` API、すべての組み込み定数 (`properties`、`groups`、`platform`)`component_types`、プラグインライフサイクルグローバルを対象としています。

## エラー処理
<a name="sbomgen-plugin-developer-guide-error-handling"></a>

 失敗する可能性がある API 関数は、 の 2 つの値を返します`value, err`。成功すると、 `err`は になります`nil`。失敗した場合、最初の値は `nil`で、 `err`はエラー文字列です。

```
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
```

 プラグインが未処理の Lua エラーを発生させた場合、sbomgen は警告をログに記録し、次のファイルまたはプラグインに進みます。他のプラグインは影響を受けません。

## サンドボックスの制限
<a name="sbomgen-plugin-developer-guide-sandbox-restrictions"></a>

 プラグインは、標準ライブラリへのアクセスが制限されたサンドボックス化された Lua VM で実行されます。


| **[Library]** (ライブラリ) | **使用可能** | **Notes** (メモ) | 
| --- | --- | --- | 
| base | ✓ | dofile、loadfile、 loadstringが削除されます | 
| string | ✓ | 完全な文字列操作 | 
| table | ✓ | 完全なテーブル操作 | 
| math | ✓ | 完全な数学ライブラリ | 
| package | ✓ | require() プラグインディレクトリに制限 | 
| io | ✗ | 代わりに sbomgen.\* I/O 関数を使用する | 
| os | ✗ | セキュリティのためにブロック | 
| debug | ✗ | VM イントロスペクションを防ぐためにブロック | 
| coroutine | ✗ | ロードされていません | 

 `io.open` または を介したファイルシステムへの直接アクセス`os.execute`は利用できません。すべてのファイルオペレーションは `sbomgen` API を経由する必要があります。これにより、アーティファクトタイプ間で一貫した動作が保証され、プラグインがアーティファクト外のファイルにアクセスできなくなります。

 `require()` は、プラグイン独自のディレクトリツリー内からのみモジュールをロードできます。などの親ディレクトリトラバーサル`require("../shared")`はブロックされます。

## プラグイン間でのコードの共有
<a name="sbomgen-plugin-developer-guide-sharing-code-between-plugins"></a>

 を使用して`require()`、プラグインの ディレクトリ内からヘルパーモジュールをロードできます。

```
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
```

 を使用したサブディレクトリもサポート`init.lua`されています。

```
my-ecosystem/
├── init.lua
└── parsers/
    └── init.lua
```

```
local parsers = require("parsers")
```

 `require()` はプラグインの ディレクトリに制限されています。他のプラグインまたはシステムパスからモジュールをロードすることはできません。サードパーティーの Lua ライブラリ (LuaRocks など) はサポートされていません。プラグインディレクトリ内のローカルヘルパーモジュールのみをロードできます。