Claude Media
Claude Codeのalways allowが効かない原因と対処法

Claude Codeのalways allowが効かない原因と対処法

許可プロンプトで「常に許可」を選んでも聞かれ続ける現象には、保存期間の違いやdeny/ask/allowの評価順、auto modeの仕様など複数の原因が重なっています。切り分け方を書き出しました。

Claude Codeで許可プロンプトの「常に許可」を選んでも、同じ操作で再び確認を求められるという報告があります。GitHub Issue #11380には同様の症状が20件以上のコメントで寄せられており、書き込んだ設定ファイルを見直しても原因が分からず、設定をbypassPermissionsに切り替えて凌いだという報告も出ています。公式ドキュメントを突き合わせると、この症状には少なくとも6つの独立した原因があり、それぞれ挙動も対処法も異なります。

ファイル編集の「常に許可」はセッション終了までしか保存されない

Claude Codeの許可プロンプトは、ツールの種類によって「常に許可」を選んだときの保存期間が違います。

ツールの種類承認が必要か「常に許可」の保存期間
ファイル読み取り(Read、Grepなど)承認が必要か作業ディレクトリ内なら不要「常に許可」の保存期間該当なし
Bashコマンド承認が必要か必要(組み込みの読み取り専用コマンドを除く)「常に許可」の保存期間リポジトリ単位・コマンド単位で永続
ファイル編集(Edit・Write)承認が必要か必要「常に許可」の保存期間セッション終了まで
WebFetch承認が必要か必要(事前承認済みドキュメントドメインを除く)「常に許可」の保存期間リポジトリ単位・ドメイン単位で永続
WebSearch承認が必要か必要「常に許可」の保存期間リポジトリ単位で永続

ここが最初の見落としどころです。BashコマンドとWebFetchのドメイン許可は.claude/settings.local.jsonallowルールとして書き込まれ、次回以降のセッションでも有効になります。一方でファイル編集の承認は仕様上セッションをまたいで保存されません。新しいセッションを開始するたびに同じファイルの編集で確認を求められるのは、多くの場合バグではなく、この保存期間の違いによる想定どおりの動作です。

許可ルールはdeny→ask→allowの順で評価され、allowは最後に見られるだけ

Claude Codeの許可ルールは、範囲の広さに関係なく「deny、次にask、最後にallow」という固定順で評価されます。最初に一致したルールが結果を決めるため、.claude/settings.local.jsonに保存した具体的なallowルールがあっても、プロジェクト設定や組織の管理設定に同じ呼び出しへのaskルールがあれば、そちらが常に優先されます。「常に許可」を選んだのに次から確認される場合、まずはどこかに競合するaskルールやdenyルールが無いかを疑う必要があります。

/permissionsコマンドを実行すると、現在有効な全ルールと、それぞれがどの設定ファイルに由来するかが一覧表示されます。競合ルールの切り分けにはここから始めるのが確実です。

/permissions

Issue #11380のコメント欄には、settings.json"Bash(:*:*)"という許可ルールを書いたが効かなかったという報告もありました。Bashルールのワイルドカードは、末尾に空白付きの*を置くBash(npm run *)の形か、それと同等なBash(npm run:*)の形で書きます。コロンは末尾のワイルドカードとしてのみ特別扱いされ、Bash(git:* push)のように途中に置くと文字どおりのコロンとして扱われ一致しません。全てのBashコマンドを一括で許可したいだけなら、パラメータを付けず"Bash"とだけ書く方がシンプルで、コマンド名の位置を誤読するリスクもありません。

サブエージェントは呼び出し元と別の権限モードで動くことがある

Issueには「特定のサブエージェントを使えば設定した許可が効くのに、汎用のサブエージェントが起動すると再び聞かれる」というコメントがありました。これは公式ドキュメントの仕様と一致します。

サブエージェントのpermissionModeは、呼び出し元(メイン会話)のモードによって扱いが変わります。メイン会話がbypassPermissionsacceptEdits・auto modeのいずれかで動いている場合、サブエージェントもそのモードを継承し、サブエージェント側で個別に設定したpermissionModeは無視されます。一方メイン会話がdefault(Manual)・dontAskplanモードのときは、サブエージェントは自分自身のpermissionModeで動きます。汎用サブエージェント(名前を指定せず起動するタイプ)に許可モードを明示していなければ、メイン会話とは別の挙動になり得るということです。

さらにバックグラウンドで動くサブエージェントには、v2.1.186より前のバージョンで「本来プロンプトが出るはずのツール呼び出しを、確認画面を出さず自動拒否する」という挙動がありました。許可したはずの操作がバックグラウンドのサブエージェントだけ黙って弾かれる現象は、この時期のバージョンでは既知の制限だったことになります。

auto modeでは危険な広域allowルールが起動時に自動で外れる

Pro・Max・Teamプランでは、Claude Codeはauto mode(バックグラウンドの分類器がツール呼び出しを審査するモード)で起動するのが既定です。auto modeに入ると、任意のコード実行を許してしまう広範なallowルールは安全側の判断でセッションから一時的に外されます。対象になるのは次のようなルールです。

  • Bash(*)PowerShell(*)のような無条件のallowルール
  • Bash(python*)のようなワイルドカード付きインタプリタ呼び出し
  • パッケージマネージャのrunコマンド
  • Agentの許可ルール

Bash(npm test)のような具体的なコマンド名のルールはそのまま残ります。auto modeを抜ければ外れたルールは復元されるため、消えたわけではありません。以前のバージョンでBash(*)のような広いallowルールを設定していた利用者が、auto modeが既定になったバージョンへアップデートした後に「効かなくなった」と感じるケースは、この仕様変更が原因である可能性があります。

