Agent SDK の権限設定:permissionMode と allowedTools の使い方

Claude Agent SDK エンジニアリング 7分で読めます

Claude Agent SDK で作ったエージェントが、どのツールを確認なしで使ってよいかは権限設定で決まります。この記事では、公式ドキュメント「Configure permissions」に沿って、ツール呼び出しが許可・拒否されるまでの評価順、allowedTools / disallowedTools の効き方、6つの権限モード(permissionMode)の違いを整理します。

とくに「allowedTools に書いたツールだけが使える」という誤解は、bypassPermissions と組み合わせたときに全ツールが自動承認される事故につながります。先に評価の流れを押さえておくと、どの設定がどこで効くのかが分かりやすくなります。

権限が評価される順番

Claude がツールの使用を要求すると、SDK は次の6段階を上から順に確認します。どこかの段階で結論が出れば、それより下には進みません。

  1. フック … まず フックが実行されます。フックは呼び出しをその場で拒否するか、次へ回します。フックが allow を返しても、下の deny ルールと ask ルールは省略されずに評価されます。
  2. deny ルール … disallowedTools(Python では disallowed_tools)と settings.json の deny ルールを確認します。一致すれば、bypassPermissions モードであってもブロックされます。
  3. ask ルール … settings.json の ask ルールに一致すると、bypassPermissions モードでも canUseTool コールバックに確認が回ります。AskUserQuestion のようにユーザーとのやり取りが必要なツールも同様です(dontAsk モードでは確認せずに拒否されます)。
  4. 権限モード … 現在の権限モードを適用します。bypassPermissions ならここで承認、acceptEdits ならファイル操作を承認、plan ならファイル編集やシェルの書き込みを allow ルールに関係なく canUseTool に回します。それ以外のモードでは次へ進みます。
  5. allow ルール … allowedTools(allowed_tools)と settings.json の allow ルールに一致すれば承認されます。作業ディレクトリ内のファイル読み取りや読み取り専用の Bash コマンドのように、ルールなしで承認される呼び出しもこの段階で決まります。
  6. canUseTool コールバック … ここまでで決まらなかった呼び出しは、アプリ側で渡したコールバックが判断します。dontAsk モードではこの段階が飛ばされ、拒否になります。

この順番から分かる重要な点は、途中の段階で自動承認された呼び出しは canUseTool に届かないということです。canUseTool の中に安全チェックを書いても、allow ルールや bypassPermissions で承認された呼び出しには適用されません。どの呼び出しにも必ず実行したい確認は、最初に評価される PreToolUse フックに書くよう公式は勧めています。

なお、rm や rmdir で重要なパス(critical path)を削除する操作は、allow ルールでも bypassPermissions でも自動承認されない例外として扱われます。

allowedTools と disallowedTools

allowedTools と disallowedTools は、上の評価フローの allow ルールと deny ルールに項目を追加するオプションです。書き方によって効き方が変わります。

指定例効果
allowedTools: ["Read", "Grep"]Read と Grep が自動承認される。ほかのツールも引き続き使える。承認が必要な呼び出しは権限モードと canUseTool に回る
disallowedTools: ["Bash"]Bash ツールの定義そのものがリクエストから除かれる。Claude にはツールが見えず、使おうともしない
disallowedTools: ["Bash(rm *)"]Bash は使えるまま、rm * に一致する呼び出しだけがすべてのモードで拒否される(bypassPermissions を含む)
disallowedTools: ["*"]すべてのツール定義が除かれる。deny ルールではツール名のグロブが使え、"mcp__*" はすべての MCP ツールに一致する

つまり allowedTools は「使ってよいツールの一覧」ではなく「確認なしで承認するツールの一覧」です。ツールそのものを使わせたくない場合は、disallowedTools にツール名だけを書きます。

allow ルールでグロブが使えるのは、mcp__<サーバー名>__ という具体的なサーバー名の後ろだけです。mcp__puppeteer__* は puppeteer サーバーの全ツールに一致しますが、allowedTools: ["*"] や ["mcp__*"] のような指定は起動時に警告が出て無視され、何も自動承認しません。

