Claude Codeの/permissionsコマンドで権限ルールとauto mode拒否を管理する
/permissionsダイアログでallow・ask・denyルールをスコープ別に管理し、auto modeが拒否した操作をRecently deniedタブから再試行する手順をまとめます。
/permissionsは、Claude Codeが使えるツールの許可・確認・拒否ルールを一覧して編集するコマンドです。設定ファイルを直接開かなくても、ダイアログ上でallow・ask・denyの3種類のルールを追加・削除できます。auto modeの分類器が止めた操作を後から見直して再試行する入口でもあります。エイリアスは/allowed-toolsで、どちらを打っても同じダイアログが開きます。
/permissionsのダイアログでできること
/permissionsを実行すると、有効なルールがスコープ(どの設定ファイルに書かれているか)ごとに一覧されます。ここでできる操作は次の5つです。
- ルールをスコープ別に閲覧する(ユーザー設定・プロジェクト設定・管理設定のどれに由来するか)
- allow・ask・denyルールを追加・削除する
- 追加した作業ディレクトリを管理する(
/add-dirで加えたディレクトリの一覧・削除) - auto modeが拒否した操作の履歴を「Recently denied」タブで確認し、再試行を指示する
- auto modeの分類器ルール(
allow・soft_deny・hard_deny・environment)を「Auto mode」タブで編集する
/add-dirで加えたディレクトリからは、Skill・Sub-agent・commandsも読み込まれます。settings.jsonのadditionalDirectoriesで加えたディレクトリは、ファイルアクセス権限だけを広げます。この違いはadditionalDirectoriesは権限だけ拡張するにまとめています。
Claudeが応答している最中でも/permissionsは開けます。v2.1.234以降は、ここで加えた変更が同じターン内の次のツール呼び出しから反映されます。それより前のバージョンは、コマンドがターンの終わりまでキューに積まれていました。
Auto modeタブが出るのはv2.1.246以降で、しかもauto modeが使えるセッションだけです。管理設定と--settingsフラグ由来のエントリは読み取り専用で、タブ上の変更はすべて~/.claude/settings.jsonに保存されます。プロジェクトの設定ファイルには書かれません。
ルールが効く順番と、denyが上書きするもの
ルールは常にdeny→ask→allowの順で評価され、この順序で最初に一致したものが結果を決めます。ルールの詳しさ(specifierの有無)は順序に影響しません。
このため、広い範囲を対象にしたdenyは、より狭いallowを上書きします。たとえばBash(aws *)をdenyに置くと、Bash(aws s3 ls)のallowがあってもすべてブロックされます。「denyの例外だけallowに逃がす」書き方は成立しません。askとallowの間でも同じで、一致したaskルールは、より狭いallowがあってもプロンプトを出します。
ルールの形によって、止まる範囲は大きく変わります。
denyの書き方で何が消えるか
Bash(裸のツール名)
ツールそのものをClaudeの文脈から取り除きます。Claudeはツールの存在自体を認識しなくなり、別の呼び出しで迂回する機会もありません。
Bash(rm *)(specifier付き)
ツールは使えるままで、パターンに一致した呼び出しだけを止めます。rm以外のBashコマンドは通常どおり動きます。
裸のツール名による削除の対象外は、EndConversationだけです。ほかのツールが1つでも残っている限り、このツールを裸のdenyで消すことはできません。ask側も同様で、EndConversationに対してはプロンプトが出ません。
denyとaskには、ツール名の位置にglobを書く形もあります。パターンはツール名全体に一致する必要があり、"mcp__*"と書けばすべてのMCPサーバーのツールをまとめて消せます。この形も裸のツール名と同じく、対象ツールをClaudeの文脈から取り除きます。
PreToolUseフックでもdenyは破れない
フックでdenyを迂回できるかは、権限設計でよく出る疑問です。PreToolUseフックは権限プロンプトの前に走りますが、フックが"allow"を返しても、一致するdenyルールは呼び出しをブロックします。askルールもフックが"allow"か"ask"を返した場合にプロンプトを出します。deny優先の順序が、フックの上にも及ぶ設計です。
ルールの範囲を絞る — コマンド指定とパラメータ一致
ToolまたはTool(specifier)の形で書くと、細かい単位で許可・拒否を分けられます。ターミナルから起動するときは、同じ書式のルールを--allowedToolsと--disallowedToolsに渡すこともできます。claude --helpの説明は「Comma or space-separated list of tool names」(v2.1.285で確認)です。
{
"permissions": {
"allow": ["Bash(npm run *)", "Bash(git commit *)"],
"deny": ["Bash(git push *)"]
}
}Bash(ls *)とBash(ls:*)は同じ意味で、末尾ワイルドカードの書き方が2通りあるだけです。ただし:*の省略形が使えるのは末尾だけです。Bash(git:* push)のようにパターンの途中にコロンを置くと、コロンはただの文字として扱われ、gitコマンドには一致しません。なおダイアログで「Yes, and don't ask again」を選んだときにコマンドの接頭辞として保存されるのは、スペース区切りの形です。
deny・askルールは、ツールの主要な内容以外の入力パラメータの値でも絞り込めます。
| ルール | 一致するもの |
|---|---|
Agent(model:opus) | 一致するものOpusのモデル階層を要求するAgent呼び出し |
Agent(isolation:worktree) | 一致するものgitのworktreeを要求するAgent呼び出し |
Bash(run_in_background:true) | 一致するものバックグラウンドで実行するBash呼び出し |
パラメータ一致には、つまずきやすい約束事が5つあります。
- 1つのルールで指定できるパラメータは1つです。
modelとisolationの両方で絞るなら、2つのルールに分けます *をワイルドカードに使えます。*が無い値は完全一致です- モデルが省略したパラメータには一致しません。
Agent(model:*)は、modelを指定しないAgent呼び出しを捕まえません - 比較対象はClaudeが送った入力そのものです。
Agent(model:opus)は別名のopusには一致しますが、完全なモデルIDには一致しません - ネストしたオブジェクトや配列の中のフィールドは指定できません
実際に何という名前と値で送られているかは、--verboseで起動すると各ツール呼び出しに表示されます。エイリアスと完全なモデルIDのずれは、ルールを書いたのに効かない原因として見落としやすい点です。
一方allowルールは、この形式を使えません。1つのパラメータが一致しただけでは、呼び出し全体の安全性を保証できないためです。Bash(command:rm *)のように主要な内容フィールドを直接狙うルールは、複合コマンドで迂回できるため、起動時に警告付きで無視されます。Bash(rm *)のように書き直します。
auto modeの拒否をレビューして再試行する
auto modeの分類器が止めた操作は、/permissionsの「Recently denied」タブに記録されます。
拒否された操作を再試行する流れ
- 1
拒否の通知を見つける
入力欄の近くに
bash denied by auto mode · [Data Exfiltration] · /permissionsのような通知が出ます。角括弧の中は、分類器が一致させたルールの名前です。 - 2
/permissionsで「Recently denied」タブを開く
分類器が拒否した操作が一覧で並びます。シェルコマンドは、Claudeが付けた説明文の形で表示されます。
- 3
再試行したい操作でrキーを押す
操作が再試行としてマークされます。まだ何も実行されません。
- 4
ダイアログを閉じる
Claudeに再試行を許すメッセージが送られ、会話が再開します。
ダイアログや通知に出るのは、コマンドやURLの全文ではありません。正確な入力が必要なら、PermissionDeniedフックを足すとtool_inputとして受け取れます。会話の中では、呼び出しがRan 3 shell commandsのように畳まれて見えることがあります。その場合はCtrl+Oでトランスクリプトを開くと展開されます。
拒否の原因によって直し方が変わる
| 拒否の原因 | 対処 |
|---|---|
| タスク全体を通じて必要な接続先(パッケージレジストリ・社内ドメイン等) | 対処autoMode.environmentに追加する |
| 今後も確認なしで実行したいコマンド | 対処allowルールを追加する |
| 意図した単発の操作だった | 対処次のメッセージで意図を伝えてClaudeに再試行させる(またはrキーで手動承認して再試行する) |
同じ接続先への拒否が繰り返されるなら、分類器が文脈を把握できていないサインです。autoMode.environmentに対象を足したら、claude auto-mode configで実効設定に反映されたかを確認します。環境エントリやallowルールの追加は、前述のAuto modeタブからも行えます。分類器がどの基準で判定するかはauto mode分類器は何を止めているかにまとめています。
表の「allowルール」には注意が要ります。通常のpermissions.allowと、分類器のautoMode.allowは別のリストです。Bash(npm test)のような狭いpermissions.allowは、auto modeでも分類器が動く前に解決されます。分類器が止めるのは、それでは扱えない呼び出しです。
逆に、Bash(*)や任意コードを実行できるワイルドカード付きインタープリターのような広いルールは、auto modeの間は保留されます。Monitorを名指しするルールも同様です。autoMode.classifyAllShellをtrueにすると、重要なパスの削除を除くすべてのBash・PowerShellのallowルールが保留され、分類器が全コマンドを評価します。
deny・askルールは、分類器より前に適用されます。一致した操作は分類器に渡る前に確定するため、分類器が評価するのはルールをすり抜けた操作だけです。「絶対に実行させたくない操作」を分類器の判断に任せず、管理設定のpermissions.denyに置くのはこのためです。
allowルールを1件ずつ手で足す代わりに、過去の会話履歴を走査して、繰り返し許可しているBashやMCPの呼び出しをsettings.jsonのallowlistへ自動で足すSkillが/fewer-permission-promptsです。仕組みと注意点は/fewer-permission-promptsで許可プロンプトを自動整理するにまとめています。
分類器自体が判定不能だった場合(auto modeとは別の安全チェックが分類器自身のリクエストを拒否した、応答がパースできなかった等)は、拒否が「Recently denied」タブに記録されません。この見分け方とエラーメッセージの読み方は、auto mode安全性判断エラーで扱っています。
手元のclaudeで分類器のルールを確かめる
拒否の通知に出る[Data Exfiltration]のようなルール名は、次のコマンドで全文を読めます。どちらもモデルを呼ばず、ローカルで完結します。以下はv2.1.285で実行した結果です。
claude auto-mode defaults | jq -c 'map_values(length)'
claude auto-mode defaults --label "Data Exfiltration" | jq -c 'map_values(length)'{"allow":17,"soft_deny":70,"hard_deny":1,"environment":21}
{"allow":0,"soft_deny":0,"hard_deny":1,"environment":0}auto modeの既定ルール数(v2.1.285)
allow
17件
softルールへの例外
soft_deny
70件
ユーザーの意図で解除できる
hard_deny
1件
意図でも解除できない
environment
21件
信頼する範囲の定義
Data Exfiltrationはsoft_denyではなくhard_deny側のルールです。会話で意図を伝えても、分類器はこの名前の拒否を解除しません。実行する必要があるなら、Recently deniedタブでrを押して手動承認で再試行するか、auto modeを抜けて確認プロンプトに答えます。--labelは先頭一致のフィルタで、大文字小文字は区別されません。自分の設定を加えた実効値はclaude auto-mode configで出ます。書いたautoModeの内容が、既定ルールと入れ替わったのか合流したのかを確かめる手段になります。
ルールの保存先とスコープ
ダイアログに並ぶルールは、どの設定ファイルに由来するかが行ごとに表示されます。ダイアログで追加したルールは、保存先に選んだ設定ファイルの行に並びます。
「Yes, and don't ask again」で恒久保存を選んだBashコマンドやWebFetchドメインのルールは、gitリポジトリのルートにある.claude/settings.local.jsonに書き込まれます。worktreeで作業していても、メインのチェックアウトへ解決されます。worktreeのサブディレクトリで承認したルールが、リポジトリ全体の将来のセッションに効くということです。
v2.1.211より前は、常に起動したディレクトリへ保存されていました。古いバージョンで保存されたルールは、そのまま起動先のサブディレクトリやworktreeに紐づいて残ります。
ファイル編集の承認は、ルールとして保存されません。セッション終了までの一時的な許可にとどまります。
保存先のファイルと、ルール内のパスの基準は別の話です。ローカル設定のパス付きルール(Edit(/src/**)など)は、ファイルの置き場所ではなく、セッションの主作業ディレクトリを基準にします。worktreeのセッションで共有ルールのEdit(/src/**)を使うと、そのworktree自身のsrc/に一致します。
.claude/settings.local.jsonが信頼確認の対象になる場合もあります。gitで追跡されているファイルや、.claudeがシンボリックリンクの場合は、リポジトリ由来の設定として扱われます。フォルダを信頼するまで、そのルールは保留されます。追跡されていない通常のローカルファイルなら、フォルダ(または親フォルダ)を信頼した時点でallowルールが適用されます。そのファイル専用の信頼確認は求められません。
保存先はリポジトリ単位です。全プロジェクトで共通のルールを配りたいなら、ユーザー設定か管理設定に書きます。設定ファイルの階層と優先順位の全体像はClaude Code settings.json完全ガイドにあります。
権限ルールとサンドボックスは別のレイヤー
/permissionsが管理するルールと、サンドボックスによるOSレベルの制限は、補完関係にある別の防御層です。
どこまでを守る層か
権限ルール
Bash・Read・Edit・WebFetch・MCPなど、ほぼ全ツールが対象です。Claudeが制限されたリソースに手を伸ばすこと自体を止めます。
サンドボックス
対象はBash・PowerShell・Monitorのコマンドとその子プロセスだけです。ファイルシステムとネットワークへのアクセスをOSレベルで制限し、プロンプトインジェクションでClaudeの判断が乗っ取られても、Bashが境界の外へ届くのを防ぎます。
2つの層は、ルールの解釈が交わる場所で挙動が変わります。サンドボックスを有効にしてautoAllowBashIfSandboxedを既定のtrueのままにすると、サンドボックス化されたBashコマンドは、権限設定に裸のBashaskルールがあっても確認なしで実行されます。サンドボックスの境界が、ツール全体へのプロンプトの代わりを務めるためです。
ただしplanモードでは、この代替は働きません。askルールが無ければ組み込みの読み取り専用コマンドは確認なしで動き、それ以外のシェルコマンドは通常の権限フローを通ります。裸のBashaskルールがあれば、サンドボックス化された読み取り専用コマンドを含め、すべてのBashコマンドがプロンプトを出します。この代替がplanモードでも適用されていたのは、v2.1.212より前です。git pushのような範囲付きのaskルールや、明示的なdenyルールも、サンドボックス下で通常の確認フローを通ります。rm・rmdirが重要なパスを対象にする場合も同様です。
もう1つの限界は、denyがコマンド文字列の解析に依存することです。evalやenv -Cで包んだ行は解析の対象から外れ、すり抜けることがあります。条件と対策はClaude Codeの拒否ルールをeval等ですり抜けられる問題と対策にまとめています。
よくある質問
dontAskモードでも/permissionsで許可したツールは使えますか
使えます。dontAskモードは、プロンプトが出るはずの呼び出しを自動で拒否します。ただし/permissionsやpermissions.allowで事前承認したツールは動き続けます。許可していても拒否される例外は次の5つです。
AskUserQuestionrequiresUserInteractionを指定したMCPツール- 組織側で
askに設定されたconnectorツール - 明示的な
askルールに一致する呼び出し - 重要なパスへの
rm・rmdir(allowルールやフックがあっても拒否されます)
古い解説にあるCtrl+Eの説明はまだ使えますか
使えません。確認プロンプトでCtrl+Eを押すとコマンドの説明が出る機能は、v2.1.257で削除されました。無効化用のpermissionExplainerEnabledキーも同時に削除され、v2.1.257以降は設定しても効果がありません。v2.1.256までは、この2つが有効でした。
まとめ
/permissionsは、allow・ask・denyのルールをスコープ別に見渡して、その場で書き換えられる対話的な入口です。auto modeで拒否が続くときは、まず「Recently denied」タブで拒否の名前を確認します。絶対に許したくない操作は、deny、サンドボックス、管理設定のどこで止めるかを先に決めておくと、後から迷いません。