組織向けの mod を管理する
管理設定で Claude Code の mod を制御します。ユーザーがインストールした mod を停止し、自分たちの mod のみを許可し、mod が実行できることを確認し、独自の mod でポリシーを実施します。
mod は Claude Code 内で実行されるプラグインで、それをインストールしたユーザーの権限で実行されます。Mod はサンドボックス化されていません。管理設定 を通じて、ユーザーのマシンで mod が実行されるかどうか、どの mod が実行されるか、実行順序を決定できます。他の mod が何をするかを監視または拒否する独自の mod をインストールすることもできます。
このページは、ファイル、MDM、または claude.ai 管理コンソールを通じて Claude Code の管理設定をデプロイする担当者向けです。Mod は Claude Code v2.1.287 以降ではデフォルトで有効です。実行したい内容に合わせて、以下のセクションから選択してください。
- ユーザーの独自 mod を除外する(独自の mod の有無を問わず): ユーザーがインストールした mod の読み込みを停止する
- 何も変更しない場合に何が起こるかを確認する: デフォルトで何が起こるかを理解する
- mod を有効にして他の制限を設定する: 許可する範囲を選択する
以下のケースは他のページで説明されています。
- 管理設定をまだデプロイしていない: 管理設定をデプロイする から始めてください
- ユーザーがインストールできるプラグインを制御したい: 組織向けのプラグインを管理する を参照してください
ユーザーがインストールした mod の読み込みを停止する
ユーザーが持ち込むすべての mod が読み込まれないようにするには、組み込みガード(Claude Code がユーザーがインストールするすべての mod の前に読み込むポリシー mod)で allowManagedModsOnly オプションを設定します。このオプションは、マネージド設定の pluginConfigs に cc-plugin-sec-default@builtin をキーとして配置します。
{
"pluginConfigs": {
"cc-plugin-sec-default@builtin": {
"options": {
"allowManagedModsOnly": true
}
}
}
}
マネージド設定でこのオプションを設定すると:
- ユーザーが持ち込む mod は読み込まれません:ユーザーがインストールしたプラグイン内の mod、
--plugin-dirで読み込まれた mod、および Claude がセッション中に作成した mod が対象です - 組織の mod は引き続き読み込まれます:組織のものとしてカウントされる mod はチェックされません。その他のすべての mod はユーザーのものとしてカウントされ、読み込まれません。これには、GitHub または他のリモートマーケットプレイスから有効にしたプラグイン内の mod、および組織が claude.ai でメンバー向けに有効にした mod が含まれます。組織のものとしてカウントされるものがない場合、インストールされた mod は読み込まれません
- ユーザーはこれを元に戻せません:ガードはマネージド設定からのみオプションを読み取るため、ユーザー、プロジェクト、またはローカル設定ファイル内の同じエントリ、または
--settingsで渡されたファイル内のエントリは何も変わりません - ファイルまたは MDM ポリシーはすべてのプロバイダーに対応します:オプションをファイルとして、または MDM を通じて配信する場合、Amazon Bedrock、Google Cloud の Agent Platform、および Microsoft Foundry で同じように機能します。claude.ai 管理コンソールからの配信については、プラットフォームの可用性 を参照してください
- ユーザーの他のカスタマイズは引き続き機能します:設定ファイル内の hooks、ステータス行、および
/goalは影響を受けません - 組み込み mod は引き続き実行されます:
AGENTS.mdサポートなど Claude Code に組み込まれた mod には、それぞれ独自のスイッチ があります
ユーザーのマシンでオプションを確認するには、--plugin-dir と mod を保持するディレクトリのパス(例:claude --plugin-dir ./first-mod)を使用して Claude Code を起動します。mod の hooks は実行されず、トランスクリプトとデバッグログに ガードのメッセージ が表示されます。このメッセージは mod と allowManagedModsOnly の名前を示します。mod が読み込まれる場合は、ポリシーが有効であることを確認する および オプションが有効になるかどうかを決定するルール を参照してください。
早期アクセス中に CLAUDE_CODE_ENABLE_FUNCTION_HOOKS を 0 に設定した場合は、このオプションに置き換えてください。Claude Code v2.1.287 以降は、任意の値で変数を無視するため、そこに 0 があると mod は有効なままになります。
デフォルトで何が起こるかを理解する
独自の mod 設定がない場合、ユーザーは以下を取得します。
-
Mod は有効です。 ユーザーは、プラグイン設定が許可するマーケットプレイスから mod を含むプラグインをインストールするか、
--plugin-dirを使用してディレクトリから読み込むことができます。 -
組み込みガードが最初に実行されます。 Claude Code は、ユーザーがインストールしたすべての mod の前に、
sec-default@builtinという名前の組み込み mod を読み込みます。ユーザーはそれをオフにすることはできません。/pluginとデバッグログは、それをcc-plugin-sec-defaultとして一覧表示します。ガードは以下のいずれかが真の場合に読み込まれます。- マシンに管理設定がある
- ユーザーが Team または Enterprise プランで Claude Code にサインインしている
API キー、または Amazon Bedrock、Google Cloud の Agent Platform、Microsoft Foundry を通じて認証するユーザーは、管理設定を持つマシンでのみガードを取得します。
-
ガードは管理対象を保護します。 ユーザーの mod は、管理フックが受け取るもの、システムプロンプト、管理対象の
CLAUDE.mdおよびその他の管理対象の指示、mod が設定として読み取るもの、または管理対象の MCP サーバーのツールと説明を変更することはできません。 -
その他はすべて許可されます。 ガードは他の制限を追加しません。ユーザーの mod は、ファイルの読み取りと書き込み、プロセスの開始、ネットワークリクエストの実行、ツール呼び出しとプロンプトの書き直し、ツール呼び出しの拒否、そうでなければプロンプトが表示されるツール呼び出しの承認、インターフェイスへの描画をすべてそのユーザーの権限で実行できます。
-
拒否ルールと管理フックが優先されます。 ガードが読み込まれる場所では、ユーザーの mod は、
denyルールが拒否する呼び出しを承認することはできません。ルールを保持する設定ファイルがどれであれ。管理設定のPreToolUseフックからのブロックも最終的です。どちらも Claude のツール呼び出しに適用されます。どちらも mod 独自の$.fsと$.process呼び出し には適用されません。Read(.env)が拒否されている場合、mod は$.fs.readでそのファイルを読み取るか、それを実行するプログラムを開始できます。これらの呼び出しを制限するには、mod の読み込みを防ぐか、ポリシー mod で呼び出しを処理してください。 -
他の権限チェックはオーバーライドできます。 ツール呼び出しを承認するユーザーの mod は、
askルールがプロンプトを表示する呼び出し、または管理設定外のPreToolUseフックがブロックした呼び出しを承認できます。自動モードでは、mod が承認する呼び出しは分類器チェックなしで実行されます。
ガードのソースは、Claude Code リポジトリの mods/sec-default ディレクトリ で公開されています。
どのコントロールが引き続き適用されるかを知る
Mod は既に持っているコントロールを置き換えません。
- 設定フックは引き続き機能します。 設定ファイルおよびプラグインの
hooks/hooks.json内のコマンド、HTTP、プロンプト、エージェントフックは以前と同じように実行され、mod と並行して実行されます。これについて非推奨のものはありません。 - 拒否ルールはガードが読み込まれる場所で優先されます。 ユーザーの mod は、
denyルールが拒否する呼び出しを承認することはできません。ただし、allowModsToOverrideDenyRulesを設定する場合を除きます。 - 管理フックが最初に実行されます。 管理設定の
PreToolUseフックは、mod がツール呼び出しを見る前に実行され、そのブロックは最終的です。mod がその後呼び出しを書き直す場合、管理フックは書き直された呼び出しで再度実行されるため、ブロックは引き続き適用されます。他の設定ファイルおよびプラグインからのPreToolUseフックは最後の mod の後に実行されるため、独自の結果を返すツール実行の代わりに返す mod は、それらが実行されるのを防ぎます。Mod が実行される順序 を参照してください。 - ネットワークポリシーは
$.http.fetchをカバーします。 組織が Web フェッチをオフにするか、セッションの非必須ネットワークトラフィックがオフになっている場合、Claude Code は mod が$.http.fetchで実行するネットワークリクエストを拒否します。ポリシーは mod が$.process.runで開始するプログラムをカバーしません。そのプログラムはユーザー独自のアクセスでネットワークに到達します。 - プラグインコントロールは mod をカバーします。 Mod はプラグインであるため、ユーザーがインストールできるものを制限する設定(
strictKnownMarketplacesなど)は、それをインストールできるかどうかを決定します。 - Mod は権限プロンプトを変更できません。 Mod は Claude Code のインターフェイスの大部分を再スタイル化できますが、権限プロンプトはできないため、プロンプトが表示するものを変更できません。Mod は、デフォルトで何が起こるかを理解する で説明されているように、プロンプトが表示される前にツール呼び出しを承認または拒否できます。
- 信頼プロンプトが最初に表示されます。 ユーザーがまだ信頼していないディレクトリでのインタラクティブセッションでは、信頼プロンプトに答えるまで mod は読み込まれません。
--safe-modeはインストールされた mod をオフにします(独自の mod を含む)。 セッションをclaude --safe-modeで開始して、mod が問題を引き起こしたかどうかを確認します。
これらのコントロールのいずれも mod をサンドボックス化しません。許可する mod はユーザーとして実行され、ファイル、プロセス、ネットワークへのユーザーのアクセスを持ちます。
Mod を有効にするかどうかを決定する
Mod は、Claude Code 内で実行されるため、プラグインの他の部分よりも多くのことができます。すべてのプロンプトとツール呼び出しを見ることができ、それらを変更でき、権限プロンプトが表示される前にツール呼び出しを許可または拒否できます。
ユーザーが mod として読み込むことができるものは、既に持っているプラグインコントロールに依存します。
| 現在のプラグインコントロール | ユーザーが mod として読み込むことができるもの |
|---|---|
| なし | マーケットプレイスから、--plugin-dir を使用したディレクトリから、または Claude がセッション中に作成した mod |
| マーケットプレイスの許可リスト | 許可するマーケットプレイスから、または --plugin-dir を使用したディレクトリから。Claude がセッション中に作成した mod は、許可リストが skills-dir を含む場合にのみ読み込まれます。 |
マーケットプレイスの許可リストと disableSideloadFlags |
許可するマーケットプレイスから |
組織向けのプラグインを管理する は、プラグインが読み込まれる方法と各方法を制御する設定を一覧表示しています。
ユーザーがインストールする前にマーケットプレイス内の mod を確認するには、mod が実行できることを確認する を参照してください。ユーザーの mod を確認するまで除外するには、ユーザーがインストールした mod の読み込みを停止する を参照してください。
Mod が実行できることを確認する
実行せずに mod が実行できることを確認できます。シェルで、プラグインのディレクトリで claude plugin validate を実行します。
claude plugin validate ./some-mod
出力の 2 行は mod のコードを説明しています。
❯ ./register.js hooks: session.start, tool.call, ui.render{component=Pane}
❯ ./register.js calls: $.fs.read, $.http.fetch, $.store.set, $.ui.open
hooks: 行は mod が受け取るイベントを一覧表示しています。calls: 行は mod のコードが呼び出す mod API メソッドを一覧表示しています。Mod API(mod のコードで $ として記述)は、mod がファイル、プロセス、ネットワークに到達する方法です。Claude Code は、このコマンドが読み取ることができない方法で mod API を使用する mod の読み込みを拒否します。
calls: 行でこれらを探してください。
| 呼び出し | 意味 |
|---|---|
$.fs.read, $.fs.write |
ユーザーが実行できる場所のファイルを読み取りまたは書き込みます |
$.process.run, $.process.spawn |
ユーザーとしてプログラムを開始します |
$.http.fetch |
ネットワークリクエストを実行します |
$.env.get, $.settings.read |
API キーを保持できる環境変数と設定を読み取ります。env reads: 行は各変数に名前を付けます。 |
$.env.set |
Claude Code およびそれが開始するすべてのコマンドと MCP サーバーの環境変数を設定し、それらが実行するものを変更できます。env writes: 行は各変数に名前を付けます。 |
$.mcp.call |
接続された MCP サーバーのツールを呼び出し、セッションの権限ルールの下で実行します |
$.model.complete |
ユーザーのプランまたは API キーをモデル呼び出しに使用します |
$.prompt.submit |
プロンプトを送信し、ユーザー独自の言葉として送信できます |
$.session.send |
別のセッションまたはサブエージェントの Claude が読む メッセージを送信します |
hooks: 行では、tool.call と prompt.submit は mod がすべてのツール呼び出しとすべてのプロンプトを見ることができ、それらを変更できることを意味しています。session.append は mod が保存される前に会話の各行を書き直すことができることを意味しています。ui.render{component=AskUserQuestion} は mod が Claude がユーザーに質問するために使用するダイアログを再描画できることを意味しています。tool.check は mod が権限プロンプトが表示される前にツール呼び出しを承認または拒否できることを意味しています。デフォルトで何が起こるかを理解する は、その答えに優先する規則とフックを一覧表示しています。
許可する範囲を選択する
Mod ポリシーは、インストールされた mod がまったくない状態から、ユーザーが選択した任意の mod まで、独自の mod が他の mod をチェックし、各ポリシーは数個の管理設定です。最初の列で必要なポリシーを見つけ、2 番目の列が名前を付けるものを設定します。管理設定をデプロイする は、管理設定がどこに存在するかをカバーしています。
| 必要なもの | 設定 |
|---|---|
| インストールされた mod なし、フックは変更なし | allowManagedModsOnly を設定し、独自の mod をデプロイしません |
| インストールされた mod なし、フックもなし、管理フックを含む | disableAllHooks を true に設定します |
| 組織の mod のみ | ガードの allowManagedModsOnly オプション を設定し、mod をインストール してそれらが組織のものとしてカウントされるようにします |
| 承認するマーケットプレイスからの任意の mod | マーケットプレイス制限 を保持し、disableSideloadFlags を true に設定します |
| 任意の mod、独自の mod が他の mod をチェック | mod をインストール し、prependPlugins で sec-default@builtin と共にリストします |
各設定が実行すること。
allowManagedModsOnly: 組み込みガードのオプション。ユーザーの独自 mod は読み込まれず、設定フック、ステータス行、/goalは引き続き機能します。ユーザーがインストールした mod の読み込みを停止する はそれがカバーするものを一覧表示しています。allowManagedHooksOnly: より広い設定。組織の mod と Claude Code に組み込まれた mod のみが読み込まれます。ユーザーが自分でインストールした mod は読み込まれません。設定はユーザー独自の設定ファイル内のフックもブロックします。設定する前に 「allowManagedHooksOnlyの下で実行されるもの」 を読んでください。disableAllHooks: 最も広い設定。管理設定では、インストールされたすべてのプラグイン(組織のものを含む)の mod を停止し、設定ファイル内のすべてのフックをオフにするため、管理設定のPreToolUseフックはもはや何もブロックしません。カスタムステータス行と/goalも機能しなくなります。設定する前にdisableAllHooksを読んでください。disableSideloadFlags: スタートアップで--plugin-dirと--plugin-urlを拒否し、Claude がセッション中に作成した mod の読み込みを防ぎます。設定は--agentsと--mcp-configも拒否します。設定する前にdisableSideloadFlagsを読んでください。
Claude Code に組み込まれた mod(AGENTS.md サポートなど)は、これらの設定の影響を受けません。各 mod には 独自のスイッチ があります。
mod が読み込まれなかったユーザーは、デバッグログで理由を見つけます。拒否メッセージ は allowManagedHooksOnly と disableAllHooks の行を一覧表示し、組み込みガードからのメッセージ は allowManagedModsOnly の行を持っています。
組織の mod のみを許可する
組織の mod を実行し、ユーザーが持ち込む mod をブロックするには、ポリシー表 の 組織の mod のみ の行の設定に加えて、disableSideloadFlags をデプロイします。次の完全な managed-settings.json を使用すると、Claude Code はユーザー独自の mod を拒否するため、そのフックは一切実行されず、ポリシー mod は他の mod より先に実行されます。
{
"extraKnownMarketplaces": {
"acme-tools": {
"source": { "source": "directory", "path": "/opt/acme/claude-plugins" }
}
},
"enabledPlugins": { "acme-guard@acme-tools": true },
"prependPlugins": ["acme-guard@acme-tools", "sec-default@builtin"],
"pluginConfigs": {
"cc-plugin-sec-default@builtin": {
"options": { "allowManagedModsOnly": true }
}
},
"disableSideloadFlags": true
}
キーの各グループは、それぞれ 1 つの役割を担います。
extraKnownMarketplaces、enabledPlugins、prependPlugins: mod を組織のものとしてカウントされるようにインストールし、最初に実行して、その後にガードを実行します。組織の mod をインストールして順序を設定する では、これらのキーが指すディレクトリについて説明しています。pluginConfigs: ガードのallowManagedModsOnlyオプションを設定し、Claude Code がユーザー独自の mod を拒否するようにします。ユーザーの設定フック、ステータスライン、/goalは引き続き機能します。disableSideloadFlags: スタートアップ時に拒否されるフラグについては、disableSideloadFlagsを参照してください
テストマシンでポリシーを確認するには、シェルで claude --debug を使用してセッションを開始し、デバッグログを読みます。
- 組織の mod: その
hooks module行にtier prependが含まれます - ユーザーがインストールした mod:
refused by cc-plugin-sec-default: mods are limited to your organization's by policy (allowManagedModsOnly)という行があります。それより前の行では、その mod のフックモジュールがloadedと表示されるため、拒否の行を探してください。 - プラグインディレクトリ:
claude --plugin-dir ./any-modは、--plugin-dir is disabled by your organization's managed settings (disableSideloadFlags)で始まるメッセージを表示して終了します
ユーザーが追加できるマーケットプレイスも制限するには、このファイルを マーケットプレイス制限 と組み合わせます。
プラグインの制御を mod に適用する
mod はプラグインであるため、組織のプラグインを管理する 方法は、mod を含むプラグインにも適用されます。
- フリート全体でどのプラグインが読み込まれるかを確認する: 監査とレビュー
- レビューしたプラグインをいつ更新できるかを決定する: 更新ポリシーを設定する
- パイロットなど、1 つのグループに異なるポリシーを適用する: 管理設定で強制できないことに備える
- どのアプリとセッションの種類がプラグインキーを適用するかを確認する: 各サーフェスがプラグインキーを適用するタイミング
- CI とコンテナをセットアップする: コンテナと CI をシードする
- ユーザーがインストールできる mod を提供する: マーケットプレイスをホストする。Claude Code が GitHub、git、URL、または npm ソースからコピーする mod は、組織のもの ではなく、ユーザーのものとしてカウントされます。
組み込みガードでオプションを設定する
組み込みガードはオプションを取ります。ユーザーがインストールした mod の読み込みを停止する の例のように、管理設定の pluginConfigs の下に、cc-plugin-sec-default@builtin をキーとして設定します。
表は、各オプションが設定されていない場合と true に設定されている場合にユーザーが取得するものを示しています。
| オプション | 設定されていない | true |
|---|---|---|
allowManagedModsOnly |
ユーザーの独自 mod が読み込まれます | 組織の mod と Claude Code に組み込まれた mod のみが読み込まれます。Claude Code はユーザーがインストールした mod または --plugin-dir で名前を付けた mod を含む他のすべての mod を拒否します。 |
allowModsToOverrideDenyRules |
拒否ルールはユーザーの mod より優先されます | ツール呼び出しを承認するユーザーの mod は、deny ルールが拒否する呼び出しを承認できます |
これらのルールはオプションが有効になるかどうかを決定します。
- ID はここで 1 つのスペルを持ちます: Claude Code はオプションを
cc-plugin-sec-default@builtinの下でのみ読み取ります。prependPluginsはsec-default@builtinも受け入れ、pluginConfigsは受け入れません。 - 管理設定のみがカウントされます: ユーザー、プロジェクト、またはローカル設定ファイル内の同じエントリ、または
--settingsで渡されたファイル内のエントリは、オプションを設定したり、オプションを緩和したりしません - ガードが読み込まれる必要があります:
prependPluginsを設定する場合、リストでガードに名前を付けます。ガードが読み込まれない場所では、どちらのオプションも適用されません。 - ガードは閉じた状態で失敗します: ガードが管理設定を読み取ることができない場合、すべてのユーザーの mod を読み込み時に拒否します。ユーザーの mod が承認した呼び出しの拒否ルールをチェックできない場合、呼び出しを拒否します。
組み込みガードからのメッセージ は、どちらのオプションが適用される場合にユーザーが見るものです。
組織独自の mod を実行する
組織独自の mod をすべてのユーザーにデプロイし、ユーザーの mod との相対的な実行位置を選択し、ポリシーを強制するために使用できます。
組織の mod をインストールして順序を設定する
組織の mod は、ユーザーの mod が読み込まれない状況でも読み込まれ、ユーザーの mod より先に実行できるため、Claude Code は mod が組織から来たものであることを判断できる必要があります。mod が組織のものとして扱われるのは、以下のすべてが当てはまる場合のみです。
- 管理設定の
enabledPluginsが mod のプラグインをtrueに設定している - 管理設定が、プラグインのマーケットプレイスをユーザーのマシン上のディレクトリとして、絶対パスで指定している。
extraKnownMarketplacesエントリはこれを行うと同時に、ユーザー向けにマーケットプレイスの登録も行います。 - マーケットプレイスがプラグインを相対パスでリストしているため、Claude Code はそのディレクトリからプラグインをその場で読み込む
これらを満たすために、デバイス管理でマーケットプレイスディレクトリをすべてのマシンの同じパスにコピーします。ディレクトリとその上位のすべてのディレクトリを、管理設定ファイルと同様に、管理者のみが書き込み可能にします。そこに書き込める人は誰でも mod を書き換えることができます。claude.ai 管理コンソールから配信する管理設定にはキーを含めることができますが、マシンにディレクトリを配置することはできません。
ディレクトリにはマーケットプレイスのマニフェストとプラグインが含まれます。
/opt/acme/claude-plugins/
├── .claude-plugin/
│ └── marketplace.json
└── plugins/
└── acme-guard/
├── .claude-plugin/
│ └── plugin.json
└── hooks/
├── hooks.json
└── register.js
マニフェストはプラグインをそのディレクトリからの相対パスでリストします。
{
"name": "acme-tools",
"owner": { "name": "Acme" },
"plugins": [
{ "name": "acme-guard", "source": "./plugins/acme-guard", "description": "Acme policy mod" }
]
}
Claude Code がキャッシュにコピーするプラグインは、管理設定の enabledPlugins がそれを有効にしている場合でも、ユーザーのものとして扱われます。これには GitHub、git、URL、または npm ソースからのすべてのプラグインが該当します。その mod はユーザーの mod の中で実行され、prependPlugins と appendPlugins はそれをスキップし、allowManagedModsOnly または allowManagedHooksOnly の下では読み込まれません。ユーザーのデバッグログには、プラグインの id と is enabled by managed settings, but で始まる行が記録されます。
Claude Code は、ツールの実行など、アクションを実行しようとするたびにイベントを発生させ、それを順番に各 mod に渡します。組織のものとして扱われる mod は、どこにもリストされていない場合でも、ユーザーの mod の前に実行されます。その位置を設定するには、その id を 2 つの設定のいずれかにリストします。id はプラグインの名前、@、マーケットプレイスの名前をつなげたもので、例えば acme-guard@acme-tools です。
prependPlugins: 組織の mod は、すべてのイベントをどのユーザーの mod よりも前に受け取り、すべての結果を最後に受け取ります。イベントを変更したり、拒否したり、ユーザーの mod をスキップしたりできます。appendPlugins: 組織の mod はすべてのユーザーの mod の後に実行されるため、それらの mod が渡したイベントのみを、渡された形式で受け取ります。
この例では、acme-tools マーケットプレイスを /opt/acme/claude-plugins に宣言し、そこから acme-guard を有効にし、その mod を最初に実行し、その後に組み込みガードを実行します。
{
"extraKnownMarketplaces": {
"acme-tools": {
"source": { "source": "directory", "path": "/opt/acme/claude-plugins" }
}
},
"enabledPlugins": { "acme-guard@acme-tools": true },
"prependPlugins": ["acme-guard@acme-tools", "sec-default@builtin"]
}
各キーはそれぞれ 1 つの役割を持ちます。
extraKnownMarketplaces:acme-toolsマーケットプレイスを保持するディレクトリを指定します。pathは.claude-plugin/marketplace.jsonを含むディレクトリの絶対パスです。enabledPlugins: これらの管理設定を受け取るすべてのユーザーに対してacme-guardをオンにします。prependPlugins:acme-guardを最初に、組み込みガードを 2 番目に配置し、両方ともユーザーがインストールするどの mod よりも前に配置します。Claude Code はリストした順序に従います。
ユーザーのマシンが設定を受け取ったことを確認するには、ポリシーが有効であることを確認するを参照してください。
mod がどこで実行されるかを確認するには、そのマシンで claude --debug を使用してセッションを開始し、デバッグログで mod の id を検索します。
hooks module acme-guard@acme-tools loadedとtier prepend: mod は組織のものとして扱われ、最初に実行されます。- 同じ行に
tier user: Claude Code はそれをユーザーの mod として扱います。2 行目のprependPlugins names acme-guard@acme-tools, which is not an enabled managed plugin with a hooks module; skippedは、リストがそれをスキップしたことを示しています。
以下のルールによって、2 つのリストのどの id が有効になるかが決まります。
- リストはデフォルトを置き換えます: 管理設定で
prependPluginsを設定する場合、組み込みガードを維持するには、そこにsec-default@builtinを指定します。ガードは組み込みのため、enabledPluginsエントリは必要ありません。 - 独自の id は組織のものとして扱われる必要があります: 管理設定では、Claude Code はプラグインが組織の mod の条件を満たさない id をスキップします。
- リポジトリはこれらを設定できません: Claude Code は両方の設定を管理設定から読み取り、リポジトリの設定ファイルからは決して読み取りません。ユーザーが
~/.claude/settings.jsonでこれらを設定して独自の mod の順序を決められるのは、管理設定がないマシンで、かつ Team または Enterprise プランでサインインしていない場合のみです。それ以外の場合、Claude Code はユーザー設定の両方のキーを無視します。そこにあるリストは、組み込みガードを追加も削除もしません。
独自の mod でポリシーを強制する
すべてのユーザーの mod を除外するだけなら、独自の mod は必要ありません。allowManagedModsOnly を設定してください。一部のユーザーの mod を許可して他を拒否したい場合や、mod の動作を記録したい場合は、ポリシー mod を作成します。
別の mod が読み込まれようとするたびに、組織の mod は claude plugin validate が出力するリストを、plugin.register という名前のイベントで受け取ります。prependPlugins 内の mod はそのリストを読み取り、その mod を拒否できます。また、任意の mods API 呼び出しを名前で処理して、他のすべての mod によるその呼び出しを記録または拒否することもできます。名前は $. を除いたメソッドなので、fs.write のフックはすべての $.fs.write 呼び出しを受け取ります。
このポリシー mod は、自身のコードで $.process.run または $.process.spawn を呼び出すユーザーの mod を拒否します。また、監査ログを保持し、各ツール呼び出しと mod が書き込む各ファイルをデバッグログに書き込みます。最初に実行されるため、ログにはユーザーの mod が変更する前の、要求された内容が記録されます。acme-guard/hooks/register.js として保存します。
// The methods no user's mod may call, each spelled namespace.method
const BLOCKED_CALLS = ['process.run', 'process.spawn']
export function register(on) {
// Runs each time another mod is about to load
on('plugin.register', async ($, e, next) => {
// Keep the calls in that mod's code that are on the blocked list
const blocked = e.uses.calls.filter((call) => BLOCKED_CALLS.includes(call))
if (e.tier === 'user' && blocked.length > 0) {
// Returning refuse keeps the mod from loading, and the text is the reason
return { refuse: 'Acme policy: mods may not call ' + blocked.join(', ') }
}
// Let every other mod load
return next(e)
})
// Record each tool call, then let it go ahead unchanged
on('tool.call', async ($, e, next) => {
$.ui.log('audit tool.call ' + e.tool, { to: 'debug' })
return next(e)
})
// Record which mod wrote a file, then the path, quoted because the mod chose it
on('fs.write', async ($, e, next) => {
$.ui.log('audit fs.write by ' + next.origin.plugin + ' ' + JSON.stringify(e.path), { to: 'debug' })
return next(e)
})
}
このファイルは 3 つのフックを登録します。
plugin.register: 別の mod を読み込むかどうかを決定します。ブロック対象のメソッドを呼び出すユーザーの mod を拒否し、他のすべての mod はそのまま通します。tool.call: 各ツール呼び出しについてaudit tool.call Bashのような行をデバッグログに書き込み、何も変更しません。fs.write: 別の mod が行う各$.fs.write呼び出しについてaudit fs.write by reader "/tmp/notes.md"のような行を書き込み、何も変更しません。mod の名前が先頭に来て、パスは引用符で囲まれるため、mod が選んだパスが行の別のフィールドになりすますことはできません。
plugin.register フックはイベントの 2 つのフィールドを読み取ります。
e.tier: mod が実行される位置で、prepend、user、append、builtinのいずれかです。人がインストールする mod はすべてuserです。e.uses.calls: mod が呼び出す mods API メソッドで、それぞれprocess.runのようにnamespace.methodの形式で記述され、claude plugin validateが出力する$.は付きません。
ユーザーが $.process.run を呼び出す mod をインストールすると、その mod は読み込まれず、ユーザーのデバッグログには refused by acme-guard: と指定した理由で終わる行が記録されます。この拒否は、プラグインディレクトリをホットリロードするセッションのトランスクリプトにも表示されます。mod 全体を拒否せずに呼び出しだけをブロックするには、その呼び出しの名前に対するフックから { deny: 'your reason' } を返します。
監査行をデバッグログ以外の場所に送信するには、同じフックから $.http.fetch を呼び出します。
セッションは組織の mod なしで実行される場合があります。インストールされた mod を実行するワーカースレッドが 3 回クラッシュすると、Claude Code は組み込み以外のすべての mod(組織のものを含む)をアンロードし、ユーザーが /reload-plugins を実行するか新しいセッションを開始するまでその状態が続きます。また、--safe-mode で Claude Code を開始したユーザーは、インストールされた mod(組織のものを含む)なしで実行します。
mod に必要なファイルについてはmod を作成するを参照してください。このポリシー mod のテストファイルはポリシー mod をテストするにあります。
チェックが失敗したときに mod を拒否する
plugin.register フックが例外をスローするか時間制限を超えた場合、Claude Code はそのフックをスキップするため、チェックはフェイルオープンとなり、チェック対象の mod は読み込まれます。フェイルクローズにしてユーザーの mod を拒否するには、チェックを名前付き関数に移し、拒否を返す .catch ハンドラーを追加します。このバージョンのファイルは plugin.register フックのみを示しているため、最初のバージョンにある 2 つの監査フックは register 内に残しておいてください。
const BLOCKED_CALLS = ['process.run', 'process.spawn']
// The same check as before, moved into a function of its own
async function checkMod($, e, next) {
const blocked = e.uses.calls.filter((call) => BLOCKED_CALLS.includes(call))
if (e.tier === 'user' && blocked.length > 0) {
return { refuse: 'Acme policy: mods may not call ' + blocked.join(', ') }
}
return next(e)
}
export function register(on) {
// The handler runs only when checkMod throws or exceeds its time limit
on('plugin.register', checkMod).catch(async ($, e, next) => {
// Let your organization's mods and built-in mods load
if (e.tier !== 'user') return next(e)
// Refuse the user's mod that couldn't be checked
return { refuse: 'Acme policy check failed, so this mod was not loaded' }
})
}
ハンドラーを配置すると、チェックが例外をスローするかタイムアウトしたときにチェック中だった mod は読み込まれず、拒否の行には refused by acme-guard: Acme policy check failed, so this mod was not loaded のように 2 番目の理由が記録されます。ハンドラーは user ティア以外のすべての mod を next(e) に渡すため、チェックが失敗しても組織がリストした mod は停止しません。他のイベントでの .catch については失敗するフックを処理するを参照してください。
次のステップ
- プラグインセキュリティ: ユーザーのマシンで任意のプラグインが実行できることと、インストール前にプラグインを確認する方法
- Mod の概要: mod とは何か、フック、スキル、MCP サーバーとの比較
- Mod が実行される順序:
prependPluginsとappendPluginsがユーザーの mod とどのように適合するか - 設定と環境変数: このページで名前が付けられたすべての設定を 1 つの表で