auto mode下ではサブエージェントの扱いも変わります。サブエージェントが開始する前にタスクの内容そのものが分類器の審査対象になり、実行中の各ツール呼び出しもメイン会話と同じ規則で分類器を通ります。この間、サブエージェント側のfrontmatterに書いたpermissionModeは無視されます。つまりauto modeの利用者にとっては、サブエージェントごとに個別の許可モードを設定しても、その設定自体が読まれていないケースがあるということです。

保存したBashルールは呼び出し方が違うコマンドには一致しない

Bashの許可ルールはコマンド文字列そのものをパターンマッチしているだけで、実行される実体を見ているわけではありません。そのため「昨日は聞かれなかったのに今日は聞かれる」という報告の中には、Claudeが前回と少し違う形でコマンドを組み立てただけというケースも混じります。Bash(curl *)というdeny/askルールはcurl https://example.comは止めますが、/usr/bin/curl https://example.comsh -c 'curl https://example.com'のようにパスやシェル経由で呼ばれた場合は文字列が一致せず素通りします。同じことがallowルールにも起きます。Bash(git push *)を許可していても、git -C . push origin mainのように別の書き方でClaudeがコマンドを組み立てると、ルールが一致せず改めて確認を求められます。

コマンドの前に付くtimeouttimenicenohupstdbuf、シェル組み込みのcommandbuiltin、zshのnoglobは、マッチングの前に自動で取り除かれます。そのためBash(npm test *)というルールはtimeout 30 npm testにもそのまま一致します。一方でdirenv execdevbox runnpxdocker execのような環境ランナーは、この除去対象に含まれていません。Bash(devbox run *)のようなルールは、devbox runの後ろに続く任意のコマンドへ広がってしまいます。逆に少し書き方を変えただけの呼び出しには一致しないこともあり、狭すぎる面と広すぎる面が同居します。

複合コマンドを承認した際に保存されるルールにも上限があります。1つの操作につき最大5個までしか保存されません。パイプやリダイレクトを多用する長いコマンドでは、一部のサブコマンドだけ承認が保存されず、翌回に確認が復活することもあります。

worktreeやリポジトリ外では保存先がずれることがあった

Bashコマンドの「常に許可」は.claude/settings.local.jsonに書き込まれますが、v2.1.211より前のバージョンでは、この保存先が常にセッションを開始したディレクトリでした。そのためworktree(同じリポジトリを複数の作業ツリーとして並行チェックアウトする機能)やサブディレクトリで許可した内容が、リポジトリの他の場所を対象にしたセッションには反映されませんでした。v2.1.211以降はworktreeをメインのチェックアウトへ解決し、リポジトリ単位でルールを共有するよう変更されています。

もう一つ見落としやすいのが、コミット済みの.claude/settings.jsonに書かれたpermissions.allowルールです。このルールは各メンバーがそのフォルダを信頼(workspace trust)するまで有効になりません。手動でsettings.jsonを編集してallowルールを追加しても効かず、defaultModebypassPermissionsにしたときだけ効いたという報告は、信頼済みでないフォルダでこの仕組みに引っかかっていた可能性があります。gitで追跡されていない個人用の.claude/settings.local.jsonはこの信頼ステップを必要としません。

症状から原因を切り分ける早見表

症状考えられる原因確認・対処
ファイル編集だけ毎回聞かれる考えられる原因仕様どおり(編集承認はセッション限り)確認・対処Bash・WebFetchの永続承認と混同していないか確認する
Bashコマンドが「常に許可」後も聞かれる考えられる原因別の設定ファイルに競合するask/denyルールがある確認・対処/permissionsでルールの出所を確認する
広めのBashルールが急に効かなくなった考えられる原因auto modeへ移行して広域allowルールが外れた確認・対処Bash(npm test)のような具体的なルールへ書き換える
同じコマンドのはずなのに時々聞かれる考えられる原因呼び出し方の違い(パス指定・シェル経由・別の書き方)でルールが一致していない確認・対処許可プロンプトに表示されたコマンド文字列を、保存済みルールと突き合わせる
汎用サブエージェントだけ聞かれる考えられる原因サブエージェントが呼び出し元と別のpermissionModeで動いている確認・対処サブエージェント定義にpermissionModeを明示するか、メイン会話のモードを確認する
worktreeや未信頼のフォルダで反映されない考えられる原因v2.1.211より前の保存先の仕様(起動ディレクトリ単位)、またはworkspace trust待ち確認・対処Claude Codeをアップデートするか、フォルダを信頼する。個人用のsettings.local.jsonに移すのも有効

.claude/settings.local.json.claude/settings.jsonの使い分け、許可ルールの書き方の基礎はClaude Code settings.json完全ガイドにまとめています。組織側で許可ルールを管理設定に限定している場合の挙動はallowManagedPermissionRulesOnlyで権限ルールを管理設定だけに縛る、WebFetchのドメイン単位の許可ルールの書式はClaude Code WebFetch権限ルールで扱っています。

まとめ

「always allowを選んでも聞かれ続ける」という一つの症状の裏には、ファイル編集承認の保存期間・deny/ask/allowの評価順・コマンド文字列の一致条件・サブエージェントの権限モード継承・auto modeの広域ルール除外・保存先ディレクトリの仕様という、少なくとも6つの異なる仕組みが関係しています。GitHub Issueのコメント欄でも原因の異なる報告が一つのスレッドに集まっており、同じ対処法が全員に効くわけではありません。まずは/permissionsで実際にどのルールがどこから効いているかを確認し、上の早見表で自分の症状に近いものから切り分けるのが近道です。過去に許可した操作を洗い出してsettings.jsonのallowlistへまとめて反映したい場合は、/fewer-permission-promptsで許可プロンプトを自動整理するも参考になります。

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