#!/usr/bin/env bash # Local-only security regression suite. Uses attack-payload fixtures on purpose. # Do NOT ask hosted AI agents to run this script or to perform equivalent red-team review. set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" cd "$ROOT" if ! command -v bats >/dev/null 2>&1; then echo "bats-core is required: brew install bats-core" >&2 exit 1 fi # Subset of the full suite: adversarial regressions + explicit SECURITY tests + # closely related path/injection rails. Keeps the run focused and fast. FILTER='SECURITY|F1:|F2:|F3:|F4:|F5:|command injection does not execute|outside HOME is refused|symlinked target is refused|shell metacharacters|command-substitution|symlinked .secrets-store is skipped|symlinked .secrets-files is ignored|symlinked .secrets.json is refused' echo "Security regression suite (operator-local only)" echo "Repository policy: see .ship-policy.json" echo "" bats --filter "$FILTER" test/ echo "" echo "All filtered security regression tests passed." echo "" if [ ! -t 0 ]; then echo "Refusing non-interactive sign-off. Re-run in a terminal and complete operator certification." >&2 exit 1 fi read -r -p "Operator name: " OPERATOR if [ -z "${OPERATOR//[[:space:]]/}" ]; then echo "Operator name is required." >&2 exit 1 fi read -r -p "Type SIGNOFF to certify you ran this suite locally: " CONFIRM if [ "$CONFIRM" != "SIGNOFF" ]; then echo "Sign-off aborted (expected exactly SIGNOFF)." >&2 exit 1 fi SIGNOFF_DIR="$ROOT/.gstack" mkdir -p "$SIGNOFF_DIR" COMMIT="$(git rev-parse HEAD 2>/dev/null || echo unknown)" TS="$(date -u +%Y-%m-%dT%H:%M:%SZ)" SIGNOFF_FILE="$SIGNOFF_DIR/security-signoff.json" # Escape operator name for JSON (minimal — names should not contain quotes). OPERATOR_JSON="${OPERATOR//\\/\\\\}" OPERATOR_JSON="${OPERATOR_JSON//\"/\\\"}" cat >"$SIGNOFF_FILE" <