何のためのものか
Agent SDK でツール使用の許可・拒否を制御する仕組み。パーミッションモード、allow/deny ルール、canUseTool コールバックの 3 つを組み合わせて決める。
触る
まず 2 つのオプションを渡してみる。
| オプション | 効果 |
|---|---|
allowed_tools=["Read", "Grep"] | 自動承認。他のツールはモードと canUseTool へフォールスルー |
disallowed_tools=["Bash"] | ツール定義自体を除去する。 Claude からは見えない |
disallowed_tools=["Bash(rm *)"] | Bash は使えるが、一致する呼び出しは全モードで拒否 |
ベアネームの deny は定義ごと消し、スコープ付きの deny は呼び出しだけを止める。 この違いが分かると設計が変わる。
入れる
モードを選び、残りを canUseTool で処理する。
| モード | ツールの挙動 |
|---|---|
default | 自動承認なし。未解決のツールは canUseTool へ |
dontAsk | 事前承認されたもの以外は拒否。canUseTool は呼ばれない |
acceptEdits | 作業ディレクトリ内のファイル編集とファイルシステム操作を自動承認 |
plan | ファイル編集は自動承認されず canUseTool へ |
bypassPermissions | プロンプトなしで実行(critical path の rm / rmdir 等は例外) |
auto | モデル分類器が承認・拒否を判定 |
ロックダウンしたいなら allowed_tools に read 系だけを並べて permissionMode: "dontAsk" にする。
効かせる
評価順を覚える。 ここを外すと「書いたルールが効かない」になる。
- Hooks(
PreToolUse)— 拒否するか次へ渡す。allowを返しても deny/ask の評価はスキップされない - Deny ルール — 一致したらブロック(
bypassPermissionsでも) - Ask ルール — 一致したら
canUseToolへ(bypassPermissionsでも)。dontAskでは deny - Permission mode
- Allow ルール — 一致したら承認
canUseToolコールバック — ここまでで解決しなかったときに呼ばれる
- subagent は親のパーミッションモードを継承する。
AgentDefinitionのpermissionModeで上書きできるが、bypassPermissions/acceptEdits/autoは上書き不可 - パスのスコープは
Edit(path)が全ファイル書き込みツールに適用される。Write(path)ルールは単独ではマッチしない
落とし穴
- critical path を対象とする
rm/rmdirは、allow ルールでも hook のallowでも承認されない allowed_tools=["*"]や["mcp__*"]は無視され、起動時に警告が出る。 allow のグロブはmcp__<server>__の後ろにしか置けないcanUseToolが実質スキップされる構成では警告が出る(TypeScript SDK のCLAUDE_SDK_CAN_USE_TOOL_SHADOWED)。permissionMode: 'bypassPermissions'とベアネームのallowedToolsエントリの組み合わせで起きるdontAskでは、事前承認済みでも拒否されるものがある(ユーザー操作を要求するツール、組織が ask に設定した connector ツール)