Have you ever pushed to GitHub and thought, "Wait, did I just commit something sensitive?"
TL;DR: .gitignore alone won't save you. A pre-commit hook that scans for secret patterns will physically prevent accidental leaks. Setup takes 3 minutes.
What Happened
I run 11 AI agents for automated SNS operations. One agent saved browser session cookies to a JSON file for auto-posting to a blogging platform:
{
"cookies": [
{
"name": "_session_v5",
"value": "626f63e8bc9a23c20a455bb4...",
"httpOnly": true,
"secure": true
}
]
}
This file wasn't in .gitignore. I caught it in git status right before pushing.
Why .gitignore Isn't Enough
.gitignore only blocks files you already know about. It can't protect against:
- Credentials generated by tools at runtime
- Downloaded Service Account JSON keys
- Auth state files created by automation scripts
The Fix: Pre-commit Hook
Save this as .git/hooks/pre-commit:
#!/bin/bash
BLOCKED=0
FILES=$(git diff --cached --name-only --diff-filter=ACM)
if [ -z "$FILES" ]; then exit 0; fi
# Dangerous filename patterns
for FILE in $FILES; do
if echo "$FILE" | grep -qE "\.pem$|\.key$|\.p12$|credentials\.json|service.account.*\.json|client_secret.*\.json|token\.json|state\.json|_cookies\.json|\.env$|\.env\."; then
echo "BLOCKED: $FILE (dangerous filename)"
BLOCKED=1
fi
done
# Secret content patterns
for FILE in $FILES; do
if [ ! -f "$FILE" ]; then continue; fi
if file "$FILE" 2>/dev/null | grep -q "binary"; then continue; fi
if git diff --cached -- "$FILE" | grep -qE "PRIVATE KEY|BEGIN.*KEY|sk_live_|sk_test_|ghp_[a-zA-Z0-9]{36}|\"type\":.*\"service_account\""; then
echo "BLOCKED: $FILE contains secret pattern"
BLOCKED=1
fi
done
if [ $BLOCKED -ne 0 ]; then
echo "Commit blocked. Potential secrets detected."
echo "To override: git commit --no-verify"
exit 1
fi
exit 0
chmod +x .git/hooks/pre-commit
Test It
echo 'sk_live_fake1234567890abcdef' > test-leak.txt
git add test-leak.txt
git commit -m "test"
# → BLOCKED: test-leak.txt contains secret pattern
Commit is rejected. Crisis averted.
Also: Harden Your .gitignore
*.pem
*.key
*.p12
*-credentials.json
service-account*.json
client_secret*.json
token.json
credentials.json
.env
.env.*
*_cookies.json
Summary
| Layer | What it does | Setup time |
|---|---|---|
| .gitignore | Blocks known patterns | 1 min |
| Pre-commit hook | Detects unknown patterns, blocks commit | 2 min |
| Total | Two-layer protection | 3 min |
Related Links
- Indie Dev Monetization Roadmap — Not just tool reviews. "How do you actually make money?" included.
- LaunchKit — SaaS Starter Kit — Next.js + Supabase + Stripe, production-ready
Top comments (0)