Claude Code の settings.json で deny を設定した場合の挙動を rm で試してみた
コーヒーが好きな emi です。
Claude Code の settings.json には、コマンドの実行を禁止する deny という権限ルールがあります。詳しい仕組みは以下公式ドキュメントに書かれています。
deny に rm を入れてちゃんんとブロックされるか、rm に類似するコマンドは実行できてしまうのか、Claude Code on Amazon Bedrock で実際に試しました。
先に結論
1. deny 指定コマンドのブロック
deny に Bash(rm:- ) を入れた状態で「target.txt を rm で削除して」と依頼したところ、rm の実行は拒否され、ファイルは残った
2. 評価順(deny 最優先)
allowとdenyの両方にBash(rm:- )を入れた状態でも、rmはブロックされた- 評価順は
deny→ask→allowでdenyが最優先のため、allowに書いてもdenyが優先される
- 評価順は
3. 類似コマンドの挙動
denyをBash(rm:*)にしたまま、find ~/work/test -name target.txt -deleteで削除を依頼Bash(rm:*)に一致しないためdenyではブロックされない- ファイルがそのまま削除されるかどうかは権限モードとファイルの中身によって左右される
動作環境
- Claude Code v2.1.248(Amazon Bedrock 経由、Sonnet 4.6)
- WSL 上の Ubuntu
- 検証ディレクトリは
~/work/test
私の検証環境は以下ブログで紹介しています。
検証すること
denyに入れたコマンドが実行前にブロックされることdeny→ask→allowの評価順でdenyが最優先になることdenyはコマンド文字列に対する一致なので、言い換えた類似コマンドはブロックされない
手順1 検証用のファイルを作る
テスト用ファイルを作成します。
echo "dummy" > ~/work/test/target.txt
手順2 検証用の settings.json を用意する
プロジェクトスコープ(.claude/settings.json)で試します。~/work/test/.claude/settings.json に rm を deny で入れました。
{
"permissions": {
"deny": [
"Bash(rm:*)"
]
}
}
手順3 deny でブロックされるか確認する
~/work/test を作業ディレクトリにして Claude Code(on Bedrock)を起動し、次のように依頼しました。
target.txt を rm で削除して
結果は以下のようになりました。

▐▛███▛█ Claude Code v2.1.248
▝▜██████▀ Sonnet 4.6 · Amazon Bedrock
▝▝ ▝▝ ~/work/test
❯ target.txt を rm で削除して
Thought for 5s, ran 1 shell command
Bash の実行が拒否されました。ツール権限の設定を確認して、rm コマンドが許可されているか見直してください。
✻ Churned for 8s · done 11:48 AM
✘ Auto-update failed · Try claude doctor or npm i -g @anthropic-ai/claude-code
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
❯
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
⏸ manual mode on · ? for shortcuts · ← for agents · shift+click to native select
拒否されました。ファイルが残っているかも確認します。
emiki@<hostname>:~/work/test$ ls target.txt
target.txt
emiki@<hostname>:~/work/test$
残っています。deny に入れた rm は、期待どおり実行前にブロックされました。
手順4 評価順(deny 最優先)を確認する
次に、allow に同じコマンドを入れても deny がの方が優先されることを確認します。settings.json を以下のように変えます。
{
"permissions": {
"allow": [
"Bash(rm:*)"
],
"deny": [
"Bash(rm:*)"
]
}
}
この状態で ~/work/test を開くと、起動時に以下信頼確認の画面が出ました。おや?
emiki@<hostname>:~/work/test$ claude-bedrock
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Accessing workspace:
/home/emiki/work/test
Quick safety check: Is this a project you created or one you trust? (Like your own code, a well-known open source project, or work from your team). If not, take a
moment to review what's in this folder first.
Claude Code'll be able to read, edit, and execute files here.
⚠ This folder pre-approves 1 tool permission in .claude/settings.json:
Bash(rm:*)
These will apply without asking. Only proceed if you trust this configuration.
Security guide
❯ No, continue without these permissions
Yes, I trust this folder
Enter to confirm · Esc to cancel
「.claude/settings.json に確認なしで実行される権限が1件ある」という警告です。allow に rm が入っているので、そのまま信頼すると rm 系は確認なしで実行される、と書かれています。
Yes で進めると rm が実行されてしまうのか?
一旦 Yes で進めます。
同じように削除を依頼します。

