mirror of
https://github.com/Such-Software/smirk-backend-core.git
synced 2026-10-17 07:21:32 +02:00
60 lines
2.6 KiB
Bash
Executable File
60 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# secret-scan: block private keys and seed material from entering the tree.
|
|
#
|
|
# Public-safe by design: it matches on secret *shapes* (key blocks, mnemonic
|
|
# markers), never on project-internal names. gitleaks runs alongside it in CI
|
|
# for broad token/credential patterns.
|
|
#
|
|
# ./tools/secret-scan.sh
|
|
#
|
|
set -uo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
|
|
FILES=()
|
|
if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
while IFS= read -r -d '' file; do
|
|
FILES+=("$file")
|
|
done < <(git ls-files -z --cached --others --exclude-standard)
|
|
else
|
|
while IFS= read -r -d '' file; do
|
|
FILES+=("$file")
|
|
done < <(find . -type f -not -path './.git/*' -not -path './target/*' -print0)
|
|
fi
|
|
|
|
# Secret shapes (not names), covering the classes this backend actually handles:
|
|
# - PEM/OpenSSH/PGP private-key blocks
|
|
# - seed-phrase markers (mnemonic / seed phrase), any capitalisation
|
|
# - nsec1... Nostr SECRET keys (bech32)
|
|
# - a secret-shaped env assignment given a 32+ hex-char value, i.e. an
|
|
# `openssl rand -hex 32` value pasted in cleartext. The name alternation is
|
|
# spelled out so it really does cover every secret this backend takes:
|
|
# *_PEPPER, *_SALT, *_SECRET (incl. *_INTEGRITY_SECRET), *_PASSWORD, *_TOKEN,
|
|
# *_API_KEY, *_ADMIN_KEY, *_HMAC_KEY, *_PRIVATE_KEY, *_SIGNING_KEY. A bare
|
|
# *KEY* is NOT in the list on purpose: it would fire on ADMIN_PUBKEYS and
|
|
# friends, whose values are public.
|
|
#
|
|
# NOT covered, and left to gitleaks rather than implied here: secret VALUES that
|
|
# are not hex (base64 or random alphanumeric API keys, real passwords). Catching
|
|
# those needs entropy heuristics, which in this tree would fire on every address,
|
|
# hash and test vector and train people to ignore the scanner.
|
|
PATTERNS='(-----BEGIN ([A-Z ]+ )?PRIVATE KEY-----|-----BEGIN PGP PRIVATE KEY|BEGIN OPENSSH PRIVATE KEY|\b([Mm]nemonic|MNEMONIC|[Ss]eed[_ ]?[Pp]hrase|SEED[_ ]?PHRASE)\b\s*[:=]|nsec1[0-9a-z]{20,}|\b[A-Z_]*(PEPPER|SALT|SECRET|PASSWORD|TOKEN|API_?KEY|ADMIN_KEY|HMAC_KEY|PRIVATE_KEY|SIGNING_KEY)[A-Z_]*\s*=\s*[0-9a-fA-F]{32,})'
|
|
|
|
fail=0
|
|
for f in "${FILES[@]}"; do
|
|
[ -f "$f" ] || continue
|
|
case "$f" in tools/secret-scan.sh) continue ;; esac
|
|
if grep -EnI "$PATTERNS" "$f" >/dev/null 2>&1; then
|
|
echo "SECRET-SCAN: possible key/seed material in $f"
|
|
# Report locations without echoing the secret-shaped value we caught.
|
|
grep -EnI "$PATTERNS" "$f" | cut -d: -f1 | sed 's/^/ line /'
|
|
fail=1
|
|
fi
|
|
done
|
|
|
|
if [ "$fail" -ne 0 ]; then
|
|
echo "SECRET-SCAN FAILED — remove key/seed material before committing."
|
|
exit 1
|
|
fi
|
|
echo "secret-scan OK (${#FILES[@]} files checked)."
|