set -euo pipefail
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m'
echo -e "${YELLOW}π Sparrow pre-commit hook β scanning staged files...${NC}"
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM 2>/dev/null || true)
if [ -z "$STAGED_FILES" ]; then
echo -e "${GREEN}β No staged files to scan.${NC}"
exit 0
fi
SENSITIVE_NAMES=(
".env" ".env.local" ".env.production" ".env.development"
"credentials.json" "service-account.json" "secrets.yaml" "secrets.yml"
".netrc" ".npmrc" ".pypirc"
"id_rsa" "id_ed25519" "id_ecdsa"
)
ISSUES=0
for file in $STAGED_FILES; do
filename=$(basename "$file")
for sensitive in "${SENSITIVE_NAMES[@]}"; do
if [ "$filename" = "$sensitive" ]; then
echo -e "${RED}β BLOCKED: Sensitive file staged: $file${NC}"
echo -e " β Remove it: git rm --cached $file"
ISSUES=$((ISSUES + 1))
fi
done
case "$filename" in
*.pem|*.key|*.p12|*.pfx)
echo -e "${RED}β BLOCKED: Private key file staged: $file${NC}"
echo -e " β Remove it: git rm --cached $file"
ISSUES=$((ISSUES + 1))
;;
esac
case "$file" in
.sparrow/*|.codex/*|.agent/*)
echo -e "${YELLOW}β WARNING: Agent config directory staged: $file${NC}"
echo -e " β Consider adding to .gitignore"
;;
esac
if [ -f "$file" ]; then
STAGED_CONTENT=$(git show ":$file" 2>/dev/null || true)
if [ -n "$STAGED_CONTENT" ]; then
if echo "$STAGED_CONTENT" | grep -qE 'ghp_[0-9a-zA-Z]{36}|github_pat_[0-9a-zA-Z_]{36,}'; then
echo -e "${RED}β BLOCKED: GitHub token detected in $file${NC}"
ISSUES=$((ISSUES + 1))
fi
if echo "$STAGED_CONTENT" | grep -qE 'sk-[0-9a-zA-Z]{32,}|sk-proj-[0-9a-zA-Z]{32,}'; then
echo -e "${RED}β BLOCKED: OpenAI API key detected in $file${NC}"
ISSUES=$((ISSUES + 1))
fi
if echo "$STAGED_CONTENT" | grep -qE 'sk-ant-[0-9a-zA-Z]{32,}'; then
echo -e "${RED}β BLOCKED: Anthropic API key detected in $file${NC}"
ISSUES=$((ISSUES + 1))
fi
if echo "$STAGED_CONTENT" | grep -qE 'AKIA[0-9A-Z]{16}'; then
echo -e "${RED}β BLOCKED: AWS Access Key detected in $file${NC}"
ISSUES=$((ISSUES + 1))
fi
if echo "$STAGED_CONTENT" | grep -qiE '(api[_-]?key|api[_-]?secret|secret[_-]?key)\s*[:=]\s*['"'"'"]?\w{20,}'; then
echo -e "${YELLOW}β WARNING: Possible API key in $file${NC}"
echo -e " β Review and use environment variables instead"
fi
if echo "$STAGED_CONTENT" | grep -qE '-----BEGIN (RSA|DSA|EC|OPENSSH|PGP) PRIVATE KEY-----'; then
echo -e "${RED}β BLOCKED: Private key detected in $file${NC}"
ISSUES=$((ISSUES + 1))
fi
if echo "$STAGED_CONTENT" | grep -qiE '(password|passwd|pwd|token|auth[_-]?token)\s*[:=]\s*['"'"'"]?\S{4,}'; then
echo -e "${YELLOW}β WARNING: Possible hardcoded password/token in $file${NC}"
fi
fi
fi
done
if [ $ISSUES -gt 0 ]; then
echo ""
echo -e "${RED}ββββββββββββββββββββββββββββββββββββββββββββββββββ${NC}"
echo -e "${RED} COMMIT BLOQUΓ β $ISSUES problΓ¨me(s) de sΓ©curitΓ©${NC}"
echo -e "${RED}ββββββββββββββββββββββββββββββββββββββββββββββββββ${NC}"
echo ""
echo "Pour ignorer (dΓ©conseillΓ©) : git commit --no-verify"
echo "Pour enlever un fichier du stage : git rm --cached <fichier>"
echo "Pour dΓ©sinstaller ce hook : rm .git/hooks/pre-commit"
exit 1
else
echo -e "${GREEN}β Aucun problΓ¨me dΓ©tectΓ© β commit autorisΓ©.${NC}"
exit 0
fi