Claude Code サブエージェントの permissionMode を解剖する — 親セッション継承の全ルールと auto モード時代の落とし穴

※本ページはプロモーションが含まれています※

サブエージェントの permissionMode は、単体で読むと意味を取り違える。この設定は「サブエージェントが何を自動承認するか」を決める前に、そもそも有効になるかどうかが親セッションの権限モードで決まる。しかも 2026 年 8 月以降、対話セッションの既定モードが auto に変わったことで、「サブエージェント側で厳しくしておけば安全」という設計が静かに無効化されるケースが増えている。

本稿では、親子関係・ツールフィルタ・バックグラウンド実行・分類器レビューという4つの層を分けて整理し、どの設定がどの層で効くのかを一次情報ベースで追いかける。

1.  親モードが「適用」か「無視」かを決める

公式のサブエージェントページは、継承ルールを次のように説明している。

メイン会話が default、dontAsk、plan モードのとき、サブエージェントはあなたが設定した権限モードで実行される。メイン会話が bypassPermissions、acceptEdits、auto モードのとき、サブエージェントはその同じモードで実行され、Claude Code は frontmatter の permissionMode を無視する。

表にするとこうなる。

親セッションのモード サブエージェントの permissionMode 実務上の意味
default(Manual) 適用される 子側の指定が生きる。締める方向にも緩める方向にも効く
dontAsk 適用される 子側の指定が生きる
plan 適用される 子側の指定が生きる
acceptEdits 無視される(親と同じ) 子を plan にしても編集できてしまう
auto 無視される(親と同じ) 子を default にしても分類器判定になる
bypassPermissions 無視される(親と同じ) 子を default にしても全許可のまま

「親がすでに緩い方向に倒れていると、サブエージェント側で締められない」という非対称性が、この仕様の本質である。締める側の制御は親モードかツール制限に置くしかない。

2. 見落とされやすい2つの例外 — bypassPermissions と auto

「親が default なら子の指定が効く」と覚えると、次でつまずく。Agent SDK の権限ページには、親が default / dontAsk / plan のときの例外が明記されている。

その場合でも、Claude Code は bypassPermissions の値を適用することはなく、auto の値はそのサブエージェントに対して auto モードが利用可能なときにのみ適用する。サブエージェントが bypassPermissions モードで実行されるのは、親セッション自身がそのモードである場合だけである。この bypassPermissions の例外には Claude Code v2.1.267 以降が必要。

整理すると次の3点になる。

  1. 昇格はできない。 親が default の状態で、サブエージェントの frontmatter に permissionMode: bypassPermissions と書いても、その値は適用されない。子が自分で権限を強くすることはできない。
  2. auto は「利用可能なときだけ」。 モデルやプロバイダ、組織設定の条件を満たさないサブエージェントに auto を指定しても効かない。auto モードは「全プラン」だが、モデル条件(Anthropic API なら Opus 4.6 以降、Sonnet 4.6 以降、Haiku 5.5、Fable 系など)と組織条件があり、満たさないセッションでは Manual にフォールバックする。
  3. 降格もできない。 逆向き、つまり親が acceptEdits / auto / bypassPermissions のときに子を厳しくするのは、前述のとおり無視される。

つまりサブエージェントの permissionMode が実際に意味を持つのは、親が default / dontAsk / plan のいずれかで、かつ指定値が bypassPermissions ではないという条件を満たす場合に限られる。

3. 2026年の最大の落とし穴 — 親はもう auto で始まっている

ここが実務上いちばん効く。権限モードのページには、次のように書かれている。

Claude Code v2.1.283 以降、auto モードは対話型ターミナルおよび VS Code セッションの組み込みの開始権限モードである。

そして auto モードの説明にはこうある。

サブエージェントの frontmatter にある permissionMode は無視される。

この2つを重ねると、何も設定していない新しいセッションでは、サブエージェントの permissionMode は既定で無効ということになる。CLI で Shift+Tab を押してモードを確認したとき、ステータスバーが auto mode on になっていれば、あなたが丹精込めて書いた permissionMode: default は読まれていない。

「調査専用サブエージェントを plan にしたのに、なぜか書き込んでいる」「レビュー用を default にしたのに確認が出ない」という症状の多くは、ここに帰着する。

