knowledge-genome-orchestrator/templates/pre-commit.sh

47 lines
1.8 KiB
Bash

#!/usr/bin/env bash
# =============================================================================
# .git/hooks/pre-commit
# Fail-safe security hook: prevents plaintext commits of encrypted files.
# Reads encryption requirements dynamically from .gitattributes via
# git check-attr — no hardcoded paths, inherits all future rules automatically.
# =============================================================================
set -euo pipefail
FAILED=0
# Verify git-crypt is initialized
if ! git-crypt status >/dev/null 2>&1; then
printf "\n[CRITICAL] git-crypt not initialized.\n"
exit 1
fi
# Get staged files (additions, copies, modifications — no deletions)
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM 2>/dev/null || true)
[[ -z "$STAGED_FILES" ]] && exit 0
while IFS= read -r file; do
# Dynamically check if this file requires git-crypt encryption
filter=$(git check-attr filter -- "$file" 2>/dev/null | sed 's/.*: //')
[[ "$filter" != "git-crypt" ]] && continue
# File is required to be encrypted — verify it actually is
status=$(git-crypt status "$file" 2>/dev/null || printf "error")
if printf '%s\n' "$status" | grep -q "not encrypted"; then
printf "\n\033[0;31m[SECURITY ALERT] PLAINTEXT LEAK DETECTED\033[0m\n"
printf -- "-----------------------------------------------------------\n"
printf "File: %s\n" "$file"
printf "Status: Marked for git-crypt in .gitattributes but NOT encrypted.\n"
printf "Action: Verify .gitattributes rules and re-run 'git-crypt init'.\n"
printf -- "-----------------------------------------------------------\n"
FAILED=1
fi
done <<< "$STAGED_FILES"
if [[ "$FAILED" -ne 0 ]]; then
printf "\n\033[0;31mCommit blocked: security policy violation.\033[0m\n\n"
exit 1
fi
exit 0