Claude Media
Agent SDKのパーミッション制御 — モードとallow/denyルール

Agent SDKのパーミッション制御 — モードとallow/denyルール

Agent SDKは6段階の評価フロー(hooks→deny→ask→モード→allow→canUseTool)でツール許可を判定します。モード一覧と設定パターンを解説します。

Agent SDKの権限判定は何が優先されるか

Claudeがツールを呼び出そうとするたびに、Agent SDKは6つのステップを順番にチェックします。まずhooksが実行され、ここで拒否すればそれ以降のステップに進まず即座にブロックされます。次にdisallowed_toolssettings.json由来のdenyルールを確認し、一致すればbypassPermissionsモードであっても遮断されます。ツール名だけを指定したBashのようなdenyルールは、この評価が始まる前にツール定義そのものをClaudeのコンテキストから取り除くため、Bash(rm *)のようなスコープ付きルールだけがこの段階で実際にチェックされます。

3番目がsettings.jsonaskルールで、一致するとbypassPermissionsモードであってもcanUseToolコールバックに処理が渡ります。AskUserQuestionツールや、サーバー側が_meta["anthropic/requiresUserInteraction"]を設定したMCPツールも、allowルールが一致していようと常にこのコールバックに落ちます(ただしdontAskモードでは、コールバックを呼ばずにそのまま拒否されます)。4番目でようやく権限モードが適用され、5番目にallowルール、最後にcanUseToolコールバックという順です。planモードはファイル編集系・シェル書き込み系のツールをallowルールの有無にかかわらずcanUseToolコールバックへ強制的に送るため、計画中に書き込みが自動承認されることはありません。

6つの権限モードは何を自動承認するか

モード説明ツールの挙動
default説明標準の権限動作ツールの挙動自動承認なし。未解決のツールはcanUseToolコールバックへ
acceptEdits説明ファイル編集を自動承認ツールの挙動Edit/Writeとmkdirrmmv等のファイルシステム操作を自動承認
dontAsk説明確認せず拒否ツールの挙動allowed_toolsやルールで事前承認されていない限りすべて拒否。canUseToolは呼ばれない
bypassPermissions説明権限チェックを回避ツールの挙動一部の例外を除きプロンプトなしで実行。取り扱い注意
plan説明計画モードツールの挙動Claudeは調査・計画のみ行い、ソースファイルの編集は自動承認されない
auto説明モデルによる分類ツールの挙動分類器が権限プロンプトを承認・拒否する

acceptEditsが自動承認するのは作業ディレクトリまたはadditionalDirectories配下に限られ、それ以外のパスや保護対象パスへの書き込みは確認を求められます。bypassPermissionsallowed_toolsの内容にかかわらず全ツールを承認しますが、rmrmdirによるクリティカルパス(ファイルシステムのルート、トップレベルディレクトリ、ホームディレクトリ、作業ディレクトリとその親など)の削除だけは対象外で、確認フローに落ちます。

autoモードの分類器は、ルール側で承認・拒否が確定しなかった呼び出しをモデル自身に判定させる仕組みです。リスクの高い操作と分類されれば通常の確認フローへ格上げされ、低リスクと判断された呼び出しは確認なしで進みます。クリティカルパスの削除のように他のモードなら確認を求める操作も、autoモードでは通常のプロンプトの代わりにこの分類器へ送られます。

allow/denyルールの書き方で挙動はどう変わるか

allowed_toolsdisallowed_tools(TypeScriptではallowedTools/disallowedTools)は、この評価フローのallow・denyルール一覧に項目を追加する役割です。書き方によって粒度が変わります。

書き方効果
allowed_tools=["Read", "Grep"]効果ReadGrepを自動承認。ここに無いツールは存在はするが権限モードへ回る
disallowed_tools=["Bash"]効果Bashのツール定義自体を取り除く。Claudeはそのツールを認識すらしない
disallowed_tools=["Bash(rm *)"]効果Bash自体は使えるがrm *に一致する呼び出しはbypassPermissionsでも拒否
disallowed_tools=["*"]効果全ツール定義を除去。"mcp__*"のようなワイルドカードもdenyルールでは有効

allowルールでツール名ワイルドカードが効くのは、mcp__<サーバー名>__というリテラルなプレフィックスの後だけです。サーバー名部分にワイルドカードを含むallowed_tools=["*"]allowed_tools=["mcp__*"]は起動時警告とともに無視され、何も自動承認しません。ReadEditのスコープ付きルールはパスパターンを取り、Edit(path)WriteNotebookEditを含む書き込み系の組み込みツール全般に適用されます。逆にWrite(path)というルールはファイル権限チェックの対象にならない点に注意が必要です。パスの指定は//pathが実ファイルシステムの絶対パス、/pathはルールの取得元(allowed_tools/disallowed_tools経由ならセッションの作業ディレクトリ)を起点にする、という2つのアンカー方式があります。

ツールの範囲を固定したい無人稼働のエージェントには、allowedToolspermissionMode: "dontAsk"を組み合わせる構成が向きます。

const options = {
  allowedTools: ["Read", "Glob", "Grep"],
  permissionMode: "dontAsk",
};

このリストにあるツールだけが承認され、それ以外は確認を挟まず即座に拒否されます。

サブエージェントは親の権限モードをどう引き継ぐか

