#!/usr/bin/env bash set -uo pipefail # CASAN Plan-16 SEC-10 (M-05) — non-spoofable agent identity. # # tool-registry-gate least-privilege trusted CASAN_AGENT (a plain env var anyone can # set → privilege spoofing). In enforced mode the caller must present a signed token # proving it is that agent (bound to agent id + run id). Proves: # * dev mode still trusts CASAN_AGENT (backward compatible), # * enforced mode denies an env-only claim (no token), # * a valid token is accepted, # * a forged token (unregistered key) is denied, # * a token minted for a different run is denied (no replay). # # Self-contained: ephemeral agent keypair + temp registry. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../scripts/bash/casan-paths.sh" PROJECT_ROOT="$CASAN_APP_ROOT" S="$CASAN_HARNESS_ROOT/scripts/bash" GATE="$S/tool-registry-gate.sh" WORK="$(mktemp -d)" trap 'git -C "$PROJECT_ROOT" checkout -- .specify/logs/ 2>/dev/null; rm -rf "$WORK"' EXIT AK="$WORK/agents"; mkdir -p "$AK" openssl genrsa -out "$WORK/rm.priv" 2048 2>/dev/null openssl rsa -in "$WORK/rm.priv" -pubout -out "$AK/release-manager.pub.pem" 2>/dev/null openssl genrsa -out "$WORK/atk.priv" 2048 2>/dev/null printf 'agent release-manager release-manager.pub.pem\n' > "$WORK/reg" export CASAN_AGENT_REGISTRY="$WORK/reg" CASAN_AGENT_KEYS_DIR="$AK" CASAN_RUN_ID=run-sec10 export CASAN_IDEMPOTENCY_KEY=k # deploy is side-effecting + idempotency-required PASS=0; FAIL=0 pass() { echo "PASS: $1"; PASS=$((PASS + 1)); } fail() { echo "FAIL: $1"; FAIL=$((FAIL + 1)); } rc_of() { set +e; "$@" >/dev/null 2>&1; echo $?; set -e 2>/dev/null || true; } echo "===== Plan-16 SEC-10: non-spoofable agent identity =====" # Dev (default): CASAN_AGENT is trusted (backward compatible). [[ "$(rc_of env CASAN_AGENT=release-manager bash "$GATE" deploy)" -eq 0 ]] \ && pass "dev mode: authorized CASAN_AGENT approved (backward compatible)" \ || fail "dev-mode agent authz broke" # Enforced: env-only claim (no token) is denied. [[ "$(rc_of env CASAN_IDENTITY_STRICT=1 CASAN_AGENT=release-manager bash "$GATE" deploy)" -ne 0 ]] \ && pass "enforced: env-only agent claim DENIED (spoof blocked)" \ || fail "enforced mode trusted a bare CASAN_AGENT env" # Enforced: a valid signed token is accepted. bash "$S/agent-identity-sign.sh" release-manager run-sec10 "$WORK/rm.priv" "$WORK/rm.sig" >/dev/null 2>&1 [[ "$(rc_of env CASAN_IDENTITY_STRICT=1 CASAN_AGENT=release-manager CASAN_AGENT_SIG="$WORK/rm.sig" bash "$GATE" deploy)" -eq 0 ]] \ && pass "enforced: valid signed agent token ACCEPTED" \ || fail "enforced mode rejected a valid agent token" # Enforced: a forged token (attacker key claiming to be release-manager) is denied. bash "$S/agent-identity-sign.sh" release-manager run-sec10 "$WORK/atk.priv" "$WORK/forged.sig" >/dev/null 2>&1 [[ "$(rc_of env CASAN_IDENTITY_STRICT=1 CASAN_AGENT=release-manager CASAN_AGENT_SIG="$WORK/forged.sig" bash "$GATE" deploy)" -ne 0 ]] \ && pass "enforced: forged agent token DENIED" \ || fail "enforced mode accepted a forged agent token" # Enforced: a token minted for a DIFFERENT run cannot be replayed. bash "$S/agent-identity-sign.sh" release-manager other-run "$WORK/rm.priv" "$WORK/replay.sig" >/dev/null 2>&1 [[ "$(rc_of env CASAN_IDENTITY_STRICT=1 CASAN_AGENT=release-manager CASAN_AGENT_SIG="$WORK/replay.sig" bash "$GATE" deploy)" -ne 0 ]] \ && pass "enforced: token bound to another run DENIED (no replay)" \ || fail "enforced mode allowed a cross-run token replay" echo "" echo "===== SEC-10 SUMMARY: PASS=$PASS FAIL=$FAIL =====" [[ "$FAIL" -eq 0 ]] || exit 1