#!/usr/bin/env bash # Scan the repo for secrets and sensitive config values. # Runs via CI (GitHub/Gitea Actions) and locally as a pre-commit check. # # Usage: scripts/check-secrets.sh [--staged-only] # --staged-only Only check files staged for commit (for pre-commit hook use) # # Requires gitleaks on PATH, or falls back to Docker if available. # Install gitleaks: https://github.com/gitleaks/gitleaks#installing set -euo pipefail REPO_ROOT="$(git -C "$(dirname "$0")" rev-parse --show-toplevel)" STAGED_ONLY=false FAILURES=0 for arg in "$@"; do [[ "$arg" == "--staged-only" ]] && STAGED_ONLY=true done cd "$REPO_ROOT" # ── Resolve gitleaks binary ──────────────────────────────────────────────────── if command -v gitleaks &>/dev/null; then GITLEAKS="gitleaks" elif command -v docker &>/dev/null; then GITLEAKS="docker run --rm -v ${REPO_ROOT}:/repo zricethezav/gitleaks:latest" # Adjust paths for docker context REPO_ROOT="/repo" else echo "ERROR: gitleaks not found. Install it or ensure Docker is available." >&2 echo " https://github.com/gitleaks/gitleaks#installing" >&2 exit 1 fi echo "=== Secret scan ===" if [[ "$STAGED_ONLY" == "true" ]]; then # Pre-commit mode: scan only staged content echo "Mode: staged files only" if ! $GITLEAKS protect --staged --config="${REPO_ROOT}/.gitleaks.toml" --source="${REPO_ROOT}" 2>&1; then FAILURES=$((FAILURES + 1)) fi else # CI mode: scan full git history echo "Mode: full git history" if ! $GITLEAKS detect --config="${REPO_ROOT}/.gitleaks.toml" --source="${REPO_ROOT}" 2>&1; then FAILURES=$((FAILURES + 1)) fi fi # ── Pi-hole specific checks ──────────────────────────────────────────────────── echo "" echo "=== Pi-hole config checks ===" PIHOLE_TOML="${REPO_ROOT}/pihole/config/pihole.toml" if [[ -f "$PIHOLE_TOML" ]]; then # Check that known sensitive fields are empty for field in pwhash totp_secret app_pwhash; do value=$(grep -E "^\s+${field}\s*=" "$PIHOLE_TOML" | sed 's/.*=\s*"\(.*\)".*/\1/' | tr -d '[:space:]' || true) if [[ -n "$value" && "$value" != '""' ]]; then echo "FAIL: pihole.toml contains a non-empty '${field}' — run pihole/sanitize-config.sh before committing" >&2 FAILURES=$((FAILURES + 1)) else echo " OK: ${field} is empty" fi done else echo " (pihole/config/pihole.toml not present, skipping Pi-hole checks)" fi # ── Summary ──────────────────────────────────────────────────────────────────── echo "" if [[ $FAILURES -gt 0 ]]; then echo "FAILED: ${FAILURES} issue(s) found. Fix before committing." >&2 exit 1 else echo "All checks passed." fi