サブエージェントは既定で親セッションの権限モードをそのまま引き継ぎます。AgentDefinitionpermissionModeフィールドで個別に上書きできますが、例外が3つあります。親がbypassPermissionsacceptEditsautoのいずれかで動いている場合、これらのモードはセッション内の全サブエージェントに強制適用され、サブエージェント単位の上書きは効きません。加えて、組織側の管理設定permissions.disableBypassPermissionsModebypassPermissionsが無効化されている環境では、AgentDefinition側でpermissionMode: "bypassPermissions"を指定してもClaude Codeはこれを無視し、そのサブエージェントは親セッションのモードのまま動きます。サブエージェントの定義自体の設計はAgent SDKのサブエージェント定義にまとめています。

この継承には実務上の注意点があります。サブエージェントは親と異なるシステムプロンプトを持ち、制約の少ない振る舞いをすることがあります。親セッションがbypassPermissionsで動いていれば、その振る舞いの自由度がそのままサブエージェントにも及び、確認なしにシステムへフルアクセスする権限が渡ります。

もう一つ見落としやすいのがcanUseToolコールバックが呼ばれない自動承認のケースです。permissionMode: "bypassPermissions"を設定した構成や、"Read"のようなツール名だけを指定したallowedToolsのエントリは、そのツールをコールバックに渡す前に承認してしまいます。TypeScript SDKはこの状態を検知するとCLAUDE_SDK_CAN_USE_TOOL_SHADOWEDというコードを持つNode.jsのプロセス警告を1回だけ発行します。Bash(ls *)のようなスコープ付きエントリやacceptEditsモードはこの警告の対象外です。モードやルールにかかわらずすべてのツール呼び出しをゲートしたい場合は、canUseToolコールバックではなくPreToolUseフックを使う必要があります。

hooksとcanUseToolコールバックはどう役割分担するか

本記事で扱ったallow/denyルールと権限モードは、6段階の評価フローのうち中間の4ステップです。残る両端——最初のhooksと最後のcanUseToolコールバック——は役割が異なります。

hooksは評価フローの一番手前で動くカスタムコードで、ルールやモードの設定にかかわらずツール呼び出しを拒否・変更できます。PreToolUseフックによる拒否はbypassPermissionsモードでも有効なままなので、「モードや設定がどうであれ絶対に止めたい操作」を扱うにはhooksが唯一の手段です。逆にcanUseToolコールバックは評価フローの最後の砦で、hooks・denyルール・askルール・権限モード・allowルールのどれによっても解決しなかった呼び出しだけがここに届きます。裏を返せば、より前段で自動承認された呼び出しはコールバックに一切現れません。

実行時にユーザーへ都度確認を取りたいだけならcanUseToolで十分ですが、設定やモードの選び間違いを構造的に防ぎたいならPreToolUseフックを併用するほうが安全側の設計です。ルールとモードは「何を自動化するか」を決める層、hooksは「自動化の結果を問わず何を絶対に止めるか」を決める層、と分けて考えると設計がぶれません。

まとめ — モードとルールは別レイヤーとして設計する

Agent SDKの権限制御は、hooks・denyルール・askルール・権限モード・allowルール・canUseToolという6段階の評価フローの上に成り立っています。モードはセッション全体の既定挙動を、allow/denyルールは個々のツールの例外を作る仕組みで、両者は独立したレイヤーです。Claude Code CLIでの権限モデルの変遷はClaude Code権限モデルの変遷、settings.jsonでのルール記法はClaude Code settings.json完全ガイドにまとめています。

よくある質問

allowed_toolsを設定していればbypassPermissionsモードでも安全ですか

安全ではありません。allowed_toolsはbypassPermissionsモードを制約しません。リストに無いツールも権限モードの段階まで落ち、そこでbypassPermissionsがすべて承認してしまいます。特定のツールだけ止めたい場合はdisallowed_toolsを使う必要があります。

canUseToolコールバックは必ず呼ばれますか

呼ばれません。より前の段階(hooks・denyルール・askルール・権限モード・allowルール)で解決した呼び出しはコールバックに届きません。bypassPermissionsモードやツール名だけのallowedToolsエントリがこの状態を作りやすく、TypeScript SDKはCLAUDE_SDK_CAN_USE_TOOL_SHADOWEDという警告コードでこれを知らせます。

dontAskモードでは何が起きますか

事前承認されていない呼び出しはすべて確認なしで拒否されます。canUseToolコールバック自体が呼ばれません。

サブエージェントに個別の権限モードを設定できますか

AgentDefinitionpermissionModeフィールドで可能です。ただし親セッションがbypassPermissionsacceptEditsautoのいずれかで動いている場合はセッション全体にそのモードが強制され、サブエージェント単位の上書きはできません。

settings.jsonの許可・拒否ルールはSDKでも有効ですか

有効です。projectという設定ソースが有効になっているときに読み込まれ、これはquery()の既定オプションでは有効です。settingSourcesを明示的に指定する場合は"project"を含める必要があります。

hooksとallow/denyルールはどちらが先に評価されますか

hooksが先です。hooksの拒否はdenyルールやモードの設定に先立って有効になり、bypassPermissionsモードでも上書きされません。

settings.jsonのルールは評価フローのどのステップに関わりますか

denyルール・askルール・allowルールの3ステップすべてに関わります。settings.jsonはdenyルールとaskルールの定義元であり、allowed_toolsと並んでallowルールの定義元にもなります。1つのファイルが評価フローの3か所に影響するため、設定変更の影響範囲を追うときはこの3ステップを順に確認する必要があります。

planモードでファイル編集を自動承認できますか

できません。planモードはallowルールが一致していてもファイル編集系・シェル書き込み系のツールを必ずcanUseToolコールバックへ送り、確認なしの自動承認を行いません。

この記事を共有:XはてブLinkedIn