Read と Edit にはパスのパターンを付けられます。Edit(path) ルールは Write や NotebookEdit を含む、ファイルを書き込む組み込みツール全体に効きます。ディスク上の絶対パスを指すときは Edit(//secrets/**) のようにスラッシュを2つ重ねます。スラッシュ1つの Edit(/secrets/**) は、オプションで渡した場合セッションの作業ディレクトリ基準になります。

外部から操作を受け付けない固定的なエージェントにしたいときは、allowedTools と dontAsk モードを組み合わせる例が公式に示されています。

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

この設定では、列挙したツールは承認され、それ以外で確認が必要になる呼び出しは拒否されます。ただし作業ディレクトリ内のファイル読み取りや読み取り専用の Bash コマンドなど、default モードでも確認が要らない呼び出しは、列挙していなくても実行されます。

allow / deny / ask ルールは .claude/settings.json にも書けます。これらは project の設定ソースが有効なときに読み込まれ、query() の既定では有効です。settingSources(setting_sources)を明示的に指定する場合は "project" を含めないと反映されません。

6つの権限モード

権限モードは、ツールの使い方を全体として切り替える設定です。SDK がサポートするモードは次の6つです。

モード動き
defaultモードによる自動承認はなし。承認が必要で allow ルールにも一致しない呼び出しは canUseTool に回る
dontAsk確認が必要になる呼び出しをすべて拒否する。allowedTools やルールで承認されたもの、もともと確認不要なものは実行される。canUseTool は呼ばれない
acceptEditsファイル編集(Edit / Write)と、mkdir・touch・rm・rmdir・mv・cp・sed などのファイル操作を自動承認する。対象は作業ディレクトリと additionalDirectories の中だけ
bypassPermissions確認なしでツールを実行する。deny ルール・ask ルール・フックは先に評価されるので、それらによるブロックは有効。慎重に使う
planソースファイルを編集せずに調査と計画を行う。ファイル編集は allow ルールがあっても自動承認されず、canUseTool で確認される
autoモデルの分類器がシェルコマンドやネットワークリクエストなどの操作を審査し、1件ずつ許可またはブロックする

permissionMode を指定しなかった場合、settings ファイルの permissions.defaultMode があればそれが使われ、なければ組み込みの既定(auto モードになることがある)で始まります。公式は、default モードを前提にしているアプリでは default を明示的に渡すよう案内しています。TypeScript SDK v0.3.286 より前は、省略すると default と同じでした。

bypassPermissions について、TypeScript の型定義では、使うときに allowDangerouslySkipPermissions: true も必要とされています。また Linux と macOS では、認められたサンドボックスの外で root や sudo の下で起動しようとすると拒否され、最初のターンの前にクエリが失敗します。

権限モードの設定と途中変更

権限モードはクエリ開始時に指定するほか、ストリーミング中のセッションで途中から切り替えることもできます。

クエリ開始時に指定する

TypeScript では permissionMode、Python では permission_mode を渡します。途中で変えない限り、セッション全体にそのモードが適用されます。

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Help me refactor this code",
  options: {
    permissionMode: "default"
  }
})) {
  if ("result" in message) {
    console.log(message.result);
  }
}
from claude_agent_sdk import query, ClaudeAgentOptions

async for message in query(
    prompt="Help me refactor this code",
    options=ClaudeAgentOptions(permission_mode="default"),
):
    if hasattr(message, "result"):
        print(message.result)

セッションの途中で変更する

TypeScript では setPermissionMode()、Python では ClaudeSDKClient の set_permission_mode() を呼びます。新しいモードは以降のツール要求すべてにすぐ反映されます。公式は「最初は制限を強くしておき、Claude の進め方を確認してから acceptEdits に切り替える」といった使い方を例に挙げています。

const q = query({
  prompt: "Help me refactor this code",
  options: { permissionMode: "default" }
});

await q.setPermissionMode("acceptEdits");

for await (const message of q) {
  if ("result" in message) {
    console.log(message.result);
  }
}

TypeScript のリファレンスでは、setPermissionMode() はストリーミング入力モードでのみ使えると記載されています。

使い分けと注意点

はまりやすい点

Claude Code 本体(CLI)側の権限モードの選び方は「Claude Code 権限モードの使い分け」、settings.json のルールの書き方は「Claude Code の設定と権限を管理する」も参考にしてください。

本ページは Configure permissions の内容に基づく非公式の日本語解説で、オプションの定義は Agent SDK reference - TypeScript と照合しています(確認日 2026-10-11)。オプション名・モード名は公式表記のまま記載しています。最新の仕様は公式ドキュメントを確認してください。