Tips & Tricks (更新: 2026/6/7)

Claude Code 権限設定リファレンス|settings.json の allow/deny/ask 早見表

Claude Code の権限を settings.json で設計するリファレンス。allow/deny/ask の評価順、Bash・Edit・Read・WebFetch のパターン構文、Hooks 自動化をコピペ設定例で。

Claude Code 権限設定リファレンス|settings.json の allow/deny/ask 早見表

Bash(git *) を allow に入れていたら、Claude Code が git reset --hard を一発で通してしまった。

幸い未コミットの変更は大したことなかったので事なきを得たんですが、青ざめました。git ** は引数全部に効くので、git reset --hardgit push --force も「git で始まるから OK」になっていたわけです。僕の deny が甘かった。

このとき痛感したのは、権限設定は「なんとなく allow を足す」ものじゃなくて、構文を正確に知って書く設定ファイルだということ。Bash(git *)Bash(git*) は別物だし、Read(/Users/alice) は絶対パスじゃない。知らないと穴が空きます。

この記事は、その穴を塞ぐためのリファレンスです。settings.json の構造、allow/deny/ask の評価順、ツール別(Bash / Edit / Read / WebFetch)のパターン書式、allowlist、PreToolUse フックによる権限の自動判定まで、全部コピペで動く設定例で並べます。「毎日どう運用するか」は深入りせず、設定の書き方そのものに徹します。

この記事の要点

  • 権限は settings.jsonpermissionsallow / deny / ask の3つで書く。評価は deny → ask → allow の順で、最初に当たったルールが勝つ。
  • ルール書式は ToolTool(specifier)Bash(ls *)Bash(ls*)スペースの有無で別物:* は末尾の * と同じ意味。
  • Read / Editgitignore 書式でパスを書く。//絶対 ~/ホーム /プロジェクト基準 相対 の4種類があり、/Users/... は絶対パスではない(罠)。
  • deny / ask はモデルではなく Claude Code 本体が強制する。CLAUDE.md やプロンプトでは緩められない。
  • 速度を上げたいなら allow を広く + PreToolUse フックで一部だけ止める。フックは exit 2 で実行をブロックできる。

毎日の安全運用や sandbox の話は姉妹記事の Approval / Sandbox 設定ガイド に、CLAUDE.md と権限を組み合わせる実用レシピは CLAUDE.md × 権限レシピ に分けてあります。この記事は設定リファレンスに集中します。

settings.json はどこに置くか

権限ルールは settings.jsonpermissions キーに書きます。ファイルの置き場所は4つあって、それぞれ役割が違います。

置き場所パス共有用途
User~/.claude/settings.jsonしない全プロジェクト共通の自分の好み
Project.claude/settings.jsongit 管理チームで共有する標準ルール
Local.claude/settings.local.jsongitignore自分だけの上書き
ManagedOS のポリシー領域 / managed-settings.json組織配布管理者が強制、最優先

優先順位は高い順に Managed → コマンドライン引数 → Local → Project → User です。ただし権限ルールだけは「上書き」ではなくスコープをまたいでマージされる点に注意してください。どこか1か所で deny されたら、他のどのレベルでも allow できません。User で allow しても Project に deny があれば deny が勝ちます。

だから安全設計の基本はこうです。deny はチーム共有の .claude/settings.json に書く。個人の settings.local.json には allow の追加だけ。 こうすればチームの deny を個人設定で外せなくなります。

# .gitignore に個人設定だけ除外を追加
echo ".claude/settings.local.json" >> .gitignore

allow / deny / ask の評価順

3つのキーの意味と、当たったときの挙動です。

キー意味挙動
allow許可確認ダイアログなしで自動実行
ask確認毎回ユーザーに承認を求める
deny拒否実行させない

評価は deny → ask → allow の順で、最初に当たったルールが勝ちます。つまり deny が常に最優先。冒頭の僕の事故は、ここを deny で先に塞いでいなかったのが原因でした。