対処の方向性

  • 親側で締める。 厳格さが要件なら、セッション自体を claude --permission-mode default で起動する、または ~/.claude/settings.json の permissions.defaultMode で固定する。auto と bypassPermissions はプロジェクト設定(.claude/settings.json / .claude/settings.local.json)では効かない点にも注意が必要で、auto を既定にしたい場合はユーザー設定側に置く。
  • 子側はツールで締める。 モードが効かない以上、書き込み能力そのものを渡さない tools: Read, Grep, Glob が最も確実な統制になる。これは後述の第5節で扱う。

4. 各モードの実挙動を、親子関係の観点で読む

4-1. default(UI 表記は Manual)

「読み取りのみが確認なしで走る」モード。ファイル編集、シェルコマンド、ネットワークアクセスは基本的に確認を求める。読み取り専用として組み込みで認識される Bash コマンド(ls、cat、grep、find、wc、which、diff、stat、du、cd、git の読み取り系など)はプロンプトなしで実行される。

子側の permissionMode が適用される親モードのひとつなので、「調査専用サブエージェント」「レビュー専用サブエージェント」を作るなら、親を default にしておくのが前提条件になる。ただし、サブエージェントは AskUserQuestion を持てないため、子自身が確認質問を投げることはできない。確認はあくまで「子が起こした操作に対して、親セッション側の権限システムが出すプロンプト」である。

4-2. acceptEdits

読み取りに加えて、ファイル編集と一般的なファイルシステムコマンドが自動承認される。対象は mkdir、touch、rm、rmdir、mv、cp、sed で、LANG=C のような安全な環境変数や timeout、nice、nohup といったラッパーが前置されていても承認される。

ただし自動承認の範囲は作業ディレクトリと additionalDirectories の内側に限られる。範囲外のパス、保護パスへの書き込み、クリティカルパスに対する rm / rmdir は依然としてプロンプトが出る。シンボリックリンクの解決先が範囲外なら、その書き込みも自動承認されない。

親がこのモードのときは、子の permissionMode は無視される。子を plan にしても編集は止まらない。「編集は自動、それ以外のシェルは確認」という親の性質がそのまま子にも及ぶ。

4-3. plan

調査と計画のためのモードで、ソースの編集はブロックされる。ファイルを読み、探索用のシェルコマンドを実行し、計画を書くが、ソースは変更しない。承認するまで編集はロックされたままで、SDK 側の記述では「許可ルールが一致していても plan モードではファイル編集が自動承認されることはない」とされている。

auto モードが利用可能で useAutoModeDuringPlan が有効(既定で有効)なセッションでは、クリティカルパス削除以外のシェルコマンドは分類器がレビューし、承認されたものだけが実行される。auto が使えない場合は、組み込みの読み取り専用セット外のコマンドは承認を求める。

サブエージェント視点で重要なのは、ExitPlanMode はサブエージェントから除去されるツールのひとつだが、サブエージェントの permissionMode が plan のときだけ例外として残るという点。つまり「計画だけさせるサブエージェント」を正しく成立させるには、親モードが default / dontAsk / plan であることに加えて、子側の permissionMode: plan が実際に適用されている必要がある。

4-4. auto

ルーチンのプロンプトを出さずに実行し、代わりに別の分類器モデルがアクションをレビューする。作業ディレクトリと、セッション開始時に設定されていたリモートは信頼され、それ以外は「外部」として扱われる。

サブエージェントに対する扱いは3段階に分かれる。

  1. 起動前: 委譲されたタスク記述そのものが評価され、危険に見えるタスクはスポーン時点でブロックされうる。
  2. 実行中: サブエージェントの各アクションが、親セッションと同じルールで分類器にかけられる。ここで frontmatter の permissionMode は無視される。
  3. 終了時: サブエージェントが作業を終えると、分類器がその作業内容と最終レポートを、親が読む前にレビューする。懸念が検出されると、レポートに警告が前置されて親に渡される。

分類器に送られるリクエストからはツール結果が取り除かれる。ファイルや Web ページに仕込まれた敵対的な内容が分類器を直接操作できないようにするためだ。

auto モードでは、許可ルールの効き方も変わる。auto で開始したセッションは、裸の Bash のような広い許可ルールを落とす。また保護パスへの書き込みは、許可ルールが一致していても分類器に回される。つまり auto 配下では「allow に書いたから自動承認」という前提が崩れる層がある。

