Tips & Tricks

Claude Code 権限設定完全ガイド|settings.json・Hooks・allowlist を徹底解説

Claude Code の権限設定を完全解説。allow/deny/ask の使い分け、Hooksによる自動化、環境別settings.json、実践パターン集まで動くコードで紹介。

Claude Code は非常に強力なファイル操作・コマンド実行能力を持っています。その力を安全に制御するのが 権限設定 (permissions) です。「なんとなく使っている」状態から脱して、意図通りに動く Claude Code を設計しましょう。

この記事では、.claude/settings.json の全設定項目、Hooks の実装パターン、環境別の権限設計まで、動くコードで徹底解説します。

権限設定の全体像

Claude Code の権限は 3レベル で制御します。

レベルキー動作
許可allow確認ダイアログなしで自動実行
確認ask毎回ユーザーの承認を要求
拒否deny一切実行できない (エラーで弾く)

設定は .claude/settings.json に書きます。プロジェクト直下に置けば git 管理でチーム共有でき、~/.claude.json に置けばグローバル設定になります。

優先順位 (高い順):
プロジェクト .claude/settings.json
    > グローバル ~/.claude.json
        > デフォルト (全て ask)

settings.json の基本構造

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Bash(npm run *)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(git push --force*)"
    ],
    "ask": [
      "Write(**)",
      "Edit(**)",
      "Bash(git commit*)"
    ]
  },
  "hooks": {
    "PreToolUse": [],
    "PostToolUse": []
  }
}

ツール名とパターン構文

権限設定に書くのは 「ツール名(引数パターン)」 の形式です。

主要ツール一覧

ツール名内容
Readファイル読み取り
Writeファイル新規作成
Edit既存ファイルの部分変更
Bashシェルコマンド実行
Globファイルパターン検索
Grep内容検索
WebFetchURL 取得
Agentサブエージェント起動

パターン構文

"Read(**)"          // 全ファイルの読み取りを許可
"Read(src/**)"      // src/ 以下のみ許可
"Read(*.md)"        // .md ファイルのみ許可
"Bash(npm run *)"   // npm run ではじまるコマンドのみ許可
"Bash(git *)"       // git コマンド全般を許可
"Bash(rm -rf *)"    // rm -rf を拒否

** はディレクトリを含む全パスに、* は単一セグメントにマッチします。

実践パターン集

パターン1: 個人開発 (比較的自由)

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Bash(npm *)",
      "Bash(git log*)",
      "Bash(git diff*)",
      "Bash(git status*)",
      "Bash(git add*)",
      "Bash(node *)",
      "Bash(echo *)",
      "Bash(cat *)",
      "Bash(ls *)"
    ],
    "deny": [
      "Bash(rm -rf /)",
      "Bash(rm -rf ~*)",
      "Bash(git push --force *main*)",
      "Bash(git push --force *master*)"
    ],
    "ask": [
      "Write(**)",
      "Edit(**)",
      "Bash(git commit*)",
      "Bash(git push*)",
      "Bash(rm *)"
    ]
  }
}

パターン2: チーム開発 (セキュリティ重視)

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Bash(npm run lint)",
      "Bash(npm run test)",
      "Bash(npm run typecheck)",
      "Bash(git log*)",
      "Bash(git diff*)",
      "Bash(git status*)",
      "Bash(git branch*)"
    ],
    "deny": [
      "Bash(rm -rf*)",
      "Bash(git push --force*)",
      "Bash(git push -f*)",
      "Bash(git reset --hard*)",
      "Bash(git rebase *main*)",
      "Bash(git rebase *master*)",
      "Bash(DROP *)",
      "Bash(TRUNCATE *)",
      "Bash(curl * | bash)",
      "Bash(wget * | sh)"
    ],
    "ask": [
      "Write(**)",
      "Edit(**)",
      "Bash(git commit*)",
      "Bash(git push*)",
      "Bash(git add*)",
      "Bash(npm install*)",
      "Bash(*deploy*)"
    ]
  }
}

