Claude Codeのpermissions設定、allowとdenyの優先順位を検証してみた

Claude Codeのpermissions設定、allowとdenyの優先順位を検証してみた

Claude Codeのsettings.jsonのallowとdenyの優先順位を検証
2026.04.10

クラスメソッド株式会社データ事業本部所属のニューシロです。
前回の記事ではClaude CodeのCLAUDE.mdの禁止ルールとsettings.jsondenyルールの違いを検証しましたが、今回はその続編として、settings.jsonallowdenyの優先順位を検証してみました。

前回の記事: Claude CodeのCLAUDE.mdの禁止事項とsettings.jsonのdenyルールを検証してみた

前提

settings.jsonのpermissions設定とは

Claude Codeのsettings.jsonでは、permissionsフィールドでallowdenyaskの3種類のルールを設定できます。

{
  "permissions": {
    "allow": ["Bash(ls *)"],
    "deny": ["Bash(rm *)"],
    "ask": ["Bash(git *)"]
  }
}
  • allow: 確認なしで実行を許可する
  • deny: 実行をブロックする
  • ask: 実行のたびにユーザーに確認を求める

参考: 設定ファイル - Claude Code

設定のスコープと優先順位

Claude Codeの設定には複数のスコープがあり、優先順位が定められています。

優先順位 スコープ 場所 説明
1(最高) Managed サーバー管理設定、plist / レジストリ、またはシステムレベルの managed-settings.json 何によってもオーバーライドできない
2 コマンドライン引数 CLIオプション 一時的なセッションオーバーライド
3 Local .claude/settings.local.json プロジェクトとユーザー設定をオーバーライド
4 Project .claude/settings.json ユーザー設定をオーバーライド
5(最低) User ~/.claude/settings.json 他に何も設定を指定しない場合に適用

参考: 設定ファイル - Claude Code

やりたいこと

以下の3点を検証します。

  1. allowとdenyで同じコマンドを指定した場合、denyが優先されるか?
  2. allowで広く許可し、denyでピンポイントに禁止した場合、正しく制御できるか?
  3. User設定(~/.claude/settings.json)とProject設定(.claude/settings.json)で競合した場合、どちらが優先されるか?

公式ドキュメントによると、評価順序はdeny > ask > allowとされています。また、設定ファイルのスコープはProject設定がUser設定より優先されるとされています。これらが実際にその通りに動作するのかを確認します。

ルールは順序で評価されます。deny -> ask -> allow。最初にマッチしたルールが優先されるため、deny ルールは常に優先されます。

検証環境

前回と同様に、専用のディレクトリを用意して独立した環境で検証を行います。

poc/
├── CLAUDE.md
└── .claude/
    └── settings.json

検証

検証1: allowとdenyが競合した場合、denyが優先されるか

settings.jsonに以下を設定します。同じパターンでallowdenyの両方を指定します。

{
  "permissions": {
    "allow": ["Bash(ls *)"],
    "deny": ["Bash(ls *)"]
  }
}

この状態で「lsコマンドを実行してください」と指示します。

devio029_01.

ドキュメントに記載された通り、allowよりもdenyが優先され、lsコマンドの実行が拒否されました。
(とはいえpoc/配下は表示してくれました)

検証2: allowで広く許可し、denyでピンポイントに禁止した場合

次に、lsコマンド全般をallowで許可しつつ、ls /etcだけをdenyで禁止する設定を試します。

{
  "permissions": {
    "allow": ["Bash(ls *)"],
    "deny": ["Bash(ls /etc)"]
  }
}

まず「lsコマンドを実行してください」と指示します。

devio029_02

こちらは実行してくれました。想定通りです。

次に「ls /etcを実行してください」と指示します。

devio029_03

こちらも想定通り、拒否してくれました。
denyルールの方が優先されていますので、このようなコマンドの制御方法もケースによっては有効だと思います。

検証3: User設定とProject設定が競合した場合

最後に、設定ファイルの配置場所による優先順位を検証します。

検証3a: User設定でallow、Project設定でdeny

User設定(~/.claude/settings.json)でlsコマンドをallowし、Project設定(.claude/settings.json)でlsコマンドをdenyした場合、どちらが優先されるかを確認します。

User設定(~/.claude/settings.json):

{
  "permissions": {
    "allow": ["Bash(ls *)"]
  }
}

Project設定(.claude/settings.json):

{
  "permissions": {
    "deny": ["Bash(ls *)"]
  }
}

この状態で「lsコマンドを実行してください」と指示します。

devio029_05

Project設定はUser設定より優先順位が高く、かつdenyallowより優先されるため、Bashコマンドの実行が拒否されました。
こちらは想定通りの挙動でした。

検証3b: User設定でdeny、Project設定でallow

今度は逆に、User設定(~/.claude/settings.json)でlsコマンドをdenyし、Project設定(.claude/settings.json)でlsコマンドをallowした場合を確認します。

User設定(~/.claude/settings.json):

{
  "permissions": {
    "deny": ["Bash(ls *)"]
  }
}

Project設定(.claude/settings.json):

{
  "permissions": {
    "allow": ["Bash(ls *)"]
  }
}

この状態で「lsコマンドを実行してください」と指示します。

devio029_04

Project設定はUser設定より優先順位が高いですが、User設定に記載したdenyルールが無視されることはありませんでした。
denyルールはスコープの優先順位に関わらず、allowより優先されることが確認できました。
想定通りではありましたが、確認できてよかったです。

所感

結果は割と予想通りで、allowよりもdenyが優先されました(とはいえそうならないとセキュリティ上まずそうなのでよかったです)。
また、denyルールは、User設定・Project設定どちらに書いてあっても、スコープの優先順位に関わらずallowより優先されることも想定通りでした。
denyルールはスコープに関わらずallowより優先されるため、禁止したいコマンドはdenyに記載しておけばどのスコープでもブロックできそうです。この辺りの設定については、きちんと挙動を把握しておくことが大切そうですね。

参考

この記事をシェアする

関連記事