hooks: track the pre-commit hook instead of generating a copy of it
setup-hooks.sh used to WRITE .git/hooks/pre-commit from a heredoc. That makes the
running hook a copy of the versioned intent, and a copy drifts. It already had:
the hook installed on this machine was an older revision than this script emits,
having lost the Linux gitleaks install hint (`uname -s` line) that the heredoc has.
Nothing reported that, because a stale hook still prints a reassuring banner.
The hook body is now a tracked file at hooks/pre-commit -- extracted byte-for-byte
from the heredoc, so this commit changes where the hook lives, not what it does --
wired via `git config core.hooksPath hooks`. git then executes the tracked file
itself, so the hook that runs and the hook in history cannot disagree. This is the
convention docker-compose-repo already uses.
setup-hooks.sh keeps its name (README references it) and now activates rather than
generates. It also warns if .git/hooks/pre-commit still exists, because after
core.hooksPath is set that file is INERT and silently shadowed -- a decoy that looks
like protection. The leftover copy on this clone was removed.
VERIFIED, and the first attempt was a false pass worth recording: a planted
`AKIAIOSFODNN7EXAMPLE` was NOT blocked and the test commit went through. The gate
was fine -- gitleaks ALLOWLISTS that string, since it is AWS's own documentation
example. A control built from a well-known example credential proves nothing. That
commit was reset (HEAD back to 69fc80a = origin/main) and the control rebuilt from a
synthetic RSA private key block, first confirmed detectable by two independent routes
(`gitleaks detect --no-git` on the file, then `gitleaks protect --staged` in-repo)
BEFORE being trusted as a control. Through the hook: rc=1, "commit blocked", HEAD
unchanged. Also confirmed core.hooksPath=hooks is set and shellcheck is clean on
both files. Test artefacts deleted; nothing leaked into history.
This commit is contained in:
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
# Pre-commit hook — scans staged files for secrets using gitleaks
|
||||
|
||||
if ! command -v gitleaks >/dev/null 2>&1; then
|
||||
echo ""
|
||||
echo "⚠️ gitleaks is not installed — skipping secret scan"
|
||||
echo " Install: brew install gitleaks (macOS)"
|
||||
echo " Or: curl -sSL https://github.com/gitleaks/gitleaks/releases/latest/download/gitleaks_\$(uname -s)_\$(uname -m).tar.gz | sudo tar -xz -C /usr/local/bin gitleaks"
|
||||
echo ""
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "🔒 Scanning for secrets..."
|
||||
|
||||
if gitleaks protect --staged --no-banner 2>/dev/null; then
|
||||
echo "✅ No secrets detected"
|
||||
exit 0
|
||||
else
|
||||
echo ""
|
||||
echo "❌ Secrets detected in staged changes — commit blocked"
|
||||
echo ""
|
||||
echo " Details: gitleaks protect --staged --verbose"
|
||||
echo " Bypass: git commit --no-verify"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user