「許可のルールを書いたのに、思ったとおりには確認なしで動きません」
「.env を deny に書いたので、もう読まれないはずですよね?」
第5回(権限モードとauto mode)で、権限モードは確認なしで実行する範囲の基準を決めるものだと見ました。モードの上に重ねて、特定の操作を事前に許可したり、確認させたり、止めたりするのが権限ルール(allow・ask・deny)です。
ただし、ルールには癖があります。評価の順番、前方一致、つないだコマンドの扱い、そして deny が「境界」ではないこと。知らないと、「書いたのに効かない」「書いたつもりで守れていない」のどちらも起きます。
第6回では、ルールの書き方と評価の順番、前方一致の落とし穴と deny の限界、設定ファイルの階層、Ansible の作業での設定例を扱います。数値・仕様は2026年10月時点です。
allow・ask・denyルールの書き方
ルールは、設定ファイルの permissions に allow・ask・deny の3つのリストとして書きます。
- 形式:
ツール名またはツール名(条件)。例:Bash(git diff *)、Read(./.env)、WebFetch(domain:docs.ansible.com) - 評価の順番:deny → ask → allow の順に調べ、最初に一致したものが決める。より具体的なルールが優先されるわけではない
- その結果①:広い deny に、狭い allow で例外を作ることはできない
- その結果②:広い ask があると、それに一致するものは、狭い allow があっても確認される。ask に一致したものは、使うたびに確認が出る
*の意味:空白を含む任意の文字列に一致する。Bash(ls:*)とBash(ls *)は同じ意味- つないだコマンド:
&&・;・|でつないだものは、1つずつ判定される - どれにも一致しない操作:モードに従う(「手動」なら確認、「自動」なら分類器が判断)
補足:出典は公式の文書 https://code.claude.com/docs/en/permissions です。

公式の文書にある、ルールの細かい決まり
上の箇条書きに、公式の文書の記述を足します。
- 順番と具体性:公式の文書も、評価は deny、ask、allow の順で、その順で最初に一致したものが結果を決め、ルールの具体性は順番を変えない、と書いている。
Bash(aws *)のような広い deny は、Bash(aws s3 ls)のような狭い allow にも一致する呼び出しをすべて止める。allow で deny に例外を作ることはできない。ask と allow の間も同じで、一致する ask は、より具体的な allow が同じ呼び出しに一致していても確認を出す :*:Bash(ls:*)のように末尾に付ける:*は、末尾のワイルドカードの同じ意味の書き方で、Bash(ls:*)はBash(ls *)と同じコマンドに一致する。:*の形が認識されるのは、パターンの末尾だけ- つないだコマンド:Claude Code はシェルの演算子を理解しているので、
Bash(safe-cmd *)というルールは、safe-cmd && other-cmdの実行を許可しない。区切りとして認識されるのは&&・||・;・|・|&・&・改行。ルールは、サブコマンドのそれぞれに、独立に一致する必要がある - 読み取り専用の組み込みの一覧:
ls・cat・echo・pwd・head・tail・grep・find・wc・which・diff・stat・du・cd、そして git の読み取り専用の形は、組み込みの読み取り専用のコマンドとして、どのモードでも確認なしで実行される(作業フォルダーの外のパスについてはpermissions.blockReadsOutsideWorkingDirectoriesで変わる)。この一覧は設定で変えられない(これらのコマンドで確認を出したいときは、そのコマンドの ask か deny のルールを足す)。自動モードでは、これらのコマンドも分類器の判定を待つことがある。ただし、cdで別のディレクトリーへ移ってからgitを実行する組み合わせ(例:cd other && git status)は、各部分が読み取り専用でも確認になる(移った先の git のフックが動きうるため)。cdの後のリダイレクトの書き込み先が決められないときも確認になる - リダイレクト:
/dev/null、2>&1や<&3のようなファイル記述子の形、here-doc や here-string のような、後ろにファイルが無い対象は、検査されない
つないだコマンドの判定が分かりやすいのは、2>&1 | cat です。ansible-playbook --check --diff ... 2>&1 | cat は、前の部分が allow のルールに一致し、2>&1 は検査されず、cat は読み取り専用の一覧にあるので、全体が許可のままになります。
前方一致の落とし穴と、denyの限界
ルールは前方一致
ルールは前方一致です。
- ルールは前方一致:
Bash(ansible-playbook --check *)は、ansible-playbook --check ...で始まるコマンドにだけ一致する - 順番が違うと一致しない:
ansible-playbook site.yml --checkは対象外。確認が求められたり、「自動」では分類器の判断になったりする - 対策:CLAUDE.md に、コマンドを書く順番を決めて書いておく(第4回の「チームで共有するCLAUDE.mdのひな形(筆者の例)」の「よく使うコマンド」)
- deny は境界ではない:
/usr/bin/curlやsh -c '...'のように書き方を変えると、deny ルールをすり抜けることがある - 確実に止めたいとき:サンドボックスか、PreToolUse フック(第7回の「フックで止める」)を使う

