Claude Code の settings.json と settings.local.json で permissions を設計する
Claude Code の権限設定を settings.json で管理する方法を解説します。allow・deny・ask の書き方とパターン記法、ユーザー・プロジェクト・ローカルの優先順位、個人用 settings.local.json の役割と Git 管理から外れる仕組み、実務向けの推奨設定を紹介します。
目次
Claude Code は既定では、ファイルの編集やコマンドの実行のたびに確認を求めます。安全ではありますが、そのままでは作業のテンポが上がりません。かといって全許可にすると、rm -rf や git push --force のような取り返しのつかない操作まで自動で通ってしまいます。
この記事では、settings.json の permissions を使って「安全な操作は自動、危険な操作は確認か禁止」という線引きを作る方法と、チームで共有する settings.json と個人用の settings.local.json の役割分担を解説します。
KEY POINT
この記事で分かること
- settings.json の置き場所と優先順位
- allow / deny / ask の書き方とパターン記法
- 個人用の settings.local.json に何が書き込まれ、どう Git 管理から外れるか
- 個人開発・チーム開発それぞれの推奨設定
settings.json の置き場所と優先順位
| スコープ | パス | 用途 | Git 管理 |
|---|---|---|---|
| ユーザー | ~/.claude/settings.json | 全プロジェクト共通の既定 | しない |
| プロジェクト | .claude/settings.json | チームで共有するルール | する |
| ローカル | .claude/settings.local.json | 個人の追加許可。対話中の「今後も許可」の保存先 | しない |
| 管理者 | OS ごとの管理ポリシー配置先 | 組織が強制する設定(Enterprise 向け) | - |
複数のファイルに同じキーがある場合、管理者設定 → コマンドライン(claude --settings)→ ローカル → プロジェクト → ユーザーの順に強く、上位に書かれた同じキーが下位を上書きします。permissions のルールだけは別で、deny → ask → allow の順に評価され、先に一致したものが結果を決めます。そのため、チームで禁止したい操作をプロジェクトの deny に書いておけば、個人の allow で解除されることはありません。
permissions の基本構造
{
"permissions": {
"allow": [
"Read",
"Edit",
"Bash(npm run lint)",
"Bash(npm run test:*)",
"Bash(git diff:*)",
"Bash(git log:*)"
],
"ask": [
"Bash(git push:*)",
"Bash(npm install:*)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(rm -rf:*)",
"Bash(git push --force:*)"
],
"defaultMode": "acceptEdits"
}
}
| キー | 意味 |
|---|---|
allow | 確認なしで実行を許可するルール |
ask | 必ず確認を求めるルール(allow に一致しても確認する) |
deny | 実行を禁止するルール。最優先 |
defaultMode | ルールに一致しなかった操作の扱い。default(都度確認)、acceptEdits(ファイル編集は自動許可)、plan(読み取りのみ)、bypassPermissions(すべて許可。隔離環境専用) |
ルールの書き方
ルールは ツール名(パターン) の形で書きます。パターンを省略するとそのツール全体が対象です。
| 書き方 | 意味 |
|---|---|
Bash(npm run test:*) | npm run test で始まるコマンドすべて(:* が前方一致) |
Bash(git commit *) | スペース区切りの引数を含む git commit |
Read(./.env) | プロジェクト直下の .env の読み取り |
Edit(src/**) | src 配下のファイル編集 |
WebFetch(domain:docs.example.com) | 指定ドメインへの取得 |
mcp__github__create_issue | MCP サーバー github の create_issue ツール |
mcp__github | MCP サーバー github の全ツール |
Bash のパターンは「コマンド文字列」に対する一致
Bash(rm -rf:*) は rm -rf で始まるコマンドを対象にしますが、sudo rm -rf や cd /tmp && rm -rf のように先頭が変わると一致しません。deny は「保険」として置き、本当に守りたいファイルはファイルシステムの権限やコンテナ側でも保護してください。
settings.json と settings.local.json の役割分担
.claude/ ディレクトリには、settings.json のほかに settings.local.json というファイルができていることがあります。Claude Code が自動生成する個人用の設定ファイルで、チームで共有する settings.json とは役割が違います。
| 項目 | .claude/settings.json | .claude/settings.local.json |
|---|---|---|
| 役割 | プロジェクト共通の設定 | 個人の追加設定 |
| Git 管理 | する | しない(Claude Code が作成時にグローバルの除外設定へ追加する) |
| 作られ方 | 手で作る | 「今後も許可」を選ぶと自動生成 |
| 優先順位 | ローカルより低い | プロジェクトより高い(ただし deny は常に最優先) |
「今後も許可」で何が起きるか
対話中に確認ダイアログで「今後も許可する」を選ぶと、そのコマンドのパターンが settings.local.json の allow に追記されます。
{
"permissions": {
"allow": [
"Bash(npm run test:*)",
"Bash(git diff:*)"
]
}
}
気付かないうちに allow が増えていくため、/permissions コマンドで定期的に確認し、不要なものは削除してください。「あのコマンドが確認なしで走るのはなぜか」と思ったら、まずこのファイルを見ます。設定の読み込み元が分からないときは claude config list や /status で確認できます。
どちらに何を書くか
| 設定 | 書く場所 |
|---|---|
| チーム全員に守らせたい deny(秘密情報の読み取り禁止、force push 禁止) | settings.json |
| 誰が実行しても安全な allow(lint、テスト) | settings.json |
| 共有 hooks(編集後の format) | settings.json |
自分の作業速度のための allow(git commit、npm install) | settings.local.json |
自分だけの defaultMode(acceptEdits など) | settings.local.json |
| ローカル環境固有の hooks や環境変数 | settings.local.json |
チームの settings.json は慎重側に倒し、速く進めたい人は settings.local.json で上書きする、という分担が扱いやすいです。
Git 管理から外れる仕組み
ここは誤解されやすい点です。Claude Code はリポジトリの .gitignore を書き換えません。まだ無視されていない git リポジトリで settings.local.json を初めて書き出すとき、グローバルの git 除外ファイルに **/.claude/settings.local.json を追加します。これによって、どのリポジトリでもこのファイルがコミットに入らなくなります。
対象のファイルは、グローバルの git 設定で core.excludesFile が絶対パスか ~ 始まりのパスに設定されていればそれ、設定されていなければ $XDG_CONFIG_HOME/git/ignore、XDG_CONFIG_HOME が未設定なら ~/.config/git/ignore です。
グローバルの除外設定はリポジトリに付いていかない
除外パターンが自分のグローバル設定にあるため、リポジトリをクローンしたチームメンバーには引き継がれません。自分で手作りして Claude Code がまだ書き込んでいない場合は、そもそも何も除外されていません。全員に効かせるなら、リポジトリの .gitignore にも書いてください。
.claude/settings.local.json
CLAUDE.local.mdGit 管理外とはいえ、hooks の command に API キーを直接書くのは避けてください。環境変数から読ませる形にします。
推奨設定、個人開発
編集は自動許可し、外部に影響する操作だけ確認する構成です。
{
"permissions": {
"defaultMode": "acceptEdits",
"allow": [
"Bash(npm run *)",
"Bash(npx tsc *)",
"Bash(git status)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Bash(git add:*)",
"Bash(git commit:*)"
],
"ask": [
"Bash(git push:*)",
"Bash(npm install:*)",
"Bash(npm uninstall:*)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Bash(rm -rf:*)",
"Bash(git push --force:*)",
"Bash(git reset --hard:*)"
]
}
}
推奨設定、チーム開発
.claude/settings.json には全員に適用したい deny と、誰が実行しても安全な allow だけを入れます。個人の好みは settings.local.json に任せます。
{
"permissions": {
"allow": [
"Bash(pnpm lint)",
"Bash(pnpm test:*)",
"Bash(pnpm typecheck)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./infra/secrets/**)",
"Edit(./.github/workflows/**)",
"Bash(git push --force:*)",
"Bash(git push -f:*)",
"Bash(rm -rf:*)",
"Bash(curl:*)",
"Bash(wget:*)"
]
}
}
curl や wget を deny に入れているのは、任意の URL からのダウンロードや外部へのデータ送信を防ぐためです。必要なら ask に移してください。
関連する設定
npm scripts の自動許可、git push の確認、force push の禁止を 1 つの設定にまとめた実例は Claude Code の permissions 設定例 にあります。権限だけでなく、hooks で「編集後に自動で lint を走らせる」仕組みを組み合わせると、自動許可の範囲を広げても品質を保ちやすくなります(hooks で lint と format を自動実行する)。秘密情報の保護は AI コーディングツールに秘密情報を読ませないための設定 で扱っています。
まとめ
- 設定はユーザー → プロジェクト → ローカルの順に上書きされ、permissions の deny は常に最優先
Bash(npm run test:*)のように「ツール名(パターン)」で書くsettings.jsonはチーム共有(Git 管理)、settings.local.jsonは個人用。「今後も許可」はローカルの allow に追記されるので/permissionsで定期的に見直すsettings.local.jsonはリポジトリの.gitignoreではなくグローバルの git 除外設定で外れる。全員に効かせるなら.gitignoreにも書くdefaultMode: "acceptEdits"と少数の allow から始め、危険な操作は deny に入れる
よくある質問
- settings.json と settings.local.json の違いは何ですか?
- settings.json はチームで共有する設定(Git 管理)、settings.local.json は個人用の設定(Git 管理外)です。同じキーがある場合はローカルが優先されますが、permissions の deny はどこに書かれていても最優先です。
- deny と allow の両方に一致した場合はどうなりますか?
- deny が優先されます。ルールは deny → ask → allow の順に評価されるため、危険な操作は deny に書いておけば、allow の書き方を誤っても実行されません。
- 対話中に許可した内容はどこに保存されますか?
- 「今後も許可」を選ぶと .claude/settings.local.json の allow に追記されます。/permissions コマンドで一覧と編集ができます。
- settings.local.json は Git にコミットされますか?
- Claude Code が作成したものなら入りません。ただし追加先はリポジトリの .gitignore ではなく、グローバルの git 除外ファイルです。自分で手作りした場合は .gitignore に自分で追加してください。
読者からの質問と回答
Q. 権限プロンプトで「Yes, and don't ask again」を選ぶと、どこまで許可したことになりますか。セッション全体の権限モードまで変わってしまうのでしょうか。
許可の範囲は ツールの種類で変わります。公式ドキュメントの表がそのまま答えになっています。
| ツールの種類 | 「Yes, and don't ask again」の効果 |
|---|---|
| 読み取り専用(ファイル読み取り、Grep) | 該当なし(そもそも確認されない) |
| Bash コマンド | リポジトリごと・コマンドごとに恒久的 |
| ファイル編集(Edit / Write) | セッション終了まで |
| WebFetch | リポジトリごと・ドメインごとに恒久的 |
| WebSearch | リポジトリごとに恒久的 |
恒久的に保存される場合の保存先は、git リポジトリのルートの .claude/settings.local.json です。worktree から実行した場合もメインのチェックアウトに解決されます。ファイル編集の承認はファイルに保存されません。 表のとおりセッション終了までの効果です。
セッションの権限モードについては、公式ドキュメントに「don't ask again を選ぶとモードが変わる」という記述はありません。モードを変える選択肢は別に用意されていて、プロンプトの 3 番目に出る 「Yes, and switch to auto mode」 がそれです。これはすべてのプロンプトに出るわけではない、とドキュメントに明記されています。
現在のモードは Shift+Tab で切り替えられ、ルールの一覧は /permissions で確認できます。意図せず変わっていないか確かめたいときは、この 2 つで確認してください。
複合コマンドを承認したときの挙動も知っておくと役立ちます。git status && npm test を承認すると、承認が必要なサブコマンドごとに別々のルールが保存されます。この例では npm test のルールが保存されるため、&& の前に何が来ても認識されます。1 つの複合コマンドから保存されるルールは最大 5 件です。
ファイルパスを承認した場合は、[、]、* などの gitignore のパターン文字がエスケープされ、承認したパスだけに一致するルールになります。自分で書いたルールはエスケープされません。
プロンプトから保存したルールは「表示されたものだけ」をカバーする
一度だけの承認しか選べないプロンプトもあります。公式ドキュメントは、許可する内容をすべて画面に表示できる場合にだけ「don't ask again」の選択肢を出す、と説明しています。より広いルールが必要なら /permissions で自分で書きます。
ルールの書き方と優先順位は Claude Code の settings.json で権限を設定する方法 にまとめてあります。
Q. acceptEdits モードで、--add-dir と allow ルールまで足したのに .git/ 配下への書き込みが通りません。設定が足りないのでしょうか?
設定が足りないわけではありません。.git は 保護パス(protected paths) で、permissions.allow では通せない仕組みになっています。公式ドキュメントに明記されています。
permissions.allowrules in settings files do not pre-approve protected-path writes. The safety check runs before Claude Code evaluates allow rules from settings.(設定ファイルの
permissions.allowルールは、保護パスへの書き込みを事前承認しません。この安全性チェックは、Claude Code が設定ファイルの allow ルールを評価する 前 に動きます。)
順序が逆なので、Edit(.git/**) のような allow ルールを足しても結果は変わりません。--add-dir も作業範囲を広げるだけで、保護パスの判定には効きません。
モードごとの挙動は次のとおりです。
| モード | 保護パスへの書き込み |
|---|---|
default、acceptEdits | 確認プロンプトが出る |
plan | 対話的なターミナルで bypass permissions が使える場合は許可。それ以外は auto モードが使えるなら分類器へ、使えないなら確認 |
auto | 分類器へ回される |
dontAsk | 拒否される |
bypassPermissions | 許可される |
acceptEdits では「自動承認されない」のであって「禁止」ではありません。確認プロンプトに答えれば書き込めます。プロンプトを表示できない経路(dontAsk や、確認を出せない実行環境)では拒否として見えます。
保護ディレクトリは .git だけではありません。
.git .config/git .vscode .idea .husky .cargo
.devcontainer .yarn .mvn .claude(一部例外あり)
保護ファイルも指定されており、.gitconfig、.gitmodules、シェルの設定(.bashrc、.zshrc、.envrc など)、パッケージマネージャの設定(.npmrc、.yarnrc、bunfig.toml など)、.pre-commit-config.yaml、.mcp.json、.claude.json が含まれます。
注意
--restricted を付けて起動したセッション(v2.1.248 以降)では、分類器も保護パスへの書き込みを承認できません。auto モードでも通らなくなります。
どうしても自動で書き込みたい場合、公式に用意されているのは bypassPermissions モードだけです。ただしこのモードは保護パスの確認ごと飛ばすため、ドキュメントはコンテナや VM のような隔離環境に限って使うよう求めています。.git を書き換える作業は、Claude に任せず git コマンド経由で行うほうが安全です。
ルールの書き方と評価順序は Claude Code の settings.json で権限を設定する にまとめています。
Q. 「このフォルダの中だけで作業して」と指示したのに、Claude Code が ~/.claude/ 配下の別のファイルを許可なく編集しました。作業範囲を本当に守らせるにはどうしますか?
文章で「このフォルダだけ」と伝えても、それは境界になりません。Claude Code の作業範囲を決めるのは、起動したディレクトリと、そこに追加したディレクトリです。公式ドキュメントにはこうあります。
By default, Claude has access to files in the directory where you launched it.
(既定では、Claude は起動したディレクトリの中のファイルにアクセスできます。)
プロジェクトの中で起動していれば、その配下すべてが対象です。プロンプトでサブフォルダ名を挙げても、対象が狭まるわけではありません。~/.claude/settings.json のようにホーム配下のファイルが編集された場合は、別の経路(ホームディレクトリで起動した、--add-dir で追加した、additionalDirectories に入っている)で範囲に入っていたと考えられます。現在の範囲は /status で確認できます。
本当に止めたい場合は、設定で縛ります。
{
"permissions": {
"deny": [
"Edit(~/.claude/**)",
"Edit(//**)"
],
"ask": [
"Edit"
],
"blockReadsOutsideWorkingDirectories": true
}
}
注意
パスのルールは Edit(path) と Read(path) でしか評価されません。公式ドキュメントには「Claude Code はファイルの権限を Edit(path) と Read(path) のルールに対してのみ照合する」とあり、Write、NotebookEdit、Glob にパスを書いても受け付けられるが参照されず、起動時に警告が出ます。Write(docs/**) ではなく Edit(docs/**) と書いてください。
評価の順序は deny → ask → allow で、最初に一致したものが結果を決めます。ルールの具体性は順序を変えないので、広い deny は狭い allow より優先されます。
permissions.blockReadsOutsideWorkingDirectories を true にすると、囲った範囲の外のパスをすべての権限モードでファイルツールが拒否します。auto モードでは、作業ディレクトリ外を最初に読もうとしたときに Claude Code 側から有効化を提案します。
作業範囲そのものを狭めたいなら、対象のフォルダで起動するか、/cd <パス> でセッションごと移動します。設定全体の組み立ては Claude Code の settings.json で権限を設定する を参照してください。
Q. Claude Code の deny で .env を禁止しても、settings.local.json の allow で読めてしまうことはありますか?
ありません。deny はどのスコープ(ユーザー / プロジェクト / ローカル)に書かれていても allow より優先されます。プロジェクトの .claude/settings.json に次を書いておけば、個人の settings.local.json で Read を広く許可していても .env は読まれません。
{
"permissions": {
"deny": ["Read(./.env)", "Read(./.env.*)"]
}
}
ただし deny は Claude Code のツール呼び出しに対する制御で、cat .env のようなシェルコマンド経由の読み取りは別ルールです。Bash(cat .env:*) のような前方一致は回避されやすいので、確実に守りたい値は .env をワークスペースの外に置くか、シークレットマネージャーから実行時に注入してください。
参考にした一次情報
この記事は公式ドキュメントを基に AI が下書きを作成し、運営者が内容を確認して公開しています。誤りを見つけた場合は お問い合わせからお知らせください。