Files
openclaw-ops/scripts/scan-secrets.sh

78 lines
2.2 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Lightweight staged-file secret scan for local git hygiene.
# Focus: obvious high-risk mistakes, not exhaustive DLP.
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "Not inside a git work tree" >&2
exit 2
fi
staged_files=$(git diff --cached --name-only --diff-filter=ACMR)
if [[ -z "${staged_files}" ]]; then
exit 0
fi
fail=0
# High-signal patterns only. Avoid noisy generic matches.
patterns=(
'AKIA[0-9A-Z]{16}'
'AIza[0-9A-Za-z\-_]{35}'
'ghp_[0-9A-Za-z]{36}'
'github_pat_[0-9A-Za-z_]{20,}'
'xox[baprs]-[0-9A-Za-z-]{10,}'
'-----BEGIN (RSA|DSA|EC|OPENSSH|PGP)? ?PRIVATE KEY-----'
'AIzaSy[0-9A-Za-z\-_]+'
)
while IFS= read -r file; do
[[ -f "$file" ]] || continue
# Skip common binary assets.
if file "$file" 2>/dev/null | grep -qiE 'image|font|audio|video|compressed|archive|executable'; then
continue
fi
# Scan staged content, not working tree content.
staged_content=$(git show ":$file" 2>/dev/null || true)
[[ -n "$staged_content" ]] || continue
for pattern in "${patterns[@]}"; do
if printf '%s' "$staged_content" | grep -nE "$pattern" >/tmp/openclaw-secret-scan-match.$$ 2>/dev/null; then
echo "Potential secret detected in staged file: $file" >&2
sed 's/^/ /' /tmp/openclaw-secret-scan-match.$$ >&2 || true
fail=1
fi
done
# Heuristic: suspicious assignments for secret-ish variable names with inline values.
if printf '%s' "$staged_content" | grep -nE '(^|[[:space:]])(API_KEY|TOKEN|SECRET|PASSWORD|PASSWD|PRIVATE_KEY)[[:space:]]*[:=][[:space:]]*[^[:space:]]+' >/tmp/openclaw-secret-scan-heuristic.$$ 2>/dev/null; then
echo "Suspicious inline credential assignment in staged file: $file" >&2
sed 's/^/ /' /tmp/openclaw-secret-scan-heuristic.$$ >&2 || true
fail=1
fi
done <<< "$staged_files"
rm -f /tmp/openclaw-secret-scan-match.$$ /tmp/openclaw-secret-scan-heuristic.$$ 2>/dev/null || true
if [[ "$fail" -ne 0 ]]; then
cat >&2 <<'EOF'
Commit blocked by lightweight secret scan.
If this is a false positive:
- inspect the staged diff carefully
- remove/redact the sensitive-looking value if needed
- re-stage and commit again
- or bypass once with: git commit --no-verify
Use --no-verify sparingly.
EOF
exit 1
fi
exit 0