はじめに
Claude Codeを使っていると、「このコマンドを実行してもよいですか?」という確認ダイアログが頻繁に表示されます。セキュリティのために大切な仕組みですが、信頼できるコマンドまで毎回確認を求められるのは煩わしいものです。
権限設定を適切に行えば、安全なコマンドは自動で許可しつつ、危険な操作はしっかりブロックできます。この記事では、プロジェクトに合った権限設定の設計方法を解説します。
権限システムの概要
Claude Codeはツールを使ってファイルの読み書きやコマンド実行を行います。各ツールには権限レベルが設定されており、ツールの種類によって承認の要否が異なります。
| ツールの種類 | 例 | 承認 |
|---|---|---|
| 読み取り専用 | ファイル読み取り、Grep | 不要 |
| Bashコマンド | シェルコマンド実行 | 必要 |
| ファイル変更 | ファイルの編集・作成 | 必要 |
Bashコマンドで「はい、今後は聞かない」を選ぶと、そのコマンドパターンが自動許可されます。しかし、毎回手動で許可するのではなく、あらかじめ設定ファイルで管理するのが効率的です。
3つの権限ルール
権限ルールには3種類があり、deny > ask > allow の優先順位で評価されます。
| ルール | 動作 | 用途 |
|---|---|---|
| allow | 確認なしで許可 | よく使う安全なコマンド |
| ask | 毎回確認を表示 | 注意が必要なコマンド |
| deny | 実行をブロック | 危険なコマンド |
いずれかの設定レベルでdenyに指定されたツールは、他のレベルでallowに指定されていてもブロックされます。denyルールは常に最優先で評価されます。
settings.jsonの構造
権限設定は settings.json に記述します。設定ファイルは3つのレベルがあり、それぞれ異なる範囲に適用されます。
| レベル | ファイルパス | 対象範囲 | 共有 |
|---|---|---|---|
| ユーザー | ~/.claude/settings.json | すべてのプロジェクト | 個人のみ |
| プロジェクト | .claude/settings.json | リポジトリ全体 | gitでチーム共有 |
| ローカル | .claude/settings.local.json | リポジトリ内の自分のみ | gitignored |
設定の基本形は以下の通りです。
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(git status *)"
],
"deny": [
"Bash(rm -rf *)",
"Read(./.env)"
]
}
}allowリストの設計パターン
フロントエンドプロジェクト向け
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(npm test *)",
"Bash(npx tsc *)",
"Bash(npx eslint *)",
"Bash(npx prettier *)",
"Bash(git status *)",
"Bash(git diff *)",
"Bash(git log *)",
"Bash(git add *)",
"Bash(git commit *)"
],
"deny": [
"Bash(npm publish *)",
"Bash(git push *)",
"Bash(rm -rf *)",
"Read(./.env)",
"Read(./.env.*)"
]
}
}バックエンドプロジェクト向け
{
"permissions": {
"allow": [
"Bash(python -m pytest *)",
"Bash(python -m mypy *)",
"Bash(python -m ruff *)",
"Bash(docker compose up *)",
"Bash(docker compose down *)",
"Bash(docker compose logs *)",
"Bash(git status *)",
"Bash(git diff *)",
"Bash(git log *)",
"Bash(git add *)",
"Bash(git commit *)"
],
"deny": [
"Bash(docker push *)",
"Bash(git push *)",
"Bash(rm -rf *)",
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
]
}
}* は任意の文字列にマッチします。Bash(npm run *) は npm run build や npm run test などすべてのnpm runコマンドに一致します。* の前のスペースは重要で、Bash(ls *) は ls -la にマッチしますが lsof にはマッチしません。
denyリストで危険なコマンドをブロック
denyリストには、実行されると取り返しのつかない影響がある操作を登録します。以下は多くのプロジェクトで共通して設定すべき項目です。
{
"permissions": {
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force *)",
"Bash(git reset --hard *)",
"Bash(curl *)",
"Bash(wget *)",
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Read(~/.ssh/**)",
"Read(~/.aws/**)"
]
}
}ベアツール名(Bash のみ)でdenyすると、そのツール自体がClaudeのコンテキストから削除されます。一方、Bash(rm -rf *) のようにパターンを指定すると、そのパターンに一致する呼び出しだけがブロックされます。
.claude/settings.json と .claude/settings.local.json の使い分け
チーム共有の設定を .claude/settings.json に書く
プロジェクト全体のセキュリティルールや、チーム標準のツールコマンドは .claude/settings.json に記述します。このファイルはgitにコミットして全員に適用します。
{
"permissions": {
"allow": [
"Bash(npm run *)",
"Bash(npm test *)",
"Bash(git status *)",
"Bash(git diff *)",
"Bash(git log *)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force *)",
"Read(./.env)",
"Read(./.env.*)"
]
}
}個人設定を .claude/settings.local.json に書く
デバッグ用の設定やUI設定など、個人の好みに関わるものは .claude/settings.local.json に記述します。このファイルはgitignoreされるため、チームには影響しません。
{
"verbose": true,
"theme": "dark",
"permissions": {
"allow": [
"Bash(docker compose *)"
]
}
}設定をバージョン管理する
.claude/settings.json をコミットし、.claude/settings.local.json が .gitignore に含まれていることを確認します。
git add .claude/settings.json
git commit -m "Claude Codeのチーム共有権限設定を追加"| 設定の内容 | 保存先 | 理由 |
|---|---|---|
| セキュリティルール(deny) | .claude/settings.json | チーム全体で統一する |
| 開発ツール許可(allow) | .claude/settings.json | チームの標準ツールを共有する |
| 個人のデバッグ設定 | .claude/settings.local.json | 他のメンバーに影響しない |
| 個人の追加allow設定 | .claude/settings.local.json | 個人のワークフローに合わせる |
よくある権限エラーとその対処法
1. 許可したはずのコマンドがブロックされる
症状: allowリストに追加したコマンドなのに、実行時にブロックされる。
原因: 別の設定レベルにdenyルールが存在する。deny > ask > allowの順で評価されるため、どこか1箇所でもdenyに設定されていれば実行できません。
対処法: /permissions コマンドで全レベルのルールを確認し、対象コマンドがdenyに含まれていないかチェックします。
/permissions
2. 複合コマンドで権限エラーが出る
症状: npm test && npm run build のような複合コマンドで権限エラーが表示される。
原因: Claude Codeは &&、||、;、| で区切られた各サブコマンドを個別に評価します。すべてのサブコマンドがallowリストに含まれている必要があります。
対処法: 各コマンドを個別にallowリストに追加します。
{
"permissions": {
"allow": [
"Bash(npm test *)",
"Bash(npm run build *)"
]
}
}3. Read/Editの権限パターンが意図通りに動かない
症状: Read(./src/*) を許可したのに、src/components/Button.tsx の読み取りで確認が表示される。
原因: * は1つのディレクトリ内のファイルのみにマッチします。サブディレクトリを含めるには ** を使います。
対処法: ディレクトリ全体を対象にする場合は ** を使用します。
{
"permissions": {
"allow": [
"Read(./src/**)",
"Edit(./src/**)"
]
}
}現在の権限設定を一覧で確認するには、Claude Codeで /permissions コマンドを実行します。どのファイルからどのルールが読み込まれているかを確認でき、問題の原因特定に役立ちます。
まとめ
- 権限設定は
settings.jsonのpermissionsセクションで管理する - allowリストで安全なコマンドを自動許可し、denyリストで危険な操作をブロックする
- denyルールは他のすべてのルールより優先される
- チーム共有の設定は
.claude/settings.jsonに、個人設定は.claude/settings.local.jsonに分ける /permissionsコマンドで現在の権限設定を確認できる