deny には2つの書き方があって、効き方がまるで違います。

  • ツール名だけ(例 Bash)→ そのツールを Claude の手元から丸ごと取り上げる。Claude はその存在すら見えなくなる。
  • specifier 付き(例 Bash(rm *))→ ツールは使えるが、マッチしたコマンドだけブロックする。

ひとつ大事な前提を。deny / ask を強制するのは Claude Code 本体であって、モデルではありません。 CLAUDE.md やプロンプトに「rm は禁止」と書いても、それは Claude が「やろうとすること」を変えるだけで、許可の境界は動きません。境界を動かすのは permissions ルール・permission mode・PreToolUse フックの3つだけです。これは公式ドキュメントでも明言されています。

settings.json の最小テンプレート

まず骨格を貼ります。これをコピーして、自分のプロジェクトに合わせて中身を削っていくのが速いです。

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Read",
      "Glob",
      "Grep",
      "Bash(npm run lint)",
      "Bash(npm run test:*)",
      "Bash(git status)",
      "Bash(git diff:*)",
      "Bash(git log:*)"
    ],
    "ask": [
      "Edit",
      "Write",
      "Bash(git add:*)",
      "Bash(git commit:*)",
      "Bash(git push:*)",
      "Bash(npm install:*)"
    ],
    "deny": [
      "Read(.env)",
      "Read(.env.*)",
      "Read(secrets/**)",
      "Bash(rm -rf *)",
      "Bash(git push --force:*)",
      "Bash(git reset --hard:*)",
      "Bash(curl:*)"
    ]
  }
}

ここで ReadEdit をカッコなしで書いているのは、「そのツールの全使用にマッチ」という意味です。Bash(npm run test:*):* は末尾の *(スペース+ワイルドカード)と同じで、npm run test:unit のようなサブコマンドにも当たります。一個ずつ見ていきましょう。

Bash パターンの正しい書き方

ここが一番事故るので丁寧にいきます。Bash ルールは * をどの位置にも置けます。

書き方マッチする例しない例
Bash(npm run build)npm run build(完全一致のみ)npm run build --watch
Bash(npm run test *)npm run test foonpm run test(末尾に語がない)
Bash(npm *)npm installnpm run devnpmx(語境界)
Bash(* install)npm installpnpm installnpm install foo
Bash(git * main)git checkout maingit push origin maingit status

決定的なのがスペースの有無です。

  • Bash(ls *) → 末尾の * の前にスペースがあると語境界が効く。ls -la には当たるが lsof には当たらない。
  • Bash(ls*) → スペースなしだと語境界がないので、ls -lalsof も両方当たる。

冒頭の僕の Bash(git *) 事故がまさにこれ。git で始まれば git reset --hardgit push --force も全部 allow になっていました。広い allow を置くなら、危険な形は必ず deny で先に潰すのが鉄則です。

複合コマンドとラッパーは別扱い

Claude Code はシェルの区切り文字(&& || ; | など)を理解しています。だから Bash(safe-cmd *) という allow があっても、safe-cmd && rm -rf . は通りません。複合コマンドは各サブコマンドが個別にマッチして初めて許可されます。

逆に timeout time nice nohup stdbuf の5つは「プロセスラッパー」として剥がされてから判定されます。つまり Bash(npm test *) の allow があれば timeout 30 npm test も通ります。一方 npx docker exec devbox run などはラッパー扱いされません。Bash(devbox run *)devbox run rm -rf . まで許してしまうので、Bash(devbox run npm test) のように内側のコマンドまで含めて書きます。

Bash の引数で URL を縛るのは諦める

