Skip to content

本番環境への誤操作を防ぐHooks

本番環境(production)に向いているときに、データベースの破壊的操作やサーバーへの危険なコマンドをブロックします。

「ローカルで作業しているつもりだったが、.env が本番の接続先を指していた」「ClaudeがマイグレーションをかけたらテーブルがDROPされた」という事故を防ぎます。

マイグレーション: データベースのスキーマ(テーブル構造)を安全に変更するための手順書。Hooks: Claude Codeの特定の操作(ツール実行前後など)に独自のシェルコマンドを自動実行できる設定機能。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/production-guard.sh"
}
]
}
]
}
}

~/.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
done
fi
# 問題なし
exit 0
Terminal window
chmod +x ~/.claude/hooks/production-guard.sh

本番の設定ファイルを誤って編集することも防げます。

{
"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
fi
done
exit 0

正しく動作するか確認するためのテストコマンド:

Terminal window
# テスト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 $?

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
fi
fi

AWSのプロダクションアカウント保護

Section titled “AWSのプロダクションアカウント保護”
#!/bin/bash
COMMAND=$(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
fi
fi
CLI: Command Line Interface の略。ターミナル(黒い画面)からコマンドを入力して操作するインターフェース。

このHooksとあわせて、作業開始時に環境を確認する習慣も重要です。

Terminal window
# 作業開始時に確認
cat .env.local | grep NODE_ENV
cat .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への指示の質がそのまま出力の質に影響する。