パターン3: 本番環境 (読み取り専用)

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Bash(git log*)",
      "Bash(git diff*)",
      "Bash(git status*)",
      "Bash(git show*)",
      "Bash(cat *)",
      "Bash(ls *)",
      "Bash(ps *)",
      "Bash(df *)",
      "Bash(top *)"
    ],
    "deny": [
      "Write(**)",
      "Edit(**)",
      "Bash(git push*)",
      "Bash(git commit*)",
      "Bash(git reset*)",
      "Bash(rm *)",
      "Bash(mv *)",
      "Bash(*deploy*)",
      "Bash(*restart*)",
      "Bash(*kill *)"
    ],
    "ask": []
  }
}

本番環境ではこれを CLAUDE_SETTINGS=.claude/settings.production.json claude で指定します。

パターン4: コンテンツ生成専用 (このサイトで使っているパターン)

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

Write(site/src/content/**) のように 書き込みを特定ディレクトリに制限 するのがポイントです。

Hooks: 権限の前後に処理を挟む

Hooks はツール実行の 前後に自動でコマンドを実行 する仕組みです。セキュリティチェックや自動整形に使えます。

PreToolUse: 実行前フック

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git add*)",
        "hooks": [{
          "type": "command",
          "command": "git diff --cached --name-only | grep -E '^\\.env' && echo '🚨 .env の追加を検出!' && exit 1 || exit 0"
        }]
      },
      {
        "matcher": "Bash(git commit*)",
        "hooks": [{
          "type": "command",
          "command": "node scripts/secret-scan.mjs"
        }]
      },
      {
        "matcher": "Bash(rm*)",
        "hooks": [{
          "type": "command",
          "command": "echo '⚠️ 削除コマンドを検出。5秒後に実行します。Ctrl+C で中止。' && sleep 5"
        }]
      }
    ]
  }
}

フックコマンドが exit code 1 を返すとツールの実行がブロック されます。これが最も重要なポイントです。

PostToolUse: 実行後フック

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [{
          "type": "command",
          "command": "npx tsc --noEmit 2>&1 | head -20 || true"
        }]
      },
      {
        "matcher": "Bash(git commit*)",
        "hooks": [{
          "type": "command",
          "command": "git log --oneline -3"
        }]
      }
    ]
  }
}

PostToolUse は 実行後の確認や副作用 に使います。ファイル編集後に自動で型チェック、コミット後に最新3件のログを表示するなど。

実用的な Hooks レシピ集

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(npm install*)",
        "hooks": [{
          "type": "command",
          "command": "echo '📦 パッケージを追加します。package.json を確認してください。'"
        }]
      },
      {
        "matcher": "Bash(*deploy*)",
        "hooks": [{
          "type": "command",
          "command": "read -p '🚀 デプロイを実行します。続けますか? [y/N] ' ans && [ \"$ans\" = 'y' ] || exit 1"
        }]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write(*.ts)|Edit(*.ts)",
        "hooks": [{
          "type": "command",
          "command": "npx eslint --fix $CLAUDE_TOOL_INPUT_FILE_PATH 2>/dev/null || true"
        }]
      }
    ]
  }
}

Permission Modes: 起動時の権限レベル

claude コマンドの起動時にモードを指定することもできます。

# 通常モード (settings.json に従う)
claude

# 全ての操作を自動承認 (危険! 信頼できる環境のみ)
claude --dangerously-skip-permissions

# 特定の操作のみスキップ
claude --allowedTools "Read,Grep,Glob"

# 非対話モード (CI/CD で使用)
claude -p "テストを実行して結果を報告して" --dangerously-skip-permissions

--dangerously-skip-permissionsCI/CD の自動実行 や完全に把握した自動化スクリプトでのみ使用し、日常的な対話では避けるべきです。

設定ファイルの優先順位と上書き

複数の設定ファイルが存在する場合:

~/.claude.json              ← グローバル (全プロジェクト共通)
    +
.claude/settings.json       ← プロジェクト (git管理)
    +
.claude/settings.local.json ← 個人上書き (gitignore推奨)
    =
マージされた設定が適用される

個人用の追加設定.claude/settings.local.json に書いて gitignore します。チームの deny リストを個人設定で上書きできないよう、deny は settings.json のみに書く のが安全な設計です。

# .gitignore に追加
.claude/settings.local.json

落とし穴5選

1. パターンのワイルドカードを間違える

// ❌ これは "git" という単一コマンドにしかマッチしない
"Bash(git)"

// ✅ git 以降の引数も含めてマッチ
"Bash(git *)"
"Bash(git*)"  // スペースなしでも動くが * で明示するほうが安全

2. deny が ask より優先されることを忘れる

// この設定で Bash(rm -rf /tmp/test) は deny に引っかかってブロックされる
// ask には到達しない
{
  "deny": ["Bash(rm -rf*)"],
  "ask": ["Bash(rm*)"]  // ← rm -rf は deny 側で処理される
}

3. Hooks の exit code を意識していない

# PreToolUse フックのコマンドが常に exit 0 を返すと
# スキャンが失敗してもブロックできない

# ❌ エラーでも通ってしまう
"command": "node scan.mjs"

# ✅ 明示的に exit code を制御
"command": "node scan.mjs || exit 1"

4. settings.json を gitignore してしまう

チームで共有するために git 管理したい settings.json を誤って .gitignore に入れてしまうケースがあります。プロジェクト設定は git 管理、個人設定の settings.local.json のみ gitignore が正解です。

5. 本番環境設定を手動で切り替えるのを忘れる

# ❌ 普段使いの設定のまま本番作業してしまう

# ✅ 本番作業前に明示的に設定を切り替える
CLAUDE_SETTINGS=.claude/settings.production.json claude

エイリアスを登録しておくと忘れにくい:

# ~/.bashrc or ~/.zshrc
alias claude-prod='CLAUDE_SETTINGS=.claude/settings.production.json claude'

設定のデバッグ方法

「なぜこのコマンドがブロックされるのか」がわかりにくい場合:

# 現在の設定を確認
claude --print-settings 2>/dev/null || cat .claude/settings.json

# どのルールにマッチしているか確認 (verbose モード)
claude --verbose -p "git push を実行して"

まとめ: 設定設計のベストプラクティス

1. まず deny から決める
   → 絶対に実行させたくないコマンドを列挙
   → rm -rf, git push --force, DROP TABLE は必須

2. 次に ask を設定
   → 本人確認が必要な「書き込み系・デプロイ系」

3. 残りを allow
   → 読み取り系・CI系は全部 allow で効率化

4. Hooks でセキュリティ自動化
   → コミット前スキャン、型チェック後自動実行

5. 環境別設定ファイルを用意
   → settings.json (開発), settings.production.json (本番)

権限設定を適切に入れると、「承認ボタンを機械的に押す」習慣がなくなり、本当に確認が必要な操作だけに集中できるようになります。最初の30分で設計しておけば、その後の数百時間の作業が安全になります。

関連記事

参考資料

#claude-code #permissions #security #hooks #settings #configuration

Claude Codeをもっと活用しませんか?

実務で使えるプロンプトテンプレート50選。コピペですぐ使えます。

無料プレゼント

無料PDF: Claude Code 5分でわかるチートシート

メールアドレスを登録するだけで、A4 1枚のチートシートPDFを今すぐお送りします。

個人情報は厳重に管理し、スパムは送りません。

Masa

この記事を書いた人

Masa

現役DX室長|Claude Code でゼロから多言語AI技術メディア運営中。実務直結の自動化、AI開発相談・研修受付中。

PR

関連書籍・参考図書

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

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