本番環境への誤操作を防ぐHooks
何をするHooksか
Section titled “何をするHooksか”本番環境(production)に向いているときに、データベースの破壊的操作やサーバーへの危険なコマンドをブロックします。
「ローカルで作業しているつもりだったが、.env が本番の接続先を指していた」「ClaudeがマイグレーションをかけたらテーブルがDROPされた」という事故を防ぎます。
※マイグレーション: データベースのスキーマ(テーブル構造)を安全に変更するための手順書。※Hooks: Claude Codeの特定の操作(ツール実行前後など)に独自のシェルコマンドを自動実行できる設定機能。
settings.json の実際のコード
Section titled “settings.json の実際のコード”環境チェック付き基本設定
Section titled “環境チェック付き基本設定”{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "~/.claude/hooks/production-guard.sh" } ] } ] }}本番ガードスクリプト
Section titled “本番ガードスクリプト”~/.claude/hooks/production-guard.sh:
#!/bin/bash
COMMAND=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.command')PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
# ===== 環境の検出 =====
detect_environment() { local env="unknown"
# .env.local を確認 if [ -f "${PROJECT_DIR}/.env.local" ]; then env=$(grep -E '^NODE_ENV=' "${PROJECT_DIR}/.env.local" | cut -d= -f2 | tr -d '"' | tr -d "'") fi
# .env を確認(フォールバック) if [ "$env" = "unknown" ] || [ -z "$env" ]; then if [ -f "${PROJECT_DIR}/.env" ]; then env=$(grep -E '^NODE_ENV=' "${PROJECT_DIR}/.env" | cut -d= -f2 | tr -d '"' | tr -d "'") fi fi
# DATABASE_URL に production のキーワードがないかも確認 if grep -qE 'prod|production' "${PROJECT_DIR}/.env" 2>/dev/null; then echo "production-suspected" return fi
echo "${env:-unknown}"}
ENVIRONMENT=$(detect_environment)
# ===== 本番環境での操作制限 =====
if [ "$ENVIRONMENT" = "production" ] || [ "$ENVIRONMENT" = "production-suspected" ]; then
# 完全ブロックするパターン BLOCKED_PATTERNS=( "DROP TABLE" "DROP DATABASE" "TRUNCATE" "prisma migrate" "db:migrate" "db:seed" "db:drop" "rake db:" )
for pattern in "${BLOCKED_PATTERNS[@]}"; do if echo "$COMMAND" | grep -qi "$pattern"; then echo "🚨 本番環境での危険な操作をブロックしました" echo "" echo "環境: ${ENVIRONMENT}" echo "ブロックされたコマンド: ${COMMAND}" echo "マッチしたパターン: ${pattern}" echo "" echo "本番でのデータベース操作を行う場合:" echo "1. バックアップを確認する" echo "2. メンテナンスモードにする" echo "3. 手動でターミナルから実行する" echo "4. 実行前後のスナップショットを記録する" exit 1 fi done
# 警告するパターン(ブロックはしないが通知) WARNING_PATTERNS=( "git push" "deploy" "helm upgrade" "kubectl apply" "systemctl restart" "service restart" )
for pattern in "${WARNING_PATTERNS[@]}"; do if echo "$COMMAND" | grep -qi "$pattern"; then echo "⚠️ 本番環境への操作です" echo "環境: ${ENVIRONMENT}" echo "コマンド: ${COMMAND}" echo "意図した操作か確認してください。" # exit 0 で続行 break fi donefi
# 問題なしexit 0chmod +x ~/.claude/hooks/production-guard.shファイル編集の保護
Section titled “ファイル編集の保護”本番の設定ファイルを誤って編集することも防げます。
{ "hooks": { "PreToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "~/.claude/hooks/protect-production-files.sh" } ] } ] }}~/.claude/hooks/protect-production-files.sh:
#!/bin/bash
FILE_PATH=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.file_path')
# 本番設定ファイルの保護PROTECTED_FILES=( ".env.production" ".env.prod" "config/production.yml" "config/database.yml" # 本番設定を含む可能性)
for protected in "${PROTECTED_FILES[@]}"; do if echo "$FILE_PATH" | grep -q "$protected"; then echo "🔒 本番設定ファイルの編集をブロックしました" echo "ファイル: $FILE_PATH" echo "" echo "このファイルを変更する場合は手動でエディタを開いてください。" exit 1 fidone
exit 0動作確認テスト
Section titled “動作確認テスト”正しく動作するか確認するためのテストコマンド:
# テスト1: ブロックされるべきコマンドをテストCLAUDE_TOOL_INPUT='{"command":"DROP TABLE users"}' \CLAUDE_PROJECT_DIR="/path/to/production-project" \~/.claude/hooks/production-guard.sh# → ブロックされること、exit code 1 を確認
# テスト2: 安全なコマンドをテストCLAUDE_TOOL_INPUT='{"command":"ls -la"}' \CLAUDE_PROJECT_DIR="/path/to/project" \~/.claude/hooks/production-guard.sh# → 続行されること、exit code 0 を確認
# exit codeを確認echo $?カスタマイズ例
Section titled “カスタマイズ例”Herokuのステージング/本番を区別
Section titled “Herokuのステージング/本番を区別”#!/bin/bash# Herokuのアプリ名から環境を判定COMMAND=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.command')
if echo "$COMMAND" | grep -q "heroku"; then # heroku コマンドのアプリ名を取得 APP_NAME=$(echo "$COMMAND" | grep -o '\-\-app [a-z0-9-]*' | awk '{print $2}')
if echo "$APP_NAME" | grep -q "production\|prod"; then echo "🚨 本番Herokuアプリへの操作をブロックしました" echo "アプリ: $APP_NAME" exit 1 fifiAWSのプロダクションアカウント保護
Section titled “AWSのプロダクションアカウント保護”#!/bin/bashCOMMAND=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.command')
# AWS CLIが本番アカウントを使っているか確認if echo "$COMMAND" | grep -q "aws "; then CURRENT_ACCOUNT=$(aws sts get-caller-identity --query Account --output text 2>/dev/null) PRODUCTION_ACCOUNT="123456789012" # 本番のAWSアカウントID
if [ "$CURRENT_ACCOUNT" = "$PRODUCTION_ACCOUNT" ]; then if echo "$COMMAND" | grep -qE '(delete|terminate|remove|destroy)'; then echo "🚨 本番AWSアカウントでの削除操作をブロックしました" exit 1 fi fifi※CLI: Command Line Interface の略。ターミナル(黒い画面)からコマンドを入力して操作するインターフェース。
環境の切り替えを習慣化する
Section titled “環境の切り替えを習慣化する”このHooksとあわせて、作業開始時に環境を確認する習慣も重要です。
# 作業開始時に確認cat .env.local | grep NODE_ENVcat .env.local | grep DATABASE_URL | sed 's/:.*/:[HIDDEN]/' # パスワードは隠す
# どの環境を見ているか常に表示するプロンプト設定# .bashrc/.zshrc に追加export PS1="[\$(cat .env.local 2>/dev/null | grep NODE_ENV | cut -d= -f2)] \$ "※プロンプト: AIへの指示文。Claude Codeへの指示の質がそのまま出力の質に影響する。