- Create Economist SubmissionTracking package correctly: * mainArticle = full blog post content * coverLetter = 216-word SIR— letter * Links to blog post via blogPostId - Archive 'Letter to The Economist' from blog posts (it's the cover letter) - Fix date display on article cards (use published_at) - Target publication already displaying via blue badge Database changes: - Make blogPostId optional in SubmissionTracking model - Economist package ID: 68fa85ae49d4900e7f2ecd83 - Le Monde package ID: 68fa2abd2e6acd5691932150 Next: Enhanced modal with tabs, validation, export 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
163 lines
5.1 KiB
Bash
Executable file
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 ""
|