Bash(curl https://github.com/ *) で「curl は GitHub だけ」とやりたくなりますが、これは穴だらけです。-X GET が前に付く、https ではなく http、リダイレクト、URL=... 変数経由、余分なスペース——どれでもすり抜けます。

URL を本気で縛るなら、curl / wget を deny して、代わりに WebFetch(domain:github.com) で許可ドメインを指定します。これは後述します。

Read / Edit のパス書式(gitignore 形式)

ReadEdit のパスは gitignore の書式です。アンカー(基準点)が4種類あって、ここを勘違いすると deny が効きません。

書き方基準実際に指す場所
//pathファイルシステムのルートRead(//Users/alice/secrets/**)/Users/alice/secrets/**
~/pathホームディレクトリRead(~/.ssh/**)/Users/alice/.ssh/**
/pathプロジェクトルートEdit(/src/**/*.ts)<プロジェクト>/src/**/*.ts
path / ./pathカレントディレクトリRead(*.env)<cwd>/*.env

罠はここです。**Read(/Users/alice/file) は絶対パスではありません。**先頭スラッシュ1個は「プロジェクトルート基準」なので、これは <プロジェクト>/Users/alice/file を指します。本物の絶対パスはスラッシュ2個 //Users/alice/file

Windows では POSIX 形式に正規化されます。C:\Users\alice/c/Users/alice になるので、ドライブ全体の .env を塞ぐなら Read(//c/**/.env)、全ドライブなら Read(//**/.env) です。

ファイル名だけ書くと深さを問わず当たります。Read(.env)Read(**/.env) と等価で、カレント以下のどの階層の .env にも効きます。

{
  "permissions": {
    "deny": [
      "Read(.env)",
      "Read(.env.*)",
      "Read(**/credentials.json)",
      "Read(~/.ssh/**)",
      "Read(~/.aws/**)",
      "Edit(/.github/workflows/**)"
    ]
  }
}

ひとつ強い注意があります。Read / Edit の deny は、Claude の組み込みファイルツールと、Claude Code が認識する cat head tail sed などの Bash には効きますが、Python や Node のスクリプトが自前でファイルを開く動きは止めません。 秘密情報を OS レベルで守るには sandbox が要ります。その話は Approval / Sandbox 設定ガイド に分けてあります。

WebFetch・MCP・Agent の書式

ファイル系・Bash 系以外のツールも同じ Tool(specifier) 形式です。

  • WebFetch(domain:example.com) — example.com への取得だけ許可。
  • mcp__puppeteer — puppeteer という MCP サーバの全ツール。mcp__puppeteer__puppeteer_navigate で個別ツール指定。
  • Agent(Explore) — サブエージェント単位の制御。deny に入れると、その agent を止められる。

URL を縛りたいときの実用形がこれです。Bash の素のネットワークツールを塞ぎ、WebFetch のドメイン許可だけ通す。

{
  "permissions": {
    "allow": [
      "WebFetch(domain:github.com)",
      "WebFetch(domain:docs.anthropic.com)"
    ],
    "deny": [
      "Bash(curl:*)",
      "Bash(wget:*)"
    ]
  }
}

ただし WebFetch を allow しただけではネットワークを塞いだことにはなりません。Bash が許可されていれば curl や wget で任意の URL に届きます。だからドメイン制限は「WebFetch 許可」と「Bash ネットワークツール deny」をセットで初めて意味を持ちます。

用途別の設定スニペット集

そのまま貼って削れる形で、代表的な3パターンを置きます。

個人開発(読み取りは自由、書き込みは確認)

{
  "permissions": {
    "allow": [
      "Read",
      "Glob",
      "Grep",
      "Bash(npm run:*)",
      "Bash(node:*)",
      "Bash(git status)",
      "Bash(git diff:*)",
      "Bash(git log:*)"
    ],
    "ask": [
      "Edit",
      "Write",
      "Bash(git add:*)",
      "Bash(git commit:*)",
      "Bash(git push:*)"
    ],
    "deny": [
      "Read(.env)",
      "Read(.env.*)",
      "Bash(rm -rf *)",
      "Bash(git push --force:*)",
      "Bash(git reset --hard:*)"
    ]
  }
}

コンテンツ生成専用(書き込み先をディレクトリで絞る)

このサイトで実際に使っている形です。肝は Edit / Write を特定ディレクトリだけに限定するところ。

{
  "permissions": {
    "allow": [
      "Read",
      "Glob",
      "Grep",
      "Edit(/site/src/content/**)",
      "Edit(/content/**)",
      "Write(/site/src/content/**)",
      "Write(/content/**)",
      "Bash(node scripts/*)",
      "Bash(git diff:*)",
      "Bash(git status)"
    ],
    "ask": [
      "Bash(git add:*)",
      "Bash(git commit:*)",
      "Bash(git push:*)"
    ],
    "deny": [
      "Read(.env)",
      "Read(.env.*)",
      "Edit(.env*)",
      "Bash(rm -rf *)",
      "Bash(git push --force:*)"
    ]
  }
}

本番に近いリポジトリ(読み取り専用に倒す)

破壊系を deny で全部塞ぎ、acceptEdits などの自動承認に流れないようにします。起動は claude --permission-mode plan で。

{
  "permissions": {
    "defaultMode": "plan",
    "allow": [
      "Read",
      "Glob",
      "Grep",
      "Bash(git status)",
      "Bash(git diff:*)",
      "Bash(git log:*)",
      "Bash(git show:*)"
    ],
    "deny": [
      "Edit",
      "Write",
      "Bash(git push:*)",
      "Bash(git commit:*)",
      "Bash(rm:*)",
      "Bash(*deploy*)"
    ]
  }
}

permissions.disableBypassPermissionsMode"disable" にしておくと、うっかり bypassPermissions で起動する事故も防げます(managed 設定に置くと組織全体で外せなくなる)。

permission mode の一覧

settings.jsondefaultMode、または起動時の --permission-mode で、全体の既定動作を切り替えられます。

モード動作
defaultツールごとに初回確認する標準動作
acceptEditsファイル編集と mkdir touch mv などを自動承認
plan読み取りと read-only コマンドだけで調査。ソースは編集しない
dontAskallow で事前許可したもの以外は自動的に拒否
bypassPermissions全プロンプトをスキップ(隔離環境専用)

bypassPermissions はコンテナや VM など「壊れてもいい環境」だけ。rm -rf /rm -rf ~ のような致命的削除は、このモードでも安全装置として確認が入ります。

# 調査だけさせたいとき
claude --permission-mode plan

# 隔離コンテナ内での一括処理(普段使い厳禁)
claude --permission-mode bypassPermissions -p "テストを直して"

PreToolUse フックで権限を自動化する

allow / deny / ask は静的なルールです。「コミット直前に秘密情報スキャンを走らせて、引っかかったら止める」のような動的な判定Hooks でやります。

PreToolUse フックはツール実行の直前に走り、結果でその呼び出しを止められます。一番大事なのは exit code 2 で実行をブロックできること(exit 1 ではなく 2 です)。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git commit:*)",
        "hooks": [
          {
            "type": "command",
            "command": "git diff --cached --name-only | grep -qE '\\.env' && { echo 'コミットに .env が含まれています。中止します' >&2; exit 2; } || exit 0"
          }
        ]
      }
    ]
  }
}