▐▛███▛█ Claude Code v2.1.248
▝▜██████▀ Sonnet 4.6 · Amazon Bedrock
▝▝ ▝▝ ~/work/test
❯ target.txt を rm で削除して
Thought for 3s
target.txt を削除する前に存在確認します。
Listed 1 directory
ファイルが存在します。削除します。
Ran 1 shell command
Bash での rm の実行が拒否されました。権限設定で rm が許可されていない可能性があります。ターミナルで直接 rm /home/emiki/work/test/target.txt を実行するか、Claude Code の設定で rm を許可してください。
✻ Cogitated for 8s · done 11:57 AM
✘ Auto-update failed · Try claude doctor or npm i -g @anthropic-ai/claude-code
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
❯
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
⏸ manual mode on · ? for shortcuts · ← for agents · shift+click to native select
止まりますね。
allow に書いてあっても、rm はブロックされました。評価順が deny → ask → allow で、deny が最優先という仕様のとおりです。
手順5 類似コマンドの挙動を確認する
deny を Bash(rm:*) にしたまま、rm を使わない書き方で同じ削除を依頼しました。
find ~/work/test -name target.txt -delete で target.txt を消して
rm を使っていないので Bash(rm:*) には一致しません。ある回では、実行前に確認プロンプトが出ました。

