#!/bin/bash # Install Gitleaks Pre-Commit Hook # Created in response to Anthropic API key exposure incident (2025-10-21) # Implements inst_070: Pre-Commit Secret Detection set -e echo "═══════════════════════════════════════════════════════════" echo " INSTALL GITLEAKS PRE-COMMIT HOOK" echo "═══════════════════════════════════════════════════════════" echo "" # Check if gitleaks is installed echo "▶ 1. Checking gitleaks installation..." if ! command -v gitleaks &> /dev/null; then echo " ✗ gitleaks not found" echo "" echo " Please install gitleaks first:" echo "" echo " macOS (Homebrew):" echo " brew install gitleaks" echo "" echo " Ubuntu/Debian:" echo " sudo apt-get update" echo " sudo apt-get install gitleaks" echo "" echo " Or download from: https://github.com/gitleaks/gitleaks/releases" echo "" exit 1 fi GITLEAKS_VERSION=$(gitleaks version 2>&1 | head -1 || echo "unknown") echo " ✓ gitleaks found: $GITLEAKS_VERSION" echo "" # Check if we're in a git repository echo "▶ 2. Checking git repository..." if [ ! -d .git ]; then echo " ✗ Not a git repository (no .git directory found)" echo " Run this script from the root of your git repository" exit 1 fi echo " ✓ Git repository detected" echo "" # Create .gitleaksignore if it doesn't exist echo "▶ 3. Creating .gitleaksignore file..." if [ -f .gitleaksignore ]; then echo " ⚠ .gitleaksignore already exists (not overwriting)" else cat > .gitleaksignore << 'EOF' # Gitleaks Ignore File # Created: 2025-10-21 (Post-breach security enhancement) # # Add false positives here with explanations # Format: regex pattern (one per line) # # Example: # sk-ant-api03-EXAMPLE-REDACTED-NEVER-USE # Documentation placeholder # Documentation placeholders (safe patterns) sk-ant-api03-EXAMPLE-REDACTED sk_live_EXAMPLE_REDACTED pk_live_EXAMPLE_REDACTED your-password-here your-token-here REDACTED # Test fixtures (if needed) # Add specific test patterns here with comments EOF echo " ✓ Created .gitleaksignore with default placeholders" fi echo "" # Create pre-commit hook echo "▶ 4. Creating pre-commit hook..." HOOK_FILE=.git/hooks/pre-commit if [ -f "$HOOK_FILE" ]; then # Backup existing hook BACKUP_FILE="${HOOK_FILE}.backup-$(date +%s)" cp "$HOOK_FILE" "$BACKUP_FILE" echo " ⚠ Existing pre-commit hook backed up to:" echo " $(basename $BACKUP_FILE)" echo "" echo " You may need to manually merge hooks if you had custom logic." echo "" fi cat > "$HOOK_FILE" << 'EOF' #!/bin/bash # Gitleaks Pre-Commit Hook # Created: 2025-10-21 (Post-breach security enhancement) # Implements: inst_070 (Pre-Commit Secret Detection) # # This hook runs gitleaks on staged files before allowing commits. # If secrets are detected, the commit is BLOCKED. echo "🔍 Running gitleaks secret detection..." # Run gitleaks on staged files if ! gitleaks protect --staged --verbose; then echo "" echo "❌ COMMIT BLOCKED: Secrets detected by gitleaks" echo "" echo "Actions:" echo " 1. Review the detected secrets above" echo " 2. Remove actual secrets from staged files" echo " 3. If false positive:" echo " - Verify it's NOT a real secret" echo " - Add pattern to .gitleaksignore with explanation" echo " - Get human approval before committing" echo " - Document in commit message" echo "" echo "NEVER bypass this hook without explicit user approval" echo "" exit 1 fi echo "✅ No secrets detected - commit allowed" exit 0 EOF chmod +x "$HOOK_FILE" echo " ✓ Pre-commit hook created and made executable" echo "" # Test the hook echo "▶ 5. Testing hook installation..." if [ -x "$HOOK_FILE" ]; then echo " ✓ Hook is executable" else echo " ✗ Hook is not executable (this should not happen)" exit 1 fi echo "" echo "═══════════════════════════════════════════════════════════" echo " ✅ INSTALLATION COMPLETE" echo "═══════════════════════════════════════════════════════════" echo "" echo "The pre-commit hook will now run automatically on every commit." echo "" echo "To test it:" echo " 1. Create a test file with a fake secret:" echo " echo 'sk-ant-api03-REAL_SECRET_KEY' > test-secret.txt" echo " 2. Stage and attempt to commit:" echo " git add test-secret.txt" echo " git commit -m 'test'" echo " 3. Commit should be BLOCKED with gitleaks error" echo " 4. Clean up:" echo " git reset HEAD test-secret.txt" echo " rm test-secret.txt" echo "" echo "Files created:" echo " - .git/hooks/pre-commit (executable hook)" echo " - .gitleaksignore (allowed patterns)" echo "" echo "Implements: inst_070 (Pre-Commit Secret Detection)" echo ""