目次
Claude Codeの権限ルール(permission rules)は、settings.json に allow / ask / deny を書いて、「どのツール・コマンド・ファイル・ドメインを、確認なしで許す/毎回聞く/禁止する」を細かく指定するしくみだ。チームで共有でき、一致した呼び出しを禁止し、事前に確認した定型作業の承認を減らせる。ただし、同じプログラムの別表記やスクリプト経由まで一律に止める仕組みではない。
本記事では、権限ルールとは何か(権限モードとの違い)・allow/ask/denyの優先順位・ルールの書き方・settings.jsonの階層・実用レシピまでを、公式仕様に基づいて整理する。
allow / ask / deny で細かく制御
評価順は deny → ask → allow(最初に一致したものが勝つ)
deny
一致する禁止ルールを先に評価
ask
毎回確認する
allow
確認なしで許可
1. 権限ルールとは(モードとの違い)
Claude Codeは段階的な権限システムを持つ。Manualを基準にすると、作業範囲の読み取りは通常確認不要、編集やBash実行は通常確認が必要(組み込みの読み取り専用コマンドやallowなどは例外)——という土台の上に、ルールで「例外」を細かく指定できる(出典:Claude Code公式「Configure permissions」)。
混同しやすいのが権限モードとの違いだ。モードは“全体の確認頻度”の大枠(default/acceptEdits/auto等)、ルールは“個別のツール・コマンド単位”の指定。両者は重なって働く——モードで大枠を決め、ルールで「これは常に許可」「この呼び出しを禁止」を上書きする。
💡 ルールはClaude Codeが強制する(モデルではない)。プロンプトや CLAUDE.md はClaudeの“やろうとすること”に影響するが、“許される範囲”は変えない。許可・禁止は /permissions・ルール・モード・PreToolUseフックで制御する。
2. allow / ask / deny と優先順位
ルールは3種類。/permissions コマンドで一覧・編集できる(どの settings.json 由来かも表示される)。
確認なしで許可
指定したツール/コマンドを手動承認なしで実行できる。
毎回確認する
使うたびに確認を求める。より広いallowがあっても、askが一致すれば確認が出る。
禁止(最優先)
使わせない。どのallowより強く、設定ルール同士では、一致したdenyをallowで上書きできない。
評価順は deny → ask → allow。通常の設定ルール同士では最初の一致で結果が決まり、ルールの細かさ(具体性)は順序を変えない。たとえば広い Bash(aws *) のdenyは、より具体的な Bash(aws s3 ls) のallowより優先してブロックする。allowで一致するdenyを上書きできないのが要点だ。ただしRead/Editの相対パスには否定パターンという別の機能がある。
⚠️ denyの2形は挙動が違う:ツール名だけの Bash はツールごと文脈から消す(Claudeが存在を認識しない)。Bash(rm *) のように範囲指定すると、ツールは使えるが一致した呼び出しだけブロックする。
3. ルールの書き方(Tool(指定子))
形式は Tool(全体)か Tool(指定子)(個別)。ツール別に指定子の書き方が違う。
| ツール | 例 | 意味 |
|---|---|---|
| Bash | Bash(npm run *) | npm run で始まるコマンド(末尾 *は単語境界) |
| Read / Edit | Read(./.env) | カレントの.env読み取り(gitignore形式パス) |
| WebFetch | WebFetch(domain:example.com) | example.comへのfetch |
| MCP | mcp__github__get_* | githubサーバーのget_系ツール |
| Agent | Agent(Explore) | Exploreサブエージェント |
MCP のルールは、名指ししたサーバーにだけ効く。v2.1.299(2026年10月14日)以降、mcp__a は a__b や a_ という名前の別のサーバーを許可しない。名前に __ を含むサーバーや _ で終わるサーバーは、mcp__reports__v2__* のように正規化した名前の全体に __* を付けて書く(公式・更新履歴、2026年10月18日に確認)。
Bashのワイルドカードは位置自由。Bash(ls *)(空白+*)は ls -la に一致するが lsof には不一致(単語境界)。空白なしの Bash(ls*) は両方一致。末尾の :* は * と等価。
// 指定した呼び出しを許可・禁止(同じプログラムの全経路は封じない)
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git commit *)"
],
"deny": [
"Bash(git push *)"
]
}
}
複合コマンドは各サブコマンドを照合し、認識するラッパーは外して判定する。ただし同じプログラムの別表記まで一致するわけではない。Bash(git push *)はgit -C . pushに一致しない。組み込みの読み取り専用コマンドは通常確認を省くが、作業範囲外の読み取り制限やautoの分類器による待機などは別の条件になる。
Read/Editのパスはgitignore形式で、アンカーが4種類ある。
| 書き方 | 基準 | 例 |
|---|---|---|
//path | ファイルシステム絶対 | Read(//tmp/x) |
~/path | ホーム | Read(~/.ssh/**) |
/path | 設定ファイルの基準(プロジェクト設定ならプロジェクトルート、ユーザー設定なら ~/.claude) | Edit(/src/**) |
path / ./path | カレント | Read(.env) |
※ /Users/... は絶対パスではなく、その設定ファイルの基準(プロジェクト設定ならプロジェクトルート)から数える。ユーザー設定の Read(/secrets/**) は ~/.claude/secrets/** を指すので、全プロジェクトに効かせたいなら // か ~/ で書く。絶対パスは //Users/... と二重スラッシュで書く。Read(.env) は Read(**/.env) と同義で、配下の全 .env に一致。
相対パスdenyの否定パターンは別機能。 同じソースの配列でRead(*.env)の後にRead(!sample.env)を置くと、sample.envをそのルールの対象から外せる。別ソースのdeny、/・~/・//で固定したルール、ディレクトリ全体の拒否はこの方法で解除できない。allowでの上書きとは区別する。公式:否定パターン。
4. settings.json の階層と優先順位
設定値は階層に従って解決する。一方、許可ルールでは一致したdenyがallowより先に評価される。以下は設定ファイル・CLIルール間の優先関係であり、modによる判定変更まで含めた絶対的な保証ではない。
| 優先 | 場所 | 用途 |
|---|---|---|
| 1(最強) | 管理(managed)設定 | 組織ポリシー(ユーザー/CLIで上書き不可) |
| 2 | コマンドライン引数 | そのセッションの一時上書き |
| 3 | .claude/settings.local.json | 個人のプロジェクト設定(gitignore) |
| 4 | .claude/settings.json | チーム共有のプロジェクト設定(コミット) |
| 5 | ~/.claude/settings.json | 全プロジェクト共通のユーザー設定 |
// .claude/settings.json(チーム共有)
{
"permissions": {
"defaultMode": "acceptEdits",
"allow": ["Bash(npm run *)", "WebFetch(domain:docs.example.com)"],
"deny": ["Read(.env)", "Read(**/secrets/**)", "Bash(git push *)"],
"additionalDirectories": ["../shared-lib"]
}
}
権限モードの既定もここで defaultMode として指定する(モード詳細)。ただし auto と bypassPermissions はプロジェクト設定(.claude/settings.json・.claude/settings.local.json)に書いても効かないので、ユーザー設定か管理設定に書く。作業フォルダ外を読み書きさせたいときは additionalDirectories に追加する。
5. 実用レシピ
基本は確認済みの定型呼び出しをallowに絞り、制限したい呼び出しをask/denyにすること。同じ操作の別表記や、許可したスクリプトの中身まで自動的に制御できるわけではない。
🔒 秘密ファイルを守る
deny: ["Read(.env)", "Read(**/secrets/**)", "Read(~/.ssh/**)"]。組み込みファイルツールや、対象パスを認識できるファイルコマンドを制限。再帰検索・任意スクリプト・MCPなど別経路は残る。
🚀 指定した呼び出しに確認を追加
ask: ["Bash(git push *)", "Bash(rm *)"]。一致する呼び出しにはautoでも確認を追加。ただし別表記やmodによる判定変更には注意。
⚡ 定型作業を自動化
allow: ["Bash(npm run *)", "Bash(git commit *)"]。テスト/ビルド/コミットをノンストップに。ただし自動モードでは、Bash(npm run *) のようなパッケージマネージャーの run コマンドの広い許可は外れ、分類器の審査に回る。
URLをBashの引数だけで強制制限するのは不十分。curl/wgetをdenyしてWebFetchを使う方針でも、絶対パスやsh -c、別プログラムによる通信は残る。WebFetchのドメイン指定はそのツールの制御であり、Bash全体の通信制限ではない。接続先の強制制限が必要なら、サンドボックスのネットワーク許可リストなどを組み合わせ、サンドボックス外のツール・再実行も別途管理する。
6. 注意点とよくある誤解
- denyはモデルではなくClaude Codeが強制。プロンプトやCLAUDE.mdで「読まないで」と書いても、ルールがなければ防げない。
- Read/Editのdenyは“間接アクセス”を防げない。組み込みファイルツールや
cat/head/sedには効くが、PythonやNodeスクリプトがファイルを開く処理には効かない。grep -r pattern .のように対象ファイルを名指ししない処理も例外。OS側の制限はサンドボックス内のプロセスへ適用され、内蔵ReadやMCPなどは別途制御する。 - 環境ランナーに注意。
devbox run *やnpx、docker execは引数をコマンドとして実行するため、Bash(devbox run *)はdevbox run rm -rf .まで許してしまう。内側のコマンドまで含めて書く。 - フックは上書きしない。PreToolUseフックはルールを“拡張”できるが、deny/askはフックの結果に関わらず評価される。ただしmodの
tool.checkは後段で判定を置換できる。askを承認でき、denyも管理設定のない個人環境などでは承認可能。管理設定のある端末・Team/Enterpriseでは既定でdenyが優先するが、組織設定でも変わる。導入するmodの信頼判断が必要だ。 - 自動モードでは、allow に書いたコマンドでも分類器の審査に回ることがある。自動モードに入ると、任意のコードを実行できる広い allow(
Bash(*)・Bash(python*)のようなインタープリタのワイルドカード・パッケージマネージャーの run コマンド・Agentなど)は外れ、モードを抜けると戻る(Bash(npm test)のような狭いルールは残る)。ルールは書かれたとおりにしか一致しないので、Bash(git push *)はgit -C . pushに一致せず、一致しなかったコマンドは分類器が判定する。保護されたパスへの書き込みも、allow があっても分類器に回る。正当な操作が止められたら/permissionsの Recently blocked(v2.1.314 より前は Recently denied)から再試行できる(権限モードの記事)。allow に書いたのに止められたという報告は GitHub の issue にもある(例:#95996)。※この項目は2026年10月9日時点の公式ドキュメント(Choose a permission mode)による。
※仕様はClaude Code公式ドキュメント(Configure permissions/Settings files and precedence/Choose a permission mode)に基づく(2026年10月9日時点)。挙動は更新されることがあるため最新は公式を確認のこと。
まとめ
Claude Codeの権限ルールを3点に整理する。
- 正体:
settings.jsonの allow/ask/deny で、ツール・コマンド・ファイル・ドメイン単位に許可/確認/禁止を指定。モードが大枠、ルールが個別。 - 優先順位:deny → ask → allow(最初の一致が勝つ・具体性は無関係)。設定ルール同士では、一致したdenyをallowで上書きできない。階層は managed>CLI>local>project>user。
- 書き方:
Tool(指定子)。Bashはワイルドカード(空白+*は単語境界)、Read/Editはgitignore形式パス、WebFetchはdomain:。複合コマンドは各サブコマンドが一致要。
ルールの一致範囲を把握して、必要な承認だけを減らすのが設計の要点。権限モードやHooksと組み合わせ、ファイル・通信の強制制限が必要ならサンドボックスも検討する。どの層がどの経路に効くかを区別しよう。
コードを変更せず、現状の調査と助言だけを依頼したい場合は、Codex・Claude Codeを調査専用で使う手順を参照してください。アプリ・IDE・CLIの操作と、実装へ進ませない依頼文を掲載しています。
FAQ
Q. 権限ルールとモードは何が違う?
A. モードは確認頻度の大枠(default/acceptEdits/auto等)、ルールは個別ツール・コマンド単位の指定です。両方が重なって働き、ルールはモードを上書きできます(例:autoモードでもask/denyルールは効く)。
Q. allowしたのに確認が出るのはなぜ?
A. 評価順が deny→ask→allow だからです。同じ呼び出しに一致するask(やdeny)が別にあると、より具体的なallowがあってもそちらが優先されます。具体性は順序を変えません。
Q. settings.json はどこに置く?
A. チーム共有は .claude/settings.json(コミット)、個人用は .claude/settings.local.json(gitignore)、全プロジェクト共通は ~/.claude/settings.json。組織で固定したい場合は管理設定(上書き不可)を使います。
Q. .env の読み取りを制限するには?
A. deny: ["Read(.env)", "Read(**/secrets/**)"]は、組み込みファイルツールや認識できるファイルコマンドを制限します。対象パスを名指ししない再帰検索、Python/Node、MCPなどすべての経路を止める保証ではありません。シェル側はOSの読み取り権限やサンドボックス内のdenyReadを、他ツールは別の権限を確認してください。
Q. Bashの引数でURLやファイルを制限できる?
A. コマンド文字列の照合だけでは、別表記や別プログラムの同じ通信・ファイル操作まで封じられません。WebFetchのドメインルールはWebFetch用です。強制が必要ならシェルのファイル・ネットワーク隔離を併用し、サンドボックス外のアクセスも別途制御してください。
権限・隔離の対象範囲と例外条件は2026年10月9日に公式原文を再照合しました。端末設定の変更や起動試験は行っていません。