分類器が同一アクションを3回連続、または1セッションで20回ブロックすると、auto モードは一時停止して通常のプロンプトに戻る。この閾値は設定できない。-p の非対話実行では、繰り返しブロックされるとプロンプトを出す相手がいないためセッションが中断される。

4-5. dontAsk

本来プロンプトが出る呼び出しを、すべて自動的に拒否する。作業ディレクトリ内のファイル読み取りや、承認が不要なアクションはそのまま実行される。SDK 側では canUseTool が呼ばれない点も明記されている。

このモードが特殊なのは、許可しても拒否されるものがあることだ。AskUserQuestion、ユーザー操作を要求する MCP ツール、ネットワークパスからの読み取り、組織が ask に設定したコネクタツールは、許可ルールがあっても拒否される。CI やスクリプトで「固定された明示的なツール面」を作りたいときの土台になる。

サブエージェント視点では、親が dontAsk のとき子の permissionMode は適用される。ただし子に与える tools を絞らずに dontAsk にしても、期待どおりの「静かな拒否」になるだけで、できることは増えない。

4-6. bypassPermissions

保護パスへの書き込みを含め、ほぼすべてを自動許可する。ただし「どのモードでも自動承認されないもの」は残る。明示的な ask ルールに一致するツール、ユーザー操作が必要なツール、組織が ask に設定したコネクタツール、クリティカルパスに対する rm / rmdir などである。また allow ルールは bypassPermissions では効果を持たない。隔離されたコンテナや VM 向けの設定であり、通常の開発で常用するものではない。

サブエージェントについては、第2節で見たとおりこのモードだけは「親が既にそうである場合のみ」子に伝わる。親が default の状態で子だけ bypassPermissions にすることは、v2.1.267 以降の仕様ではできない。逆に親が bypassPermissions なら、子の frontmatter に何を書いてもその緩さが継承される。これは GitHub の Issue #20264 で「第三者のサブエージェントが意図せず全権限を継承する」として問題提起されている挙動であり、多層防御を設計する際の前提として認識しておく必要がある。

5. モードより手前の層 — tools / disallowedTools という本当の境界

permissionMode が効かない状況でも、ツール制限は常に効く。むしろ「親が auto だからモード指定が無効」という場面では、これが唯一の実効的な統制になる。

  • tools は許可リスト。省略すると「サブエージェントが利用可能な全ツール」を継承する。「ツール無し」ではなく「全部」が既定である点が最大の誤解ポイント。
  • disallowedTools は拒否リスト。両方指定した場合は disallowedTools が先に適用され、残った集合に対して tools が解決される。両方に書かれたツールは除去される。
  • disallowedTools に Bash(git push *) のような指定子を書いても、ツール全体が除去される。特定コマンドだけをブロックしたいなら permissions.deny に Bash(git push *) を書く。このルールは親セッションとサブエージェントの両方に適用される。

サブエージェントが構造的に持てないツール

リストに書いても除去されるものがある。AskUserQuestion、EndConversation、EnterPlanMode、ScheduleWakeup、WaitForMcpServers、Workflow、そして深度制限に達した場合の Agent。ExitPlanMode はサブエージェントの permissionMode が plan のときだけ残る。

このリストの中で実務的に重いのは AskUserQuestion だ。サブエージェントは本質的に「あなたに質問できない」。承認が途中で必要なタスクを委譲すると、確認が取れないまま進むか、失敗するかになる。これは後述のバックグラウンド実行の話と直結する。

バックグラウンド実行時のツール縮小

バックグラウンドで動くサブエージェントには、もう一段のフィルタがかかる。MCP ツールはすべて維持されるが、組み込みツールは Read、Grep、Glob、LSP、Bash、PowerShell、Edit、Write、NotebookEdit、WebFetch、WebSearch、TodoWrite、Skill、ToolSearch、EnterWorktree、ExitWorktree、Monitor、TaskStop、SendMessage、Artifact などに限定される。それ以外は、継承されたものでも tools に列挙したものでも除去される。同じ定義ファイルでも、フォアグラウンドとバックグラウンドで解決されるツールが変わりうる。

6. 確認プロンプトはどこに出るのか — フォアグラウンドとバックグラウンドの分岐

