← back to Unclaimed Property Platform

scripts/pre-commit-tripwire.sh

50 lines

#!/usr/bin/env bash
# Pre-commit tripwire — the ACTIVE half of the synthetic-only guardrail.
#
# .gitignore is passive (it only ignores untracked paths). This hook BLOCKS a commit that
# would introduce (a) an SSN-shaped string, or (b) a real-feed file format anywhere outside
# data/sample/. Born from Security audit finding 2.4 + Steve's standing "one accidental
# commit is how a key/feed leaks" lesson.
#
# Install (from repo root):
#   ln -sf ../../scripts/pre-commit-tripwire.sh .git/hooks/pre-commit
#   chmod +x scripts/pre-commit-tripwire.sh
# Bypass (only with a human decision): git commit --no-verify
set -euo pipefail

fail=0
staged=$(git diff --cached --name-only --diff-filter=ACM)

# (a) SSN-shaped content in any staged text file
ssn_re='[0-9]{3}-[0-9]{2}-[0-9]{4}'
for f in $staged; do
  [ -f "$f" ] || continue
  # skip obvious binaries
  if file "$f" | grep -qi 'text\|json\|csv\|ascii'; then
    if grep -nEq "$ssn_re" "$f"; then
      echo "TRIPWIRE: SSN-shaped string found in staged file: $f"
      grep -nE "$ssn_re" "$f" | head -3 | sed 's/^/    /'
      fail=1
    fi
  fi
done

# (b) real-feed file formats must never be committed outside data/sample/
while IFS= read -r f; do
  [ -n "$f" ] || continue
  case "$f" in
    data/sample/*) : ;;                       # the ONE allowed synthetic location
    *.naupa|*.dat|*.tab) echo "TRIPWIRE: real-feed format staged: $f"; fail=1 ;;
    data/*.txt|data/*.xml|data/*.zip|data/**/*.txt|data/**/*.xml|data/**/*.zip)
      echo "TRIPWIRE: data-feed file staged outside data/sample/: $f"; fail=1 ;;
  esac
done <<< "$staged"

if [ "$fail" -ne 0 ]; then
  echo ""
  echo "Commit BLOCKED by pre-commit-tripwire. This repo is synthetic-only."
  echo "If this is a false positive, a HUMAN may bypass with: git commit --no-verify"
  exit 1
fi
exit 0