Skip to content

Security Control Verification Matrix

Control Area Control Owner Verification Method Frequency
Auth OIDC + short-lived access tokens Security integration tests + pen-test each release
AuthZ Role/tenant policy enforcement Backend authz test suite + code review gates each PR
Secrets secret manager only, no hardcoded secrets Security/Platform secret scan + config review each PR
Transport TLS at edge, secure internal transport Platform config validation + periodic scan monthly
Session security admin token emergency deny-list Security/Backend revocation drill + auth middleware test each release
Realtime channel isolation Redis ACL for notification publish/subscribe Security/Platform ACL config review + negative subscribe test each release
Runtime key handling No persistent user private-key storage for allocation access Security/Platform API contract review + storage/log scan + negative endpoint test each release
Runtime key handling User-managed SSH public key path only for runtime access Security/Backend request/response contract checks + integration tests each release
Terminal session auth Single-use terminal token atomic consume (Redis GETDEL) — no replay Backend/Security replay attack test (reuse consumed token → 401) each release
Terminal session binding Session bound to {session_id, user_id, allocation_id, node_id, expires_at} — gateway enforces at open Backend binding invariant test + mismatch rejection test each release
Terminal session concurrency Single active terminal session per allocation enforced at open Backend concurrent open attempt test → second open rejected each release
Terminal session TTL Active session closed at terminal.session_max_ttl_seconds (policy key, default 4h) — not inherited from OIDC token TTL Backend TTL expiry test with short policy override each release
Terminal task signing terminal.open task signed with Ed25519 — node rejects unsigned or replayed task Security/Node signature bypass test + replay test → node rejected each release
Terminal least-privilege boundary Terminal path allows only user impersonation bootstrap; interactive shell runs as allocation user with no privileged lifecycle operations Security/Backend integration test verifies effective uid/gid; negative test forbids privileged terminal operations; sudoers policy review each release
SKU lifecycle governance SKU lifecycle changes (create/update/activate/deactivate) require approval policy and node-registration references only active catalog SKUs Platform/Inventory change-review evidence + negative registration test for invalid/inactive SKU reference + runbook mapping check each release
Terminal release sequencing Allocation release closes terminal first (allocation_released frame + ack/timeout) before allocation.revoke_user Backend release-during-active-terminal integration test each release
Terminal session audit Every terminal open/close recorded in audit_logs with session_id, user_id, allocation_id, reason Backend audit log presence check in integration tests each release
Payments webhook raw-body signature verification before JSON parse + event-id idempotency Payments integration replay tests + signature bypass tests each release
Billing immutable ledger writes Billing ledger invariant tests each release
Audit privileged action logging Platform log schema checks + spot audit weekly
Abuse WAF/rate limits/bot controls Platform load+abuse tests monthly

Release Blocking Controls

  • Auth/AuthZ verification pass
  • Admin token revocation drill pass
  • Redis notification ACL isolation test pass
  • Runtime key handling checks pass (no persistent private-key endpoint/data path)
  • Secrets scan pass
  • Webhook replay/idempotency tests pass
  • Webhook signature bypass test (AT-053) pass
  • Ledger integrity tests pass
  • Terminal token replay rejection test pass
  • Terminal session binding invariant test pass
  • Terminal least-privilege boundary checks pass
  • SKU lifecycle governance checks pass
  • Terminal release sequencing test pass (terminal closed before revoke_user)

Implementation Requirements

Stripe Webhook Signature Verification

The Payments service MUST verify the Stripe webhook signature against the raw request body bytes before any JSON parsing or deserialization occurs. - Read the raw body stream once and buffer it. - Verify the Stripe-Signature header against the buffered bytes using the signing secret. - Only proceed to JSON parse if verification passes. - Reject any request that pre-parses JSON before signature check — this is a known class of signature bypass attack. - Required test case: AT-053 — reuse a previously valid Stripe-Signature header with a modified request body and confirm 400 rejection.

Runtime Access Key Handling (Post-Cutover)

Runtime access MUST avoid persistent user private-key storage and re-download paths. - Allowed model: user-managed public key registration and runtime access via terminal/SSH proxy controls. - Disallowed model: API or database persistence of user private key material for later retrieval. - Verification evidence for this control family: - threat baseline linkage: doc/architecture/Threat_Model.md - ops tracking: doc/governance/Agent_Work_Queue.yaml task C-OPS-003