ここで覚えておきたいのが、フックと権限ルールの関係です。

  • deny / ask ルールはフックの判定を無視して常に評価される。 フックが「allow」を返しても、マッチする deny があればブロックされる。
  • ブロックするフック(exit 2)は allow より優先。 だから「Bash は基本全部 allow にして、危ないやつだけフックで弾く」という運用が成立する。

つまり速度重視なら、allow"Bash" を入れて全許可にしつつ、PreToolUse フックで特定コマンドだけ exit 2 で止める、という形が作れます。

{
  "permissions": { "allow": ["Bash"] },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "node scripts/block-dangerous-bash.mjs"
          }
        ]
      }
    ]
  }
}

CLAUDE.md と権限・フックを組み合わせて「毎回の説明と危険操作を減らす」具体レシピは CLAUDE.md × 権限レシピ にまとめてあります。

設定を確認・デバッグする

「なぜこのコマンドが止まるのか」が分からないときは、/permissions を使います。有効な全ルールと、それがどの settings.json 由来かを一覧してくれます。

# 起動して
claude
# 対話中に実行
/permissions

CLI から素早く確認したいなら、起動時に --allowedTools / --disallowedTools で一時的に上書きして挙動を比べるのも手です。ただし managed の deny だけは CLI でも外せません。