公式ページの記述では、フォアグラウンドのサブエージェントは「権限プロンプトが発生した時点であなたに転送される」。一方、バックグラウンドのサブエージェントについては「セッションで既に付与された権限で実行され、本来プロンプトになるツール呼び出しを自動拒否する」とされている。

ただし、このバックグラウンド側の記述は現行バージョンと一致していない可能性がある。GitHub の Issue #70143 は「v2.1.186 でバックグラウンドサブエージェントの権限プロンプトが自動拒否ではなくメインセッションに表面化するよう変更された。ダイアログにはどのエージェントが要求しているかが表示され、Esc でそのツールだけを拒否できる」と主張し、ドキュメントが古いと指摘している。2026年10月時点の第三者ガイド(Caprock, 2026-10-13)も「バックグラウンドサブエージェントの権限プロンプトはメインセッションに届き、要求元のサブエージェント名が示される。Esc はその1回の呼び出しだけを拒否し、サブエージェント自体は止まらない」と記述している。

この点は自分のインストールしているバージョンで実地確認するのが確実である。確認方法は、権限が必要になる操作(作業ディレクトリ外への書き込みなど)をバックグラウンドで走らせ、プロンプトの有無と表示内容を見るだけだ。設計をドキュメントの一文に依存させないほうがよい。

親コンテキストから複数のサブエージェントへファンアウトし、結論だけが戻ってくる構造を示した図
親から子へ渡るのは委譲プロンプトだけ、子から親へ戻るのは最終メッセージだけ。権限設定もこの細い境界を越えるかどうかが問題になる(出典: Claude Code Subagents and Multi-Agent Orchestration Guide)。

7. Deny / ask ルールは、モードより強い層

モードの上にルールが乗る。評価順は拒否 → 確認 → 許可で、この順序で最初に一致したものが結果を決める。ルールの具体性は順序を変えない。つまり Bash(aws *) の拒否ルールは、より狭い Bash(aws s3 ls) の許可ルールがあってもブロックする。

  • 拒否ルールはすべてのモードでブロックする。bypassPermissions でも例外ではない。モードの設定よりも上位の層だと考えるのが正しい。
  • 許可ルールは bypassPermissions では効果を持たない。
  • 裸のツール名(例: Bash)の拒否ルールは、そのツールを Claude のコンテキストから完全に除去する。セッション途中で追加した場合、次のツール呼び出しから呼べなくなる。スコープ付きの拒否ルール(例: Bash(rm *))はツールを残したまま、一致する呼び出しだけをブロックする。
  • 許可ルールは mcp__<server>__ のリテラル接頭辞がある場合にのみツール名グロブを受け付ける。"*" や "mcp__*" のようなアンカーなしの許可グロブは警告付きでスキップされ、何も自動承認しない。

サブエージェントは親セッションの権限ルールを継承する。したがって「モード指定が無視される状況でも、deny ルールは最後の防波堤として機能する」。子を確実に縛りたいなら、frontmatter のモード指定よりも settings の permissions.deny を先に書くべきである。

8. プラグイン由来サブエージェントの例外

プラグインから読み込まれるサブエージェントは、セキュリティ上の理由で hooks、mcpServers、permissionMode の3フィールドをサポートしない。読み込み時に無視される。もしこれらが必要なら、エージェントファイルを .claude/agents/ または ~/.claude/agents/ にコピーする。あるいは settings.json / settings.local.json の permissions.allow にルールを追加する方法もあるが、こちらはセッション全体に適用され、そのプラグインのサブエージェントだけに限定できない。

プラグイン作者向けには、フックはプラグインの hooks/hooks.json に、MCP サーバーは .mcp.json に置くよう案内されている。プラグインが有効な間ずっと適用され、サブエージェント内だけに閉じない。

9. 目的別の設計パターン

目的 tools permissionMode 親モードの条件と注意
調査のみ Read, Grep, Glob plan または default 親が default / dontAsk / plan であること。auto 親では指定が無視されるので、tools を絞ることが実効的な防御
レビュー Read, Grep, Glob(テスト実行が要るなら Bash を追加) default 確認を出したいなら親も default に。auto 親では分類器判定になる
実装・修正 Read, Write, Edit, Bash, Grep, Glob acceptEdits 親を default にしておく必要がある。親が acceptEdits 以上だと子側の指定は読まれない
完全自律 必要一式 auto または bypassPermissions bypassPermissions は親が既にそのモードでない限り子には適用されない(v2.1.267+)。隔離環境を前提に
CI・厳格実行 許可リストを明示 dontAsk 子側の指定が効く親モード。ただし AskUserQuestion 等は許可しても拒否される

