diff --git a/docs/MATCHMAKING.md b/docs/MATCHMAKING.md index da470ce6..056a5a34 100644 --- a/docs/MATCHMAKING.md +++ b/docs/MATCHMAKING.md @@ -101,7 +101,7 @@ roles rather than independently designed microservices: | API | HTTPS/WebSocket auth, profile, queue commands, status resync | | Matcher | Atomic proposal formation from queue state | | Allocator | Agones allocation, server registration, assignment delivery | -| Maintenance worker | Outbox delivery, season rollover, expiry, reconciliation | +| Maintenance worker | Season rollover, initial-connect/no-show expiry, live reconnect-abandonment reconciliation, and other durable lifecycle recovery | API replicas are stateless. Redis sorted sets provide the fast candidate index, but Redis is never the durable allocation fence: asynchronous failover @@ -356,16 +356,17 @@ public-IP/unsolicited-UDP reachability, provider firewall/NAT validation, per-location certificates and coordinator trust. Use an Agones dynamic or passthrough mapping whose externally reported port is the `SDR_IP` port while the process binds `SDR_LISTEN_PORT`; test SDR and ENet mappings separately. -Credentials arrive through runtime secret mounts, never allocation metadata, -arguments, logs or images. - -Result authentication uses a projected, pod-bound service-account token with -a dedicated audience and one service account per workload class. The backend -validates the configured cluster issuer/JWKS, audience, expiry, namespace, -service account, bound pod UID and allocator-recorded GameServer UID, then -checks that GameServer/match binding in PostgreSQL. Issuers and trust roots are -allowlisted and rotated explicitly for every cluster/provider. A one-match -server credential issued after this attestation is an acceptable equivalent. +The control plane's HMAC signing secret arrives through a runtime Secret mount; +it never reaches the game pod, command line, logs, or image. For each +allocation, the allocator signs a short-lived bearer token containing only the +allocation ID and requests Agones to attach it to the selected GameServer's +metadata. The allocated pod's local SDK sidecar is the delivery boundary: the +supervisor reads that annotation and supplies it only as a child-process +environment variable. The backend verifies the HMAC and expiry, then resolves +the allocation ID to the durable allocation/match/server tuple in PostgreSQL; +the game server cannot choose that binding. A future projected-service-account +attestation may replace this delivery mechanism, but it is not a current +security claim. ### Warm capacity and density diff --git a/docs/THREAT-MODEL.md b/docs/THREAT-MODEL.md index a7526a39..26d407ab 100644 --- a/docs/THREAT-MODEL.md +++ b/docs/THREAT-MODEL.md @@ -12,7 +12,7 @@ individual pod. | Queue/proposal flooding or duplicate claims | Body/rate limits, one active ticket partial unique index, idempotency keys, serializable participant fence | Per-identity/IP rate alerts, queue-depth and conflict dashboards, overload shedding | API/matcher | Distributed abusive identities can consume bounded capacity until automated bans act | | Latency-evidence forgery | Opaque location, nonce/freshness checks, server-computed RTT, discrepancy quarantine; evidence affects placement only | Three-bad/five-clean counters and regional RTT SLO alerts | Matcher/networking | Colluding endpoints can bias placement within the accepted evidence window | | Join-authorisation theft or slot hijack | Signed match-scoped authorisation binds verified SteamID/match/server/team/slot/protocol/expiry; server-owned generation fences old peers | Rejected-binding/generation metrics and audit events; revoke assignment | Allocator/game-server | A stolen valid authorisation remains usable until expiry unless the server revokes it | -| Forged or replayed match result | Pod/GameServer-bound projected identity or one-match credential; issuer/audience/namespace/SA/pod/GameServer/allocator binding; canonical digest | Receipt conflict is inert and pages; duplicate is idempotent; result lag alerts at 5/30 minutes | Result/maintenance | A compromised authoritative pod can submit before compromise is detected | +| Forged or replayed match result | Short-lived HMAC workload token delivered through the allocated GameServer annotation; backend resolves its allocation ID to the durable match/server binding; canonical digest | Receipt conflict is inert and pages; duplicate is idempotent; result lag alerts at 5/30 minutes | Result/maintenance | A compromised authoritative pod can submit before compromise is detected | | Workload/insider compromise | Per-workload service accounts, least RBAC, private stores, default-deny network, no publisher/root key in game pods | Credential-use audit, pod identity anomaly alerts, immediate workload drain/revoke | Platform/security | Cluster-admin or KMS compromise is outside application controls | | Gameplay/API DDoS and flood | Connection/body/WebSocket limits, token buckets, overload shedding, edge WAF/DDoS service, live-result priority | Saturation, 5xx, tick-backlog and dropped-work dashboards; shed new queue/allocation work first | SRE/platform | Volumetric attack may require provider mitigation capacity | | SDR signing-key theft | Offline CA separated from online signer; non-exportable KMS/HSM key; signer allowlist and short-lived tickets | Signer audit and anomaly alerts; rotate/revoke certificates and tickets | Security/networking | Provider/Valve trust or HSM compromise requires external response |