Claude Codeの読み取り専用コマンドが確認なしで通る範囲と例外
lsやgrepなど読み取り専用コマンドは確認なしで通りますが、ワイルドカード・cd・リダイレクトの組み合わせで許可を求められます。原因の切り分け順を示します。
ls・cat・grepなどの読み取り専用コマンドは、許可ルールを書かなくても確認なしで実行されます。この集合はClaude Codeに組み込まれていて、settings.jsonから増減できません。
ただし、コマンド名が読み取り専用でも常に通るとは限りません。引用符なしのワイルドカード、コマンドの組み合わせ、リダイレクトが加わると、Manual modeで許可を求められます。
この集合はManual・acceptEdits・auto・plan・dontAsk・bypassPermissionsに共通の下限です。以下では、確認が出たときの原因を切り分ける順番を中心に書きます。
どのコマンドが確認なしで通るか、設定で変えられるか
Claude Codeが読み取り専用として扱うのは、ls・cat・echo・pwd・head・tail・grep・find・wc・which・diff・stat・du・cdと、読み取り専用の形のgitです。公式ドキュメントはこれを例示として挙げるだけで、完全な一覧は載せていません。そのためgit logやgit showが含まれるかどうかは、名前だけでは断定できません。迷うコマンドは、プロンプトが出るかどうかを実際に見て判断することになります。
集合そのものは設定で変えられません。特定のコマンドにだけ確認を求めたいときは、Bash(find *)のようなaskルールかdenyルールを足します。逆向きは効果がありません。例外条件に当たらない形はもともと確認なしで通るので、allowルールを足しても変わりません。allowが効くのは、npm testやgit commitのような集合の外のコマンドと、引用符なしのグロブを含むfindのように例外条件で確認が出る形の一部です。ルールの書き方と優先順位は/permissionsコマンドで権限ルールとauto mode拒否を管理するで扱っています。
なお「どのモードでも」には但し書きがあります。auto modeでは、分類器のレビューが走る環境で、読み取り専用のコマンドもそのレビューを待ちます。これはv2.1.281の変更です。permissions.blockReadsOutsideWorkingDirectoriesをtrueにすると、作業ディレクトリの外へのReadやGrepなどのファイルツールによる読み取りは、全モードで拒否されます(v2.1.257以降)。ただしシェルコマンドは直接拒否されません。cat ../other/fileのような認識されたファイル読み取りコマンドは、auto modeやbypassPermissionsでも確認が出ます。
読み取り専用コマンドなのに許可を求められる6つの条件
コマンド名が集合に入っていても、Manual modeでは次の6つのどれかに当たるとプロンプトが立ちます。共通点は、コマンド名だけでは副作用や境界越えのリスクを排除できないことです。
Manual modeで確認が立つ6つの条件
引用符なしグロブ
find・sort・sed・gitのように書き込み系や実行系のフラグを持つコマンドは、引用符なしのグロブがあると確認が出ます。グロブが-deleteのようなフラグに展開されうるためです。別のデーモンを指すdocker
-Hや--contextで接続先を切り替えると確認が出ます。Podmanの--urlと--connectionも同じ扱いです。パスを開くfile
-m(--magic-file)と-f(--files-from)は、フラグの値に書かれたパスを実際に開くため確認が出ます。特殊なシェル変数
PATHやIFSなどの特殊なシェル変数を設定・解除する、またはそれでループするコマンドは、残りが読み取り専用でも確認が出ます。v2.1.274で直された挙動です。Windowsのネットワークパス
\\server\share\fileのようなUNCパスは、アクセスするとWindowsの資格情報が相手のホストに送られる可能性があるため確認が出ます。PowerShellツールにも同じ検査があります。解析できないコマンド
完全に解析できないコマンドは、読み取り専用と扱わず承認に回ります。10,000文字を超えるコマンドは解析の上限を超えるため、必ず確認が出ます。
dockerの接続先切り替えは、Claude Codeのサンドボックス設計が扱うネットワーク分離と同じ発想の検査です。
確認が出たときの切り分け手順
プロンプトが出たら、次の順に見ていくと原因を絞れます。
確認が出た読み取り専用コマンドの見方
- 1
区切り文字で分ける
&&・||・;・|・|&・&・改行がコマンドの区切りです。各部分が単独で判定され、1か所でも確認が必要なら全体が確認対象になります。cd packages/api && lsは、両方が単独で読み取り専用なら確認なしで通ります。複合コマンド全体の評価はClaude CodeのBash権限ルールは複合コマンドをどう評価するかにまとめています。 - 2
グロブとフラグを見る
ls *.tsやwc -l src/*.pyは、そのコマンドのフラグがすべて読み取り専用なので通ります。同じ形でもfindやsedには書き込み系のフラグがあり、引用符なしのグロブを含むだけで確認が出ます。グロブを引用符で囲むと、この条件は外れます。 - 3
cdとの組み合わせを見る
作業ディレクトリか追加ディレクトリの中への
cdは、それ自体が読み取り専用です。組み合わせでは2つの型が確認になります。cdで別のディレクトリへ移ってからgitを実行する型は、移動先のgit hookが動く可能性があるためです。移動先が現在の作業ディレクトリに解決されるcdは実質no-opで、確認になりません。cdのあとにリダイレクトが続く型は、リダイレクト先がどのディレクトリ基準で解決されるかを判定できない場合に確認になります。 - 4
リダイレクトの宛先を見る
ls > out.txtのような出力リダイレクトは、宛先へのファイル書き込みとして別に検査されます。対象になるのはEditのallowルールとdenyルール、保護対象パス、作業ディレクトリです。宛先が~で始まる、またはグロブ文字を含むときは確認が出ます。2>/dev/nullだけの場合は、作業ディレクトリに依存しないのでcd app; grep -r pattern . 2>/dev/nullも通ります。判定の主体はコマンドではなく宛先のパスです。 - 5
ルールで解消する
頻繁に出る確認は、正確な形のallowルールで消せます。ただし
Bash(find *)は、-execや-delete付きのfindをカバーしません。その形を通したいときは、コマンド全文に一致するルールを書きます。
入力リダイレクト(< file)の宛先は、v2.1.257以降でReadのルールと作業ディレクトリに照らして検査されます。作業ディレクトリの外を指す宛先は、Readのallowルールで許可していなければ確認が出ます。グロブを含む宛先と、cdのあとの相対パスは、allowルールがあっても確認が出ます。この検査はv2.1.232で入り、v2.1.233でその変更が戻された経緯があります。挙動はバージョンで違うので、古い環境の記事や実測とは食い違うことがあります。
確認を消すルールは、どの単位で保存され何にマッチするか
確認プロンプトで「Yes, and don't ask again」を選ぶと、Bashコマンドのルールはリポジトリのルートにある.claude/settings.local.jsonに保存され、そのリポジトリのどこから始めたセッションにも効きます。複合コマンドを承認したときは、全体を1つのルールにするのではなく、確認が必要だったサブコマンドごとに別のルールが保存されます。たとえばgit status && npm testを承認すると、保存されるのはnpm testのルールです。1つの複合コマンドから保存されるルールは最大5つです。
ルールが何にマッチするかにも決まりがあります。allowルールの照合前には、timeout・time・nice・nohup・stdbufと、シェル組み込みのcommand・builtin、zshのnoglobが取り除かれます。Bash(npm test *)がtimeout 30 npm testにも当たるのはこのためです。フラグなしのxargsも取り除かれるので、Bash(grep *)はxargs grep patternに当たりますが、xargs -n1 grep patternには当たりません。
逆に、npx・docker exec・direnv execのような実行環境のランナーは取り除かれません。Bash(devbox run *)のように広く書くとdevbox run rm -rf .まで通るため、内側のコマンドまで含めてBash(devbox run npm test)と書きます。また、allowルールは既知の安全な環境変数以外の代入をまたいでは当たりませんが、denyルールとaskルールは任意の代入をまたいで当たります。Bash(rm *)をdenyに置けば、FOO=bar rm -rf tmp/も止まります。
プロンプトによっては、1回だけの承認しか選べない場合もあります。保存されるルールが、プロンプトに表示できた範囲だけを対象にするためです。その場合は、1回だけ承認するか、/permissionsでルールを自分で足します。
承認や拒否には、メモを添えることもできます。多くのBashプロンプトでは、YesかNoに合わせてTabを押すとコメント欄が開きます。Yesならコマンドの実行後に、Noなら拒否の理由として、Claudeへコメントが渡されます。コメントなしでNoを選ぶと、メイン会話のプロンプトではそのターンが止まります。「グロブを引用符で囲んで再実行して」のように理由を添えておけば、Claudeが同じ形を繰り返しにくくなります。
モードごとに変わるのは、下限の上に積まれるもの
読み取り専用の集合は全モード共通の下限で、acceptEdits modeでは、その上に書き込み系の自動承認が積まれます。2階建てで捉えると、同じモードの中でlsとrmの扱いが違う理由が説明できます。
acceptEdits modeの2階建て
下限(全モード共通)
ls・cat・grepなど組み込みの集合。settings.jsonでは増減できず、絞りたいときはaskルールかdenyルールを足します。
積み増し(acceptEditsのみ)
mkdir・touch・rm・rmdir・mv・cp・sed。対象は作業ディレクトリとadditionalDirectoriesの中に限られ、LANG=Cのような安全な環境変数やtimeout・nice・nohupが前に付いた形も通ります。
積み増し側にも外れる条件があります。範囲の外のパス、保護対象パスへの書き込み、シンボリックリンクの解決先が範囲外に出る書き込みは確認が立ちます。rmとrmdirが向かう先がcriticalなパスなら、allowルールやPreToolUseフックがあっても承認されません。criticalなパスには、ファイルシステムのルート、ルート直下のディレクトリ(/usr・/etcなど)、ホームディレクトリ、作業ディレクトリとその親が含まれます。
他のモードも同じ形です。plan modeは調査用のモードで、シェルコマンドの扱いは次の3通りのうち最初に当たるもので決まります。bypass permissionsが使える対話ターミナルでは、分類器も確認も入りません。auto modeが使えてuseAutoModeDuringPlanが有効(既定)なら、分類器がシェルコマンドをレビューします。承認されたものは実行され、却下されたものは止まります。criticalなパスへの削除だけは、レビューの対象外です。どちらにも当たらないときは、読み取り専用の集合の外のコマンドで確認が出ます。dontAsk modeは、確認が出るはずの呼び出しを自動で拒否しますが、読み取り専用のBashコマンドやallowルールに一致する操作は動きます。bypassPermissionsは、保護対象パスへの書き込みも含めて確認を省きます。それでも、明示的なaskルール、criticalなパスを狙うrm・rmdir、blockReadsOutsideWorkingDirectoriesが有効なときの作業ディレクトリ外の読み取りは、どのモードでも自動承認されません。
確認が頻発するのがモードの問題なら、切り替えも選択肢です。ManualとacceptEditsのBashプロンプトには、auto modeが使える環境で「Yes, and switch to auto mode」が加わります。選ぶとそのコマンドを承認したうえで、セッションがauto modeに切り替わります(v2.1.247以降)。Shift+Tabでもモードを順に切り替えられ、ステータスバーには⏸ manual mode onや⏵⏵ accept edits onのように現在のモードが出ます。dontAsk modeはこの巡回に入らず、--permission-mode dontAskでだけ指定します。
v2.1.285で確認できたこと
手元のv2.1.285でヘルプを見ると、--permission-modeの選択肢はmanualを含む6つでした。記事内で使う「Manual mode」は、このmanualに当たります。出力は次のとおりです。
claude --version
claude --help | sed -n '/--permission-mode/,/--permission-prompts/p'2.1.285 (Claude Code)
--permission-mode <mode> Permission mode to use for the session
(choices: "acceptEdits", "auto",
"bypassPermissions", "manual",
"dontAsk", "plan")一方、--helpの出力には読み取り専用コマンドの一覧も、集合を変えるオプションも出ません。集合の中身を実行前に確かめる公式の手段は見当たらないため、git logのような迷うコマンドは、実際にプロンプトが出るかどうかで確かめるのが確実です。ヘルプに出る選択肢は起動時に選べるモードの名前だけで、各モードが実際に何を承認するかは、ここまでの公式ドキュメントの記述に頼る形になります。
まとめ
確認が出たら、まず区切り文字でコマンドを分け、どの部分が引っかかったかを見ます。自動化を組むときは、findやsedへ渡すグロブを引用符で囲み、cdのあとのgitやリダイレクトを避けると確認が減ります。集合そのものは変えられないので、通したい形はallowルールで、止めたい形はaskルールかdenyルールで調整します。