Files
sxchnge/infra/local/scripts/verify.sh

62 lines
4.0 KiB
Bash

policies() (
root_token=$VAULT_TOKEN
identity=''
trap 'if [ -n "$identity" ]; then printf "{}" | VAULT_TOKEN=$identity vault auth/token/revoke-self POST >/dev/null; fi' EXIT
for service in bff notifications nats; do
directory="$STATE/agents/$service"
login=$(jq -n --rawfile role "$directory/role-id" --rawfile secret "$directory/secret-id" '{role_id:($role|rtrimstr("\n")),secret_id:($secret|rtrimstr("\n"))}' | vault auth/approle/login POST)
identity=$(printf '%s' "$login" | jq -er '.auth.client_token')
printf '%s' "$login" | jq '{token:.auth.client_token,paths:["kv/data/bootstrap/mongo","kv/data/infrastructure/mongo/bootstrap","sys/init","kv/data/bff","kv/data/caller","kv/data/services/notifications/callers/bff","kv/data/email","kv/data/nats","kv/data/tls"]}' | vault sys/capabilities POST | jq -e '.data | all(.[]; .==["deny"])' >/dev/null || fail 'Service can access bootstrap credentials'
VAULT_TOKEN=$(printf '%s' "$login" | jq -er '.auth.client_token')
printf '{}' | vault auth/token/revoke-self POST >/dev/null
VAULT_TOKEN=$root_token
identity=''
done
echo 'PASS: service identities cannot read bootstrap credentials'
)
database_access() (
for role in bff notifications; do
database=sxchnge; forbidden=sxchnge_notifications
if [ "$role" = notifications ]; then database=sxchnge_notifications; forbidden=sxchnge; fi
vault "database/creds/$role" > "$WORK/lease"
trap 'jq "{lease_id:.lease_id}" "$WORK/lease" | vault sys/leases/revoke POST >/dev/null' EXIT
{
jq -r '"db.getSiblingDB(\"admin\").auth("+(.data.username|tojson)+","+(.data.password|tojson)+");"' "$WORK/lease"
printf 'const database="%s", forbidden="%s";\n' "$database" "$forbidden"
cat infra/local/mongo/mongo-check.js
} | mongo > "$WORK/check" || fail 'Mongo access/transaction check failed'
grep -q scope-ok "$WORK/check" || fail 'Mongo check incomplete'
jq '{lease_id:.lease_id,increment:"1h"}' "$WORK/lease" | vault sys/leases/renew POST | jq -e '.lease_duration>0' >/dev/null || fail 'Mongo renewal failed'
jq '{lease_id:.lease_id}' "$WORK/lease" | vault sys/leases/revoke POST >/dev/null
trap - EXIT
{ admin_auth; jq -r '"print(admin.getUser("+(.data.username|tojson)+")===null);"' "$WORK/lease"; } | mongo > "$WORK/revoked" || fail 'Mongo revocation check failed'
grep -q true "$WORK/revoked" || fail 'Revoked Mongo user still exists'
done
echo 'PASS: Vault database issuance, isolated access, transaction commit/rollback, renewal and revocation'
)
infrastructure() {
compose ps --format json | jq -se '[.[] | select(.Service=="vault" or .Service=="mongo" or .Service=="nats")] | length==3 and all(.[];.Health=="healthy")' >/dev/null || fail 'Infrastructure is not healthy'
echo 'PASS: Vault, Mongo replica set and NATS JetStream are healthy'
layout
policies
database_access
}
# Resolve through Docker DNS while verifying the certificate for localhost.
https() { curl -sS --max-time 5 --cacert "$STATE/ca.pem" --connect-to localhost:5126:frontend:8443 "$@"; }
product() {
compose ps --format json | jq -se 'length==6 and all(.[];.Health=="healthy")' >/dev/null || fail 'Expected six healthy services'
https -f https://localhost:5126/ >/dev/null
https -f https://localhost:5126/api/v1/health >/dev/null
echo 'PASS: six healthy services, frontend and proxied BFF use verified TLS; no email sent'
}
layout() {
kv services/notifications/email/resend | jq -e 'keys==["api_key"]' >/dev/null || fail 'Non-secret email configuration remains in Vault'
for old in bootstrap/mongo bff caller services/notifications/callers/bff email nats tls frontend-tls notifications-tls; do
[ "$(vault "kv/metadata/$old" GET yes)" = null ] || fail "Obsolete KV entry remains: $old"
done
for path in services/bff/jwt services/notifications/email/resend infrastructure/nats/auth infrastructure/mongo/bootstrap; do
vault "kv/metadata/$path" | jq -e '.data.current_version>0' >/dev/null || fail "Missing canonical KV entry: $path"
done
echo 'PASS: canonical Vault hierarchy present; obsolete flat and TLS entries absent'
}