Files
siriusscan--sirius/scripts/verify-runtime-auth-contract.sh
wehub-resource-sync 161ef94b4f
Check engine pin consistency / Dockerfile / CI pin consistency (push) Successful in 8s
Sirius CI/CD Pipeline / Detect Changes (push) Successful in 23s
Validate Docker Configuration / Validate Docker Compose Configuration (push) Successful in 47s
Sirius CI/CD Pipeline / Build API (${{ matrix.platform }}) (push) Has been cancelled
Sirius CI/CD Pipeline / Build UI (${{ matrix.platform }}) (push) Has been cancelled
Sirius CI/CD Pipeline / Merge Engine Manifest (push) Has been cancelled
Sirius CI/CD Pipeline / Merge API Manifest (push) Has been cancelled
Sirius CI/CD Pipeline / Merge UI Manifest (push) Has been cancelled
Sirius CI/CD Pipeline / Build Engine (${{ matrix.platform }}) (push) Has been cancelled
Sirius CI/CD Pipeline / Build Infra (${{ matrix.service }}, ${{ matrix.platform }}) (push) Has been cancelled
Sirius CI/CD Pipeline / Merge Infra Manifest (sirius-postgres) (push) Has been cancelled
Sirius CI/CD Pipeline / Merge Infra Manifest (sirius-rabbitmq) (push) Has been cancelled
Sirius CI/CD Pipeline / Merge Infra Manifest (sirius-valkey) (push) Has been cancelled
Sirius CI/CD Pipeline / Integration Test (push) Has been cancelled
Sirius CI/CD Pipeline / Public Stack Contract (push) Has been cancelled
Sirius CI/CD Pipeline / Dispatch Demo Deployment (sirius-demo branch) (push) Has been cancelled
Sirius CI/CD Pipeline / Dispatch Demo Canary (main branch) (push) Has been cancelled
Sirius CI/CD Pipeline / Guard Registry Namespace (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:32:25 +08:00

199 lines
7.6 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Runtime auth contract: internal API key comes from the mounted
# SIRIUS_API_KEY_FILE secret, POSTGRES_PASSWORD parity, engine env, API HTTP
# behavior.
#
# Container names default to docker-compose.yaml `container_name` values (project: sirius).
# Override for other projects, e.g. CI:
# export SIRIUS_CONTRACT_CONTAINER_UI=sirius-test-sirius-ui-1
# export SIRIUS_CONTRACT_CONTAINER_API=sirius-test-sirius-api-1
# export SIRIUS_CONTRACT_CONTAINER_ENGINE=sirius-test-sirius-engine-1
# export SIRIUS_CONTRACT_CONTAINER_POSTGRES=sirius-test-sirius-postgres-1
#
# Host URL for curl (published API port on the host):
# export SIRIUS_API_PUBLIC_URL=http://localhost:9001
#
set -euo pipefail
: "${SIRIUS_CONTRACT_CONTAINER_UI:=sirius-ui}"
: "${SIRIUS_CONTRACT_CONTAINER_API:=sirius-api}"
: "${SIRIUS_CONTRACT_CONTAINER_ENGINE:=sirius-engine}"
: "${SIRIUS_CONTRACT_CONTAINER_POSTGRES:=sirius-postgres}"
: "${SIRIUS_API_PUBLIC_URL:=http://localhost:9001}"
SIRIUS_API_PUBLIC_URL="${SIRIUS_API_PUBLIC_URL%/}"
CTR_UI="$SIRIUS_CONTRACT_CONTAINER_UI"
CTR_API="$SIRIUS_CONTRACT_CONTAINER_API"
CTR_ENGINE="$SIRIUS_CONTRACT_CONTAINER_ENGINE"
CTR_POSTGRES="$SIRIUS_CONTRACT_CONTAINER_POSTGRES"
required_containers=("$CTR_POSTGRES" "$CTR_API" "$CTR_ENGINE" "$CTR_UI")
for name in "${required_containers[@]}"; do
if ! docker inspect "$name" >/dev/null 2>&1; then
echo "❌ Missing container: $name (override SIRIUS_CONTRACT_CONTAINER_* if using a non-default compose project)"
exit 1
fi
done
extract_env() {
local container="$1"
local key="$2"
# NOTE: use grep, not rg — ripgrep is not preinstalled on GitHub-hosted
# ubuntu-latest runners. The trailing `|| true` previously masked the
# `rg: command not found` failure, silently returning empty for every
# key and tripping the POSTGRES_PASSWORD parity check downstream.
docker inspect "$container" --format '{{range .Config.Env}}{{println .}}{{end}}' \
| grep "^${key}=" | sed "s/^${key}=//" || true
}
# Effective key inside the container (trimmed file contents only).
resolve_file_backed_api_key() {
local container="$1"
docker exec "$container" sh -lc \
'if [ -r "${SIRIUS_API_KEY_FILE:-}" ]; then tr -d "\r\n" < "$SIRIUS_API_KEY_FILE"; fi'
}
mask_value() {
local value="$1"
if [ -z "$value" ]; then
echo "<empty>"
return
fi
local len=${#value}
if [ "$len" -le 10 ]; then
echo "${value:0:2}***"
return
fi
echo "${value:0:6}...${value: -4}"
}
assert_file_only_api_key_contract() {
local container="$1"
local label="$2"
local file_key
local configured_env_key
file_key="$(resolve_file_backed_api_key "$container")"
configured_env_key="$(extract_env "$container" SIRIUS_API_KEY)"
if [ -n "$configured_env_key" ]; then
echo "❌ ${label} still has legacy SIRIUS_API_KEY configured in container env"
exit 1
fi
if [ -z "$file_key" ]; then
echo "❌ ${label} is missing a readable file-backed internal API key"
exit 1
fi
}
assert_file_only_api_key_contract "$CTR_UI" "sirius-ui"
assert_file_only_api_key_contract "$CTR_API" "sirius-api"
assert_file_only_api_key_contract "$CTR_ENGINE" "sirius-engine"
ui_key="$(resolve_file_backed_api_key "$CTR_UI")"
api_key="$(resolve_file_backed_api_key "$CTR_API")"
engine_key="$(resolve_file_backed_api_key "$CTR_ENGINE")"
postgres_db_pw="$(extract_env "$CTR_POSTGRES" POSTGRES_PASSWORD)"
api_db_pw="$(extract_env "$CTR_API" POSTGRES_PASSWORD)"
engine_db_pw="$(extract_env "$CTR_ENGINE" POSTGRES_PASSWORD)"
engine_api_base_url="$(extract_env "$CTR_ENGINE" API_BASE_URL)"
engine_sirius_api_url="$(extract_env "$CTR_ENGINE" SIRIUS_API_URL)"
engine_agent_id="$(extract_env "$CTR_ENGINE" AGENT_ID)"
engine_host_id="$(extract_env "$CTR_ENGINE" HOST_ID)"
echo "Runtime key fingerprints:"
echo " ui ($CTR_UI): $(mask_value "$ui_key")"
echo " api ($CTR_API): $(mask_value "$api_key")"
echo " engine ($CTR_ENGINE): $(mask_value "$engine_key")"
if [ -z "$ui_key" ] || [ -z "$api_key" ] || [ -z "$engine_key" ]; then
echo "❌ One or more services are missing readable SIRIUS_API_KEY_FILE secret data"
exit 1
fi
echo "✅ File-only internal API key contract check passed"
if [ "$ui_key" != "$api_key" ] || [ "$api_key" != "$engine_key" ]; then
echo "❌ Internal API key mismatch across services (key split-brain detected)"
exit 1
fi
echo "✅ Internal API key parity check passed"
if [ -z "$postgres_db_pw" ] || [ -z "$api_db_pw" ] || [ -z "$engine_db_pw" ]; then
echo "❌ One or more services are missing POSTGRES_PASSWORD"
exit 1
fi
if [ "$postgres_db_pw" != "$api_db_pw" ] || [ "$api_db_pw" != "$engine_db_pw" ]; then
echo "❌ POSTGRES_PASSWORD mismatch across postgres/api/engine"
exit 1
fi
echo "✅ POSTGRES_PASSWORD parity check passed"
if [ -z "$engine_sirius_api_url" ] || [ -z "$engine_agent_id" ] || [ -z "$engine_host_id" ]; then
echo "❌ sirius-engine is missing one or more required runtime env values (SIRIUS_API_URL, AGENT_ID, HOST_ID)"
exit 1
fi
if [ -n "$engine_api_base_url" ] && [ -n "$engine_sirius_api_url" ]; then
if [ "${engine_api_base_url%/}" != "${engine_sirius_api_url%/}" ]; then
echo "❌ API_BASE_URL must equal SIRIUS_API_URL on engine (got API_BASE_URL=${engine_api_base_url} SIRIUS_API_URL=${engine_sirius_api_url})"
exit 1
fi
fi
echo "✅ sirius-engine runtime env contract check passed"
if docker exec "$CTR_POSTGRES" test -f /usr/local/bin/start-with-monitor.sh 2>/dev/null; then
if docker exec "$CTR_POSTGRES" sh -lc "grep -E -q 'psql[^\\n]*\\|\\| true|ALTER ROLE[^\\n]*\\|\\| true' /usr/local/bin/start-with-monitor.sh"; then
echo "❌ Running postgres entrypoint still contains permissive psql reconciliation fallback"
exit 1
fi
echo "✅ Postgres reconciliation script does not contain permissive psql fallback"
else
echo "️ Skipping custom postgres entrypoint check (not Sirius postgres image)"
fi
if ! docker exec "$CTR_ENGINE" bash -lc 'for bin in bash curl psql pkill nmap rustscan pwsh; do command -v "$bin" >/dev/null || exit 1; done'; then
echo "❌ sirius-engine runtime binary contract check failed"
exit 1
fi
echo "✅ sirius-engine runtime binary contract check passed"
if ! docker exec "$CTR_ENGINE" bash -lc '/bin/bash -n /start-enhanced.sh && grep -q "validate_required_binary \"psql\"" /start-enhanced.sh'; then
echo "❌ sirius-engine startup script contract check failed"
exit 1
fi
echo "✅ sirius-engine startup script contract check passed"
HOST_PROBE="${SIRIUS_API_PUBLIC_URL}/host/"
unauth_code="$(curl -sS --max-time 15 -o /tmp/sirius-auth-unauth.out -w '%{http_code}' "$HOST_PROBE" || true)"
if [ "$unauth_code" != "401" ]; then
echo "❌ Expected unauthenticated /host/ to return 401, got $unauth_code (URL: $HOST_PROBE)"
exit 1
fi
echo "✅ Unauthenticated API contract check passed"
auth_code="$(curl -sS --max-time 15 -o /tmp/sirius-auth-auth.out -w '%{http_code}' -H "X-API-Key: $api_key" "$HOST_PROBE" || true)"
if [ "$auth_code" = "401" ] || [ "$auth_code" = "403" ] || [ "$auth_code" = "000" ]; then
echo "❌ Authenticated /host/ request failed with status $auth_code"
exit 1
fi
if ! [[ "$auth_code" =~ ^[0-9]+$ ]]; then
echo "❌ Unexpected curl HTTP code output: $auth_code"
exit 1
fi
if [ "$auth_code" -lt 200 ] || [ "$auth_code" -ge 300 ]; then
echo "❌ Authenticated /host/ expected HTTP 2xx, got $auth_code"
exit 1
fi
echo "✅ Authenticated API contract check passed (status $auth_code)"
if ! docker exec "$CTR_POSTGRES" sh -lc 'PGPASSWORD="$POSTGRES_PASSWORD" psql -h 127.0.0.1 -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "SELECT 1;" >/dev/null'; then
echo "❌ Postgres runtime credential probe failed"
exit 1
fi
echo "✅ Postgres runtime credential probe passed"
echo "✅ Runtime auth contract verification succeeded"