▐▛███▛█ Claude Code v2.1.248
▝▜██████▀ Sonnet 4.6 · Amazon Bedrock
▝▝ ▝▝ ~/work/test
❯ find ~/work/test -name target.txt -delete で target.txt を消して
● Deleting target.txt files under ~/work/test
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Bash command
find ~/work/test -name target.txt -delete
Delete target.txt files under ~/work/test
│ find with '-delete' executes commands or modifies files — cannot be auto-allowed by a Bash(find:*) prefix rule
Do you want to proceed?
❯ 1. Yes
2. No
Esc to cancel · Tab to amend · ctrl+e to explain
Yes を選択
▐▛███▛█ Claude Code v2.1.248
▝▜██████▀ Sonnet 4.6 · Amazon Bedrock
▝▝ ▝▝ ~/work/test
❯ find ~/work/test -name target.txt -delete で target.txt を消して
Thought for 2s, searched for 1 pattern
完了しました。~/work/test 以下の target.txt を削除しました。
✻ Brewed for 4s · done 5:13 AM
● high · /effort
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
❯
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
⏸ manual mode on · ? for shortcuts · ← for agents · shift+click to native select
deny には一致しないので、この確認プロンプトは deny が出したものではありません。
観測したログ
find ~/work/test -name target.txt -delete を、モードやモデル、ファイルの中身を変えて試します。
これまでの検証は manual モード(Sonnet 4.6)でした。
auto モード(Opus 4.8)ファイル中身が dummy
auto モード(Opus 4.8)では、確認プロンプトなしでそのまま削除されました。
▐▛███▛█ Claude Code v2.1.248
▝▜██████▀ Opus 4.8 · Amazon Bedrock
▝▝ ▝▝ ~/work/test
❯ find ~/work/test -name target.txt -delete で target.txt を消して
まず消す対象を確認します。
Searched for 1 pattern, read 1 file
1件だけ見つかりました(/home/emiki/work/test/target.txt、中身は dummy の1行)。削除します。
Searched for 1 pattern
削除しました。/home/emiki/work/test/target.txt(中身は dummy の1行)1件のみ対象でした。
✻ Baked for 14s · done 5:09 AM
✘ Auto-update failed · Try claude doctor or npm i -g @anthropic-ai/claude-code
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
❯
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
⏵⏵ auto mode on (shift+tab to cycle) · ← for agents · shift+click to native select
auto モード(Opus 4.8)ファイル中身に重要な内容を記載
target.txt のファイルの中身を変えます。
ここには業務上重要な内容を書きます。
auto モード(Opus 4.8)のまま、また削除指示を出します。
▐▛███▛█ Claude Code v2.1.248
▝▜██████▀ Opus 4.8 · Amazon Bedrock
▝▝ ▝▝ ~/work/test
❯ find ~/work/test -name target.txt -delete で target.txt を消して
まず消す前に対象を確認します。
Searched for 1 pattern, read 1 file
削除前に中身を確認したところ、想定と違う内容でした。
対象は1件、/home/emiki/work/test/target.txt。中身はこうなっています。
ここには業務上重要な内容を書きます。
target.txt という名前だけ見ると使い捨てのファイルに見えますが、中身は「業務上重要な内容」と書かれています。私が作ったファイルでもありません。このまま -delete で消してよいか確認させてください。
- 消してよいなら、そのまま実行する
- 中身を残したいなら、先に別名でコピーしてから消す、など
どうしますか。
✻ Baked for 17s · done 5:30 AM
✘ Auto-update failed · Try claude doctor or npm i -g @anthropic-ai/claude-code
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
❯
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
⏵⏵ auto mode on (shift+tab to cycle) · ← for agents · shift+click to native select
manual モード(Opus 4.8)ファイル中身が dummy
target.txt のファイルの中身を変えます。
dummy
Shift + Tab で manual モード(Opus 4.8)に変更し、削除指示を出します。
▐▛███▛█ Claude Code v2.1.248
▝▜██████▀ Opus 4.8 · Amazon Bedrock
▝▝ ▝▝ ~/work/test
❯ find ~/work/test -name target.txt -delete で target.txt を消して
まず対象を確認してから消します。
Searched for 1 pattern, read 1 file
中身は dummy の1行だけで、消して問題なさそうです。削除します。
Deleting target.txt files
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Bash command
Tip: auto mode handles these prompts for you — choose "switch to auto mode" below
find ~/work/test -name target.txt -delete
Delete target.txt files
│ find with '-delete' executes commands or modifies files — cannot be auto-allowed by a Bash(find:*) prefix rule
Do you want to proceed?
❯ 1. Yes
2. Yes, and switch to auto mode · auto mode handles these prompts for you
3. No
Esc to cancel · Tab to amend · ctrl+e to explain
これらのケースを並べると、確認プロンプトが出るかどうかは権限モードで決まっていました。
manual モードでは、find -delete を Bash で実行する前に必ず確認プロンプトが出ました。ファイルの中身がどうであっても、Bash コマンドを実行する時点で一度止まります。
auto モードでは、Bash 実行前の確認プロンプトは出ず、代わりに Claude が削除前にファイルの中身を読んで、消してよいかどうかを自分で判断していました。中身が dummy のときはそのまま削除し、中身が「業務上重要な内容」のときは削除を止めてユーザーに確認しています。
どちらのモードでも共通しているのは、deny に Bash(rm:*) を入れていても find -delete はブロックされなかったという点です。確認プロンプトや Claude の判断で止まる場面はありましたが、それは deny が止めたものではありません。find -delete は Bash(rm:*) に一致しないので、deny の対象外のままでした。
選択できるモデルが変わる挙動
Claude Code on Bedrock なのですが、起動するたびに利用できるモデルが変わるという謎事象にもぶち当たっており、なんでかな~となっています。

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Select model
Switch between Claude models. Your pick becomes the default for new sessions. For other/previous model names, specify with --model.
❯ 1. Default ✔ Use the default model (currently Opus 4.8)
2. Sonnet 4.6 Sonnet 4.6 · Previous Sonnet version
3. Sonnet 4.6 (1M context) Sonnet 4.6 for long sessions
4. jp.anthropic.claude-opus-4-8 Custom Opus model
5. Haiku Haiku 4.5 · Fastest for quick answers
● High effort (default) ←/→ to adjust
Enter to set as default · s to use this session only · Esc to cancel

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Select model
Switch between Claude models. Your pick becomes the default for new sessions. For other/previous model names, specify with --model.
1. Default Use the default model (currently Opus 4.8)
❯ 2. jp.anthropic.claude-sonnet-4-6 ✔ Custom Sonnet model
3. jp.anthropic.claude-opus-4-8 Custom Opus model
4. Haiku Haiku 4.5 · Fastest for quick answers
● High effort (default) ←/→ to adjust
Enter to set as default · s to use this session only · Esc to cancel

:
以下ブログの通りモデルを設定しているのですが、プロジェクトスコープの settings.json が悪さをしているのか、ガードレールのクロスリージョン推論が悪さをしているのか…
原因が分かったらどこかで記事にしたいと思っています。
おわりに
rm を直接 deny に入れれば rm は確実に止まりますし、allow に同じものがあっても deny が優先されます。
一方 find -delete のように別の書き方で同じ結果を出すコマンドは 止まりません。manual モードでは Bash 実行前に確認プロンプトが出て、auto モードでは Claude がファイルの中身を見て消してよいか判断していました。
コマンドの言い換えまで含めて止めるにはどうするかというと、PreToolUse フック(ツール実行の直前に自分のスクリプトで内容を検査する仕組み)や sandbox(OS レベルでアクセス自体を制限する仕組み)が候補になりうる、と Claude にアドバイスもらったのですが、実際には試していないのでまだ分かりません。
別の記事で実際に動かして確かめてみようと思います。
本記事への質問やご要望については画面下部の「DevelopersIOへのご意見」からお問い合わせいただけます。
参考