10. ケーススタディで動作を追う

ケースA: 親 default / 子 plan

サブエージェントが Edit を試みると、plan モードのため書き込めず失敗する。子には ExitPlanMode が与えられる(permissionMode: plan の例外)。計画の提示まではできるが、実行は承認後になる。

ケースB: 親 acceptEdits / 子 plan

親が acceptEdits なので子の plan は無視される。編集は自動承認され、そのまま書き換わる。「計画だけさせるつもりだったのに差分が出ている」という事故はこの形で起きる。

ケースC: 親 default / 子 acceptEdits

子の指定が適用され、作業ディレクトリ内の編集と mkdir / mv / cp などが確認なしで実行される。範囲外パス、保護パス、クリティカルパスの削除は依然としてプロンプトが出る。

ケースD: 親 default / 子 default / tools に Write なし

ツール自体が渡されていないので Write は呼べない。permissionMode 以前の問題であり、最も確実な統制。

ケースE: 親 auto / 子 default

子の default は無視され、分類器がアクションを評価する。終了時には作業内容と最終レポートが親に渡る前にレビューされる。厳格にしたいなら親を auto から外すか、tools を絞る。

ケースF: 親 default / 子 bypassPermissions

v2.1.267 以降、この昇格は適用されない。サブエージェントが自分で権限を強めることはできない。親を bypassPermissions にする以外に道はない。

11. 導入前チェックリスト

  1. 親モードを確認したか。 ステータスバーが auto mode on なら、子の permissionMode は読まれていない。厳格さが必要なら --permission-mode default で起動するか、ユーザー設定の permissions.defaultMode を固定する。
  2. 子の統制を tools / disallowedTools に置いたか。 モードが効かない場面でも効く唯一の層。
  3. deny ルールを土台に敷いたか。 deny はすべてのモードで優先される。
  4. プラグイン由来ではないか。 プラグインのサブエージェントでは permissionMode、hooks、mcpServers が読み込み時に捨てられる。
  5. バックグラウンド実行時のプロンプト挙動を実機で確認したか。 ドキュメントの記述とバージョンの挙動がずれている可能性がある領域。
  6. 検証手段を持っているか。 /permissions でルールと出所を確認、/tasks で実行中サブエージェントのモデルと effort を確認、claude --debug で認識されなかった frontmatter フィールドを確認、claude plugin validate で agents ディレクトリの frontmatter を検証。
ターミナルのエージェントビュー。Needs input、Working、Completed のグループに行が並び、上部に入力待ち・作業中・完了の件数が表示されている
エージェントビューでは、複数のバックグラウンドセッションの状態を一覧できる。権限モードはセッションの起動方法に依存するため、どのモードで走っているかを確認する習慣が重要になる(出典: Claude Code「Manage multiple agents with agent view」)。

12. まとめ — 4つの層を分けて考える

サブエージェントの権限は、単一の設定ではなく4つの層の合成で決まる。

  1. 層1: 親セッションのモード。 親が acceptEdits / auto / bypassPermissions なら、子の permissionMode は無視される。ここが最初の関門。
  2. 層2: サブエージェントの permissionMode。 親が default / dontAsk / plan のときのみ意味を持つ。ただし bypassPermissions への昇格はできず、auto は利用可能なときだけ適用される。
  3. 層3: tools / disallowedTools。 モードに関係なく常に効く。省略すると全ツール継承という既定が最大の罠。
  4. 層4: deny / ask / allow ルールとフック。 deny は全モードで最優先。auto 配下では広い allow が落ち、保護パスへの書き込みは allow 一致でも分類器に回る。

「サブエージェント側で厳しくしておけば安全」という設計は、親が auto で始まる現在の既定環境では成立しない。厳格さを求めるなら、親モードを明示的に選び、子には書き込み能力そのものを渡さない。これが2026年時点での現実的な結論である。

そして最後に、設計をドキュメントの一文だけに依存させないこと。バックグラウンドサブエージェントのプロンプト挙動のように、バージョンによって変わる領域が残っている。/permissions と /tasks を眺める習慣が、最も安価な検証手段になる。


 

コメント

タイトルとURLをコピーしました