補足:出典は公式の文書 https://code.claude.com/docs/en/permissions です。公式のページには Ansible の例がないため、次の「Ansibleの作業での設定例」の設定で、筆者が実機で確かめました(2026-10-18、CLI の Claude Code 2.1.289、「手動」に当たる --permission-mode default)。順番を変えたコマンドは承認が要り、2>&1 | cat を付けたものは許可のままでした。
筆者の演習でも、ansible-lint; echo "exit=$?" が、allow のルール(Bash(ansible-lint *))があっても確認になりました(2026-10-18、CLI の claude -p。承認が要るものは拒否されます)。同じルールで、別々に実行した追加の実測(--permission-mode default=「手動」)の結果は次のとおりです。
| コマンド | 結果 |
|---|---|
ansible-lint --version | 確認なしで実行 |
ansible-lint --version; echo done | 確認なしで実行 |
ansible-lint --version; echo "exit=$?" | 承認が要って止まった(ansible-lint の部分も実行されない) |
ansible-lint --version && echo ok | 確認なしで実行 |
筆者の実測では、; や && でつないだことや echo ではなく、$? の展開(変数の展開)を含む部分が確認の原因と見られます。公式の文書では、この挙動の記述を見つけられていません。
公式の文書にある、deny の限界
公式の文書は、Bash のルールの限界を次のように書いています。
- Bash のルールは、Claude Code が複合コマンドを分け、ラッパーを外した後の、Claude が書いたコマンドの文字列に一致する。同じプログラムを別の形で呼び出したものには一致しない。そのため、deny や ask のルールは、Claude が普通に出す呼び出しをカバーするだけで、プログラムの周りのセキュリティの境界ではない
| ルール | 止めるもの | 止めないもの |
|---|---|---|
Bash(curl *) | curl https://example.com | /usr/bin/curl https://example.com、sh -c 'curl https://example.com' |
- deny のルールは、パスで呼んだ同じプログラムや
sh -cの中には一致しない。制限を守らせる必要があるときは、サンドボックスのネットワークの許可リストと組み合わせる - コマンドの文字列に頼らず、ファイルシステムとネットワークで強制したいときは、サンドボックスを使う
サンドボックスについて、公式の文書は次のように書いています。
- サンドボックスは macOS・Linux・WSL2 で動く。ネイティブの Windows では、Claude Code はサンドボックスなしでコマンドを実行する。Windows で使うなら、WSL2 のディストリビューションの中で Claude Code を動かす
- サンドボックスが対象にするのはシェルのコマンドだけ。Claude のファイルのツール・MCP サーバー・フックは、サンドボックスの外で動く
- サンドボックスは既定ではオフ
Read の deny は、Bash の cat も止めるか
.env を読ませたくないときは、Read(./.env) や Read(./secrets/**) のような Read の deny ルールを書きます。公式の文書は、Read と Edit の deny ルールが、Claude のファイルのツールに加えて、Bash の中で Claude Code が認識するファイルのコマンド(cat・head・tail・sed・tee など)と、リダイレクトの対象(> file・< file)にも効くと書いています。一方、ファイル名を挙げずに読むコマンド(ファイルのあるディレクトリーで実行する grep -r pattern . など)や、Python・Node のスクリプトが自分でファイルを開く場合には効きません。組み込みの Grep・Glob、プロンプトの @file、接続した IDE が渡す選択範囲や開いているファイルにも、Read のルールを best-effort(できる限り)で適用する、とも書いています。
筆者が確かめ直したとき(2026-10-18、CLI の Claude Code 2.1.289)は、まず CLAUDE.md の「.env と vault_pass.txt を読まない」の指示が先に効いて、Claude が cat .env も ansible-vault view vault_pass.txt も自分で実行しませんでした。CLAUDE.md のその行を一時的に外して頼むと、どちらも「Permission to use Bash with command cat .env has been denied.」のように拒否されました。Read(./.env) の deny は、Claude Code が見分けられる cat などのファイルのコマンドにも効きます(公式の permissions の文書の注意と一致)。ただし、名前を挙げずに読むコマンド(grep -r など)や自分でファイルを開くスクリプトには効かないので、そこまで止めたいものは、サンドボックス(OS のレベルの制限)やフックで守ります。連載「Claude活用入門」第5回の「秘密情報を読ませない」にも、同じ注意があります。
設定ファイルの階層
ルールは、設定ファイルのどこに書くかで、効く範囲と強さが変わります。
| 優先順位 | ファイル | 用途 |
|---|---|---|
| 1(最優先) | 管理ポリシー(managed-settings) | 組織が配る。利用者は上書きできない。個人の PC では、自分で置かない限り無い |
| 2 | コマンドラインの指定 | その回だけ(CLI) |
| 3 | .claude/settings.local.json | このリポジトリでの自分用(Git で共有しない)。「常に許可」の保存先 |
| 4 | .claude/settings.json | このリポジトリの共通設定(Git で共有する)。チームで共有するひな形はここ |
| 5 | ~/.claude/settings.json | 自分の全プロジェクト共通 |

補足:permissions.allow などのリストは、上書きではなく全部合わせて使われます。どこか1か所で deny されたものは、ほかで allow できません。公式の文書も、permissions.allow のように同じリストのキーを複数のファイルに書くと、Claude Code は1つを選ばずにリストを結合するので、各ファイルは、ほかのファイルのエントリーを消さずに、エントリーを足せる、と書いています。
CLI では、どのファイルが読まれたかを /status の Setting sources 欄で確認できます(Setting sources の行に、User settings や Project local settings のように、そのセッションで読み込んだ設定ファイルが並びます)。Code タブの /status で、設定ファイルごとの一覧が出るかどうかは、筆者は確かめていません。出典は公式の文書 https://code.claude.com/docs/en/settings です。
未信頼のフォルダーでは、プロジェクトの allow が効かない
.claude/settings.json(プロジェクトの共通設定)に書いた permissions.allow のルールと permissions.additionalDirectories は、Claude に権限を与えるものです。そのため、Claude Code は、そのフォルダーのワークスペースの信頼の確認に応じた後にだけ適用します。
- 親のフォルダーだけを信頼していた場合:信頼の確認にもう一度応じるまで使われない。確認の画面には、そのルールが一覧で出る
claude -pや SDK で、そのフォルダーを一度も信頼していない場合:使われない。Claude Code はthis workspace has not been trustedという警告を stderr に出す- 信頼の確認は、対話のセッションだけで出る。
claude -pや SDK のセッションには出ない
筆者の CLI での実測(2026-10-18、Claude Code 2.1.289)でも、初めてのフォルダーを「信頼」する前は、.claude/settings.json の allow のルールが無視されました(Ignoring 6 permissions.allow entries from .claude/settings.json: this workspace has not been trusted. と表示)。対話の画面で一度開いて信頼の確認に答えると効きました。Code タブでの表示は確かめていません。
組織のプランの補足:管理された設定の配り方
階層の1番目の管理ポリシーは、組織が配るものです。公式の文書では、次のような配り方があります。
- ファイル:macOS は
/Library/Application Support/ClaudeCode/managed-settings.json、Linux と WSL は/etc/claude-code/managed-settings.json、Windows はC:\Program Files\ClaudeCode\managed-settings.json - MDM:macOS の構成プロファイルや Windows の
HKLMのレジストリ値として、Jamf・Intune・グループポリシーなどのツールで配る - サーバー管理の設定(claude.ai の管理画面):Claude for Teams か Claude for Enterprise のプランが要る
ファイルや MDM による配り方に、Team・Enterprise だけという制限は、見つけた範囲の文書には書かれていませんでした。個人で自分の PC を使うなら、自分で置かない限りこの段は空なので、意識する必要はありません。
Ansibleの作業での設定例(筆者の例)
ここまでの決まりを使って、Ansible の作業での設定例を示します。Ansible のリポジトリの .claude/settings.json(Git で共有する)に置きます。第8回の演習の準備プロンプトで作る設定と同じものです。
{
"permissions": {
"allow": [
"Bash(ansible-lint *)",
"Bash(ansible-inventory *)",
"Bash(ansible-playbook --syntax-check *)",
"Bash(ansible-playbook --check --diff *)",
"Bash(git diff *)",
"Bash(git status *)"
],
"ask": [
"Bash(ansible-playbook * inventory/prod*)",
"Bash(git push *)"
],
"deny": [
"Read(./.env)",
"Read(./**/vault_pass*)",
"Bash(ansible-vault decrypt *)",
"Bash(ansible-vault view *)"
]
}
}
- allow(確認なしで実行):lint・インベントリーの確認・構文確認・
--check --diff(変更を加えずに差分を見る実行)・git の差分と状態 - ask(毎回確認):インベントリーのパスに
inventory/prodが入る ansible-playbook(本番を指すもの)と、git push - deny(拒否):
.envと、vault_passで始まるファイルの読み取り、Vault の復号と表示
この設定は筆者の例で、公式の推奨ではありません。
設定例の読み方と、使い分け
設定例が、モードごとにどう動くかを表にします。
| 場面 | モード | 設定例での動き |
|---|---|---|
| 調べる・計画する | プラン | 読み取りと、分類器が認めた調査用のコマンドだけ |
| 書かせてレビューする | 編集を受け入れる | lint・構文確認・stg への –check –diff は確認なし。stg への本実行は確認が出る |
| 長く任せる | 自動 | 上と同じものは確認なし。どれにも一致しないものは分類器が判断する |
| 本番の作業 | 手動 | prod を指すものは、–check でも必ず確認が出る(ask は allow より先に評価される) |
| どのモードでも | — | .env や Vault のパスワードは読ませない。Vault の復号はさせない |
補足:この設定は筆者の提案で、公式の推奨ではありません。表のうち「手動」の動きは、筆者が 2026-10-18 に CLI の Claude Code 2.1.289(--permission-mode default)で13件のコマンドを試して確かめました。lint・構文確認・stg への --check --diff(2>&1 | cat 付きも)と、&& でつないだ lint と構文確認は確認なしで実行され、順番を変えた --check --diff、stg への本実行、prod を指す --check --diff(2>&1 | cat 付きも)、git push は承認が要りました。ansible-vault view と cat .env は、前の節のとおり Claude が実行しませんでした。第4回のひな形(「チームで共有するCLAUDE.mdのひな形(筆者の例)」)どおりに 2>&1 | cat を付けても、同じように判定されます。
表のうち、いくつかの動きを補います。
- prod を指すものは、
--checkでも確認が出る:ansible-playbook --check --diff -i inventory/prod/hosts.ini site.ymlは、allow のBash(ansible-playbook --check --diff *)にも、ask のBash(ansible-playbook * inventory/prod*)にも一致します。ask が先に評価されるので、確認になります - 「自動」でも ask は確認が出る:公式の文書は、auto mode でも、ask のルールが出させる確認は引き続き出る、と書いています。
git pushを、auto mode の分類器に任せずに確認させたいときに使えます(第5回の「公式の文書にある、表に載せなかった項目」で見たように、auto mode は既定のブランチへの通常の push を通すため) - stg への本実行は確認が出る:allow にあるのは
--syntax-checkと--check --diffだけなので、--checkを付けない本実行は、どのルールにも一致せず、モードに従います。筆者の演習の記録(2026-10-18、CLI、--permission-mode default=「手動」)でも、stg への本実行(ansible-playbook --diff -i inventory/stg/hosts.ini site.yml)は承認待ちになり、承認されなかったので実行されませんでした - 「常に許可」で足されるもの:Code タブで、その確認に「常に許可」を選ぶと、
.claude/settings.local.jsonに{"permissions":{"allow":["Bash(ansible-playbook -i inventory/stg site.yml)"]}}が保存され、同じ依頼の2回目は確認が出ませんでした(2026-10-04、Code タブ 2.1.284)。そのコマンドだけに一致するルールで、パイプの2>&1 | catは外されていました。この形を、この回のルールの書き方と比べてみてください
この回の内容は、第9回の演習の手順6(「手動」のまま stg への本実行を頼み、確認の画面で「常に許可」を選んで、.claude/settings.local.json を開く)で試せます。
考えてみよう
- allow に
Bash(ansible-playbook --check *)だけがあるとき、ansible-playbook site.yml --checkは確認なしで実行されますか。実行されない場合、どうすれば確認を減らせますか。 - allow に
Bash(git push origin feature/*)、ask にBash(git push *)があるとき、git push origin feature/xは確認なしで実行されますか。理由も答えてください。 .envを読ませたくありません。Read(./.env)の deny だけで十分でしょうか。確実に止めたいなら、ほかに何を使いますか。
ヒント:1は「前方一致の落とし穴と、denyの限界」、2は「allow・ask・denyルールの書き方」の評価の順番、3は「Read の deny は、Bash の cat も止めるか」の節を見直してください。
まとめ
- ルールは
ツール名(条件)の形。deny → ask → allow の順に調べ、最初に一致したものが決める。具体的なルールが優先されるわけではなく、広い deny に狭い allow で例外は作れない - ask に一致したものは、狭い allow があっても使うたびに確認になる。どれにも一致しないものは、モードに従う
- ルールは前方一致で、つないだコマンドは1つずつ判定される。順番が違うと一致しないので、CLAUDE.md にコマンドの書く順番を決めておく
- deny は境界ではない。
/usr/bin/curlやsh -c '...'で書き方を変えると、すり抜けることがある。確実に止めたいなら、サンドボックスか PreToolUse フック - 設定は、管理ポリシー、コマンドライン、
.claude/settings.local.json、.claude/settings.json、~/.claude/settings.jsonの順に強い。リストは合算され、どこかで deny されたものは、ほかで allow できない - プロジェクトの allow は、ワークスペースの信頼の確認に応じた後にだけ効く
- 設定例は、allow に lint・構文確認・
--check --diff、ask に prod への実行とgit push、deny に.envと Vault の復号を置く(筆者の例。公式の推奨ではない)
次回は、「走らせたら終わり」にしないための検証を扱います。
連載「Claude Code実践入門」全9回
- 任せる前に知っておくこと
- 作業範囲を決める
- 走らせながら操縦する
- CLAUDE.mdを育てる
- 権限モードとauto mode
- allow・ask・denyのルールと設定ファイル(この記事)
- 検証で終わらせる
- 演習(前編):準備から実装と検証まで
- 演習(後編):巻き戻し・差分・権限と振り返り


コメント