Some checks failed
Security / Security check (push) Failing after 1s
The old 'F∆I Platform' product name and platform@flemming.ai contact survived in docs/NOTICE/descriptions/help text; the product is Ch∆In and the contact is chain@flemming.ai. Generic 'cross-platform/platform-native' left untouched. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
229 lines
7.1 KiB
Bash
Executable file
229 lines
7.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Ch∆In — smoke tests for `tools/security/check-staged.sh`.
|
|
#
|
|
# Spins up an isolated tempdir per scenario, stages a tripwire,
|
|
# and asserts the security script either passes or fails with the
|
|
# expected violation string. Never touches the operator's repo.
|
|
#
|
|
# Run manually:
|
|
# bash tools/security/test-check-staged.sh
|
|
#
|
|
# Wire into CI alongside the script-under-test if you want a
|
|
# second-line check that the rules themselves still trigger.
|
|
|
|
set -uo pipefail
|
|
|
|
SCRIPT="$(cd "$(dirname "$0")" && pwd)/check-staged.sh"
|
|
if [ ! -x "$SCRIPT" ]; then
|
|
echo "FATAL: $SCRIPT not found or not executable" >&2
|
|
exit 2
|
|
fi
|
|
|
|
PASS=0
|
|
FAIL=0
|
|
|
|
setup_repo() {
|
|
local d
|
|
d=$(mktemp -d -t fai_check_test.XXXXXX)
|
|
(
|
|
cd "$d"
|
|
git init -q
|
|
git config user.email t@t.local
|
|
git config user.name "Test"
|
|
git commit --allow-empty -m "init" -q
|
|
)
|
|
cp "$SCRIPT" "$d/check.sh"
|
|
chmod +x "$d/check.sh"
|
|
echo "$d"
|
|
}
|
|
|
|
# Args: label, expected-substring-in-stderr
|
|
assert_content_fails() {
|
|
local label="$1" expected="$2"
|
|
local out
|
|
if out=$(./check.sh content 2>&1); then
|
|
echo " FAIL [$label]: expected fail, but passed"
|
|
FAIL=$((FAIL + 1))
|
|
return
|
|
fi
|
|
if echo "$out" | grep -q -F -- "$expected"; then
|
|
echo " PASS [$label]"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
echo " FAIL [$label]: failed but did not mention '$expected'"
|
|
echo "$out" | head -5 | sed 's/^/ /'
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
}
|
|
|
|
assert_content_passes() {
|
|
local label="$1"
|
|
if ./check.sh content >/dev/null 2>&1; then
|
|
echo " PASS [$label]"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
echo " FAIL [$label]: expected pass, but failed"
|
|
./check.sh content 2>&1 | head -5 | sed 's/^/ /'
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
}
|
|
|
|
assert_message_fails() {
|
|
local label="$1" msg="$2" expected="$3"
|
|
local f
|
|
f=$(mktemp -t fai_msg_test.XXXXXX)
|
|
printf "%s\n" "$msg" > "$f"
|
|
local out
|
|
if out=$(./check.sh message "$f" 2>&1); then
|
|
echo " FAIL [$label]: expected fail, but passed"
|
|
FAIL=$((FAIL + 1))
|
|
rm -f "$f"
|
|
return
|
|
fi
|
|
if echo "$out" | grep -q -F -- "$expected"; then
|
|
echo " PASS [$label]"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
echo " FAIL [$label]: failed but did not mention '$expected'"
|
|
echo "$out" | head -5 | sed 's/^/ /'
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
rm -f "$f"
|
|
}
|
|
|
|
assert_message_passes() {
|
|
local label="$1" msg="$2"
|
|
local f
|
|
f=$(mktemp -t fai_msg_test.XXXXXX)
|
|
printf "%s\n" "$msg" > "$f"
|
|
if ./check.sh message "$f" >/dev/null 2>&1; then
|
|
echo " PASS [$label]"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
echo " FAIL [$label]: expected pass, but failed"
|
|
./check.sh message "$f" 2>&1 | head -5 | sed 's/^/ /'
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
rm -f "$f"
|
|
}
|
|
|
|
# ─── content scenarios ──────────────────────────────────────────────
|
|
|
|
echo "── content scans ──"
|
|
|
|
d=$(setup_repo); cd "$d"
|
|
assert_content_passes "clean state"
|
|
|
|
d=$(setup_repo); cd "$d"
|
|
echo "TOKEN=ghp_aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789" > leak.txt
|
|
git add leak.txt
|
|
assert_content_fails "github PAT detected" "ghp_"
|
|
|
|
d=$(setup_repo); cd "$d"
|
|
echo "key: sk-ant-aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789aBcDeF" > anthropic.txt
|
|
git add anthropic.txt
|
|
assert_content_fails "anthropic key detected" "sk-ant-"
|
|
|
|
d=$(setup_repo); cd "$d"
|
|
echo "AWS_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE" > aws.txt
|
|
git add aws.txt
|
|
assert_content_fails "AWS access key detected" "AKIA"
|
|
|
|
d=$(setup_repo); cd "$d"
|
|
echo "-----BEGIN RSA PRIVATE KEY-----" > id.pem
|
|
echo "stuff" >> id.pem
|
|
git add id.pem
|
|
assert_content_fails "PEM private key detected" "PRIVATE KEY"
|
|
|
|
d=$(setup_repo); cd "$d"
|
|
touch .env
|
|
echo "X=y" > .env
|
|
git add .env
|
|
assert_content_fails ".env in stage" "forbidden file"
|
|
|
|
d=$(setup_repo); cd "$d"
|
|
echo "DEMO_VAR=value" > .env.example
|
|
git add .env.example
|
|
assert_content_passes ".env.example allowlisted"
|
|
|
|
d=$(setup_repo); cd "$d"
|
|
mkdir tests
|
|
echo "fake cert content" > tests/server.pem
|
|
git add tests/server.pem
|
|
assert_content_passes "tests/*.pem allowlisted"
|
|
|
|
d=$(setup_repo); cd "$d"
|
|
# The confidentiality list lives outside the repo at
|
|
# $FAI_BANNED_TERMS_FILE (default ~/.fai-security/banned-terms.txt).
|
|
# For the test we point at a temp file holding a single
|
|
# generic test term — the actual production terms stay in the
|
|
# operator's untracked file and never enter this test suite.
|
|
TEST_BANNED_TERMS=$(mktemp -t fai_banned.XXXXXX)
|
|
printf "\\\\bSYNTHETIC_BANNED_TERM_XYZZY\\\\b\n" > "$TEST_BANNED_TERMS"
|
|
export FAI_BANNED_TERMS_FILE="$TEST_BANNED_TERMS"
|
|
echo "Document contains SYNTHETIC_BANNED_TERM_XYZZY in passing" > confidential.md
|
|
git add confidential.md
|
|
assert_content_fails "confidential term (synthetic test term)" "SYNTHETIC_BANNED_TERM_XYZZY"
|
|
rm -f "$TEST_BANNED_TERMS"
|
|
unset FAI_BANNED_TERMS_FILE
|
|
|
|
d=$(setup_repo); cd "$d"
|
|
echo "Our viral release of a powerful tool that just works" > marketing.md
|
|
git add marketing.md
|
|
assert_content_fails "banned phrase viral" "viral"
|
|
|
|
d=$(setup_repo); cd "$d"
|
|
echo "viral content" > marketing.md
|
|
mkdir -p tools/today
|
|
echo "this references viral and powerful intentionally" > tools/today/prompt.md
|
|
echo "tools/today/" > .security-allow
|
|
git add .security-allow tools/today/prompt.md
|
|
assert_content_passes ".security-allow excludes legit listing"
|
|
# But banned content outside the allow path must still trip:
|
|
git add marketing.md
|
|
assert_content_fails ".security-allow does not cover other paths" "viral"
|
|
|
|
# ─── message scenarios ──────────────────────────────────────────────
|
|
|
|
echo ""
|
|
echo "── message scans ──"
|
|
|
|
# Need a working dir to run the script from (it cd's to git toplevel).
|
|
d=$(setup_repo); cd "$d"
|
|
|
|
assert_message_passes \
|
|
"well-formed Conventional Commits + DCO" \
|
|
"$(printf 'feat(hub): add thing\n\nbody\n\nSigned-off-by: Test <t@t.local>')"
|
|
|
|
assert_message_fails \
|
|
"missing DCO" \
|
|
"feat(hub): add thing" \
|
|
"missing DCO"
|
|
|
|
assert_message_fails \
|
|
"non-conventional subject" \
|
|
"$(printf 'added stuff\n\nSigned-off-by: Test <t@t.local>')" \
|
|
"Conventional Commits"
|
|
|
|
assert_message_fails \
|
|
"Claude co-author trailer" \
|
|
"$(printf 'feat(hub): add thing\n\nCo-Authored-By: Claude <claude@anthropic.com>\nSigned-off-by: Test <t@t.local>')" \
|
|
"Co-Authored-By: Claude"
|
|
|
|
assert_message_fails \
|
|
"banned phrase in message body" \
|
|
"$(printf 'feat(hub): add thing\n\nThis is just a viral test.\n\nSigned-off-by: Test <t@t.local>')" \
|
|
"banned phrase"
|
|
|
|
assert_message_passes \
|
|
"merge commits skip Conventional check" \
|
|
"$(printf 'Merge branch feature-x into main\n\nSigned-off-by: Test <t@t.local>')"
|
|
|
|
# ─── summary ────────────────────────────────────────────────────────
|
|
|
|
echo ""
|
|
echo "─────────────────────────────────"
|
|
echo "Tests: $PASS passed, $FAIL failed"
|
|
if [ "$FAIL" -ne 0 ]; then
|
|
exit 1
|
|
fi
|