よくある質問

Q. Bash(git *)Bash(git*) は何が違うの? A. スペースの有無で語境界の扱いが変わります。Bash(git *) は末尾にスペースがあるので git status などには当たるが gitk には当たりません。Bash(git*) はスペースなしなので gitk まで当たります。とはいえ git * でも git reset --hard まで許してしまうので、危険な形は deny で先に塞いでください。

Q. Read(.env) を deny したのに、なぜか中身が読まれた気がする。 A. Read deny は Claude の組み込みツールと cat head sed 等には効きますが、Python や Node スクリプトがファイルを自分で開く動きは止めません。OS レベルで塞ぐには sandbox が必要です(Approval / Sandbox 設定ガイド 参照)。

Q. /Users/me/secret を deny したのに効かない。 A. 先頭スラッシュ1個は「プロジェクトルート基準」で、絶対パスではありません。本物の絶対パスはスラッシュ2個 //Users/me/secret です。これは公式の罠ポイントとして明記されています。

Q. チームの deny を個人が外せないようにしたい。 A. deny は git 管理の .claude/settings.json に書き、個人の settings.local.json には allow 追加だけにします。deny はどのスコープからでも allow より先に評価されるので、Project の deny を Local の allow で外すことはできません。組織で完全に固定するなら managed 設定の allowManagedPermissionRulesOnly を使います。

Q. 確認だらけで遅い。安全に速くするには? A. allow を広めに取りつつ、PreToolUse フックで危険コマンドだけ exit 2 で止めるのが効きます。フックのブロックは allow より優先されるので、「基本許可・例外だけ遮断」が成立します。

まとめ

権限設定は気合や運用ルールではなく、書式を正確に知って settings.json に落とす設計作業です。最後に要点を圧縮します。

  • まず deny から書くrm -rfgit push --forcegit reset --hard.env 系。deny が最優先で評価される。
  • 次に ask。書き込み・コミット・push・install など、人間の意図確認が要るもの。
  • 残りを allow。読み取りと検証コマンド。Bash(... *) はスペースの有無に注意。
  • パスは gitignore 書式//絶対/プロジェクト基準 を取り違えない。
  • 速くしたいなら 広い allow + PreToolUse フックの exit 2

毎朝5分で allow/deny を棚卸しする運用は 権限監査チェックリスト に、コピペで使えるテンプレ一式は Claude Code 教材一覧 にまとめてあります。まずは上の最小テンプレートを .claude/settings.json に貼って、自分の deny を1行足すところから始めてみてください。最初の30分の設計が、そのあとの数百時間を安全にします。

参考資料

#claude-code #permissions #settings-json #allow-deny-ask #hooks
無料

無料PDF: Claude Code はじめてのチートシート

まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。

スパムは送りません。登録情報は厳重に管理します。

Claude Codeを仕事で使える形にしませんか?

まず無料PDFで基本を固め、繰り返し使う作業はGumroad教材へ、チーム導入や権限設計は導入相談へ進めます。

Masa

この記事を書いた人

Masa

Claude Codeの実務活用、導入設計、収益導線改善を検証しているエンジニア。10言語の技術メディアを運営中。

PR

関連書籍・参考図書

この記事のテーマに関連する書籍を楽天ブックスで探せます。

※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。