プラグインの仕組み
このページでは、プラグインシステムをオペレーターの視点から説明します。プラグインがどのように検出されるか、何を行うことが許可されているか、そしてホストが信頼できないプラグインをどのように封じ込めるかについて解説します。プラグイン作成者が実装するディスク上のコントラクト(マニフェストフィールド、ブリッジのエクスポート、ホスト関数)については、Plugin protocolを参照してください。
システムの形
プラグインは、サンドボックス化された WebAssembly モジュールとマニフェストです。ホストはそれを読み込み、宣言されたケーパビリティとパーミッションを読み取り、オペレーターがプラグインシステムをオンにした場合にのみ、そのツールをエージェントに公開します。プラグインについて暗黙的なものは何もありません。プラグインは、マニフェストが宣言し、オペレーターのポリシーが許可するケーパビリティのみを取得し、それ以外は何も取得しません。自分で構築するには、プラグインガイド から始めてください。
すべてのレイヤーで3つのプロパティが成り立ちます:
- デフォルトでは無効です。 プラグインシステムは
[plugins] enabled = trueでない限り何も読み込みません。プラグイン設定のないデフォルトビルドでは、プラグインコードは実行されません。 - デフォルトで拒否。 プラグインは、マニフェストで対応する権限を宣言することによってのみ、ホストの機能(HTTP egress、config、memory)に到達できます。宣言されていない機能は、単に未使用なのではなく、到達不能です。
- ポリシーにより検証済み。 未署名または信頼されていないプラグインが読み込まれるかどうかはオペレーターの決定であり、設定で一度設定され、検出時に一律に適用されます。
プラグインのロードのライフサイクル
ランタイムがツールセットを構築する際、プラグインローダーはこれらのステージを順番に実行します。前のステージで失敗したプラグインは、後のステージに到達することはありません。
- ゲート。
[plugins] enabledが false の場合、ローダーは何もしません。これは最初で最も安価なチェックです。 - 検出。 ローダーは解決済みのプラグインディレクトリ(
[plugins] plugins_dir、デフォルト~/.zeroclaw/plugins/)をスキャンし、manifest.tomlを含むサブディレクトリを探します。 - 形状を検証します。 各マニフェストは少なくとも1つのケイパビリティを宣言する必要があり、skill 以外のプラグインは存在する
wasm_pathを指定する必要があります。不正な形式のマニフェストは警告とともにスキップされ、決してロードされません。 - 署名ポリシーを強制する。 各プラグインは、設定された
[plugins.security] signature_modeとtrusted_publisher_keysに対してチェックされます。ポリシーに失敗したプラグインは、読み込まれたセットから除外され、ツールとして表示されません。 - ツールを登録します。 残ったツールプラグインはエージェントツールとしてラップされ、組み込みツールの後に追加されます。ツールのディスパッチでは名前が最初に一致したものに解決されるため、組み込みツールと名前が衝突するプラグインツールは選択されません。プラグインツールには一意の名前を付けてください。ツールプラグインとスキルプラグインは_自動検出される_ため、この列挙は
[plugins] auto_discover = trueの場合にのみ行われます(デフォルトはfalse、フェイルクローズ)。enabled = trueでもauto_discover = falseの場合、プラグインツールやスキルは読み込まれませんが、[channels.plugin.<alias>]の下で宣言したチャネルは引き続き有効になります。スキルローダーにも同じauto_discoverゲートが適用されます。
署名ステージは最も設定を誤りやすいステージであるため、単独で理解しておく価値があります。
署名ポリシー
すべてのプラグインマニフェストには、Ed25519 署名と、署名した公開者の 16 進数エンコードされた公開鍵を含めることができます。オペレーターは、[plugins.security] signature_mode を通じて、その署名をどの程度厳密に強制するかを決定します:
| モード | 何が読み込まれるか | 使用するタイミング |
|---|---|---|
disabled | 署名の有無にかかわらず、すべての整形式のプラグイン | 自分で構築したプラグインに対するローカル開発 |
permissive | すべての整形式プラグイン。未署名、信頼されていない、無効な署名は警告付きでロードされます | 既存のインストールを壊さずに署名へ移行する |
strict | 信頼できる発行元からの有効な署名を持つプラグインのみが読み込まれます | 任意の共有または本番ホスト |
strict モードでは、マニフェストの publisher_key が [plugins.security] trusted_publisher_keys に含まれている必要があり、署名は正規化されたマニフェストのバイト列に対して検証されなければなりません。未署名、信頼されていない鍵で署名されている、または署名が検証できないプラグインは、検出時に破棄され、ツールになることはありません。デフォルトは disabled なので、新規のローカルチェックアウトは鍵管理なしで動作しますが、制御下にない場所からプラグインを読み込むホストは strict で実行すべきです。
このポリシーは一律に適用されます。プラグインを一覧表示する際にホストが適用するチェックと同じものが、エージェントランタイムがツールセットを構築する際にも適用されます。そのため、strict モードで表示されないプラグインは、エージェントも呼び出せないプラグインとなります。
ケーパビリティと権限
マニフェストは2つの別々のものを宣言し、その区別は重要です。
- Capabilities は、プラグインがどの種類の拡張であるかを示します:
tool、channel、memory、observer、またはskill。toolプラグインは、LLM が呼び出せるツールを提供します。 - パーミッションは、プラグインのコードが実行時に到達できるホストサービスです: HTTP エグレス、構成、メモリ。マニフェストで宣言されていないパーミッションは、プラグインが到達できないホスト関数です。
ホストは権限を限定的に付与します。マニフェストで宣言されていない権限に対応するホスト関数には、プラグインはアクセスできません。設定はホストが発行したインスタンス ID から解決されるため、プラグインが別のパッケージやバインディングを選択することはできず、生のプロセス環境を読み取ることもありません。http_client は外向きの wasi:http サーフェスへのアクセスを制御します。共有の SSRF 対策付きエグレスポリシーは、引き続き別途行うプラグイン強化作業です。このページでは署名ポリシーの境界を扱います。
設定リファレンス
すべての設定は plugins.* 設定パス配下にあり、任意の設定サーフェス(zerocode、ゲートウェイ、または CLI)経由で設定されます:
# マスタースイッチ。これが false の間は何もロードされません。
zeroclaw config set plugins.enabled true
# 実行時に自動検出されたツールおよびスキルのプラグインを読み込む(デフォルト: false)。
# Without this, `enabled = true` activates only explicitly-declared channels.
zeroclaw config set plugins.auto_discover true
# プラグインが検出される場所(デフォルト: ~/.zeroclaw/plugins)。
zeroclaw config set plugins.plugins_dir ~/.zeroclaw/plugins
# disabled | permissive | strict
zeroclaw config set plugins.security.signature_mode strict
# 厳格モードでプラグインの公開が許可された、16進数エンコードされた Ed25519 公開鍵。
zeroclaw config set plugins.security.trusted_publisher_keys ["a1b2c3d4e5f6..."]
サードパーティ製プラグインを読み込むホストでは、enabled = true、signature_mode = "strict" を設定し、信頼する発行元のキーのみを列挙します。自動検出されたツールおよびスキルプラグインも読み込むには、auto_discover = true も設定します。これはデフォルトでは false であるため、enabled = true だけでは、[channels.plugin.<alias>] の下で宣言したチャネルだけが有効になり、プラグインのツールやスキルは有効になりません。自分で構築したプラグインだけを実行するホストでは、開発中は signature_mode をデフォルトの disabled のままにし、ホストを共有する前に制限を強化できます。
プラグインでまだできないこと
すべての権限が付与されていても、サンドボックスはプラグインを制限します:
- WebAssembly モジュールとして実行され、ホストプロセスやルート化されたワークスペース外のファイルシステムへの環境アクセスはありません。ネットワークエグレスは HTTP パーミッションによってゲートされ、SSRF ガードされたエグレス境界自体は、コンパニオンのプラグインハードニング作業によって提供されます。
- 信頼されたツールまたはチャネルプラグインは、認可されたサービス呼び出し中に、スコープ付き
secrets.getインポートを通じて、スキーマで指定されたシークレットの平文を読み取れます。ツールはexecute中にアクセスを受け取ります。チャネルはconfigureおよび運用呼び出し中にconfig.getとsecrets.getへのアクセスを受け取ります。1 回の呼び出し内での読み取りには 1 つの正規リビジョンが使用されるため、同一バインディングの公開設定とシークレットのローテーションは次の操作で利用可能になります。インスタンス化と静的メタデータの検出では、どちらのインポートも使用できません。ホストは公開設定の注入とクロスインスタンス選択を防ぎますが、平文を返すインポートでは、悪意のあるゲストが読み取った内容を保持するのを防げません。準拠するチャネルプラグインは、使用する各時点で設定と認証情報を解決する必要があります。 - 組み込みツールを置き換えることはできません。組み込みツールが先に登録され、ツールディスパッチは名前を最初の一致で解決するため、衝突するプラグインツールは単に選択されません。
サンドボックスと名前空間の制約は、プラグインコードが何を試みるかにかかわらず適用されます。一方、保持禁止ルールは信頼されたチャネルプラグイン契約の一部であり、だからこそ発行元の審査と署名ポリシーが依然として重要です。