tractatus/scripts/install-gitleaks-hook.sh
TheFlow af58ce01b6 fix(security): comprehensive security incident response for API key exposure
INCIDENT SUMMARY:
- Date: 2025-10-21
- Severity: CRITICAL → MEDIUM (credential revoked before exploitation)
- Exposed: Anthropic API key (ID 5043627, name: family-history-ocr)
- Location: docs/STRIPE_LIVE_MODE_DEPLOYMENT.md (commit 31345d5c)
- Detection: GitHub secret scanning (automatic)
- Revocation: Anthropic (automatic, within hours)
- Financial Impact: $0 (no unauthorized usage)

ROOT CAUSE - 5 FAILURE POINTS:
1. No credential redaction in documentation (PREVENTION)
2. Framework fade - BoundaryEnforcer not used (ENFORCEMENT)
3. No pre-commit secret detection (DETECTION)
4. No credential audit in pre-deployment checklist (MITIGATION)
5. Single-layer security model, not defense-in-depth (ARCHITECTURAL)

NEW GOVERNANCE RULES:
- inst_069: Credential Handling in Documentation (SYSTEM, HIGH, PERMANENT)
  - Requires ALL credentials redacted with example-only values
  - Patterns: sk-ant-api03-EXAMPLE-REDACTED, sk_live_EXAMPLE_REDACTED
  - Mandatory secret detection scan before commits

- inst_070: Pre-Commit Secret Detection (SYSTEM, HIGH, PERMANENT)
  - Requires gitleaks or detect-secrets as pre-commit hook
  - BLOCKS commits containing secrets
  - False positives require user approval + documentation

- inst_071: Enhanced Pre-Deployment Checklist (OPERATIONAL, HIGH, PERMANENT)
  - Replaces inst_054 with 8 steps including secret detection
  - Step 2: gitleaks detect --source .
  - Step 3: Credential audit (grep for sk-, pk-, secret, password)
  - Step 8: Public repository content review

- inst_072: Assume Breach - Defense in Depth (STRATEGIC, HIGH, PERMANENT)
  - Layer 1 - Prevention: Never commit credentials
  - Layer 2 - Mitigation: Redact credentials in docs
  - Layer 3 - Detection: Pre-commit secret scanning (automated)
  - Layer 4 - Backstop: GitHub secret scanning
  - Layer 5 - Recovery: Credential rotation procedures

DOCUMENTATION:
- SECURITY_INCIDENT_POST_MORTEM_2025-10-21.md (comprehensive analysis)
- SECURITY_INCIDENT_HUMAN_ACTIONS_REQUIRED.md (15-step action plan)
- scripts/install-gitleaks-hook.sh (automated installation)
- scripts/add-security-rules-2025-10-21.js (rules migration)

ADDITIONAL FINDINGS:
Comprehensive credential scan revealed additional exposed credentials in
internal repository (not public):
- Same Anthropic key in .env file
- Same key in internal docs/STRIPE_LIVE_MODE_DEPLOYMENT.md
- Stripe test keys in .env
- JWT production secret in .env

HUMAN ACTIONS REQUIRED:
1. Rotate Anthropic API key (CRITICAL)
2. Rotate JWT secret (CRITICAL)
3. Remove credentials from internal repository files
4. Install gitleaks pre-commit hook
5. Decide on git history cleanup (Option A/B/C)

VERSION UPDATE:
- instruction-history.json: 3.6 → 3.7
- Total rules: 68 → 72
- Active rules: 56 → 59

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 00:31:30 +13:00

163 lines
5.1 KiB
Bash
Executable file

#!/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 ""