Control Plane¶
The control plane is a small set of .NET 8 services that handle everything around the real-time netcode: identity, matchmaking/fleet orchestration, social, the developer console, and analytics. They are independently deployable and talk to each other over HTTP, sharing one primitive: EdDSA / Ed25519 JWTs verified offline against each issuer's JWKS.
flowchart LR
subgraph clients[Game clients]
C[player client]
end
subgraph cp[Control plane .NET 8]
AU[lattice-auth<br/>identity + tokens]
DI[lattice-director<br/>matchmaking + fleet]
SO[lattice-social<br/>friends/presence/parties + WS]
CO[lattice-console<br/>dev/game registry + RBAC :3004]
AN[lattice-analytics<br/>events + metrics :3006]
PO[lattice-portal<br/>developer dashboard :3007]
end
subgraph dp[Data plane]
GS[lattice-gameserver]
end
C -->|guest/login| AU
C -->|matchmake/resolve| DI
C -->|friends/presence| SO
DI -->|verify access token| AU
DI -->|mints session token| GS
GS -->|register/heartbeat| DI
SO -->|verify JWT / resolve game key| AU
SO -->|tenancy| CO
AN -->|validate game key| CO
PO -->|upstreams| CO
PO -->|upstreams| AN
Services at a glance¶
| Service | Purpose | Port | Primary auth |
|---|---|---|---|
| lattice-auth | Account/identity, Ed25519 token issuance, bans | default binding (3004–3010 range) | anonymous → bearer JWT |
| lattice-director | Fleet registry, matchmaking, session-token mint | default binding | bearer JWT (players) + X-Fleet-Token (servers) |
| lattice-social | Friends, presence, parties, invites, chat + WebSocket | LB-fronted wss://…:9443/v1/ws |
bearer JWT or X-Api-Key |
| lattice-console | Developer accounts, game registration + API keys, module admission, RBAC/tenancy authority | 3004 | developer bearer + game API key |
| lattice-analytics | Telemetry ingestion + RBAC-scoped metrics | 3006 | game API key (ingest) + developer bearer (query) |
| lattice-portal | The developer dashboard UI | 3007 | developer session (upstreams console + analytics) |
Two non-interchangeable token families¶
sequenceDiagram
participant C as Client
participant AU as lattice-auth
participant DI as lattice-director
participant GS as Game server
C->>AU: POST /guest or /login
AU-->>C: access_token (iss=lattice-auth, aud=lattice, TTL 10m) + refresh (30d)
C->>DI: POST /matchmake (Bearer access_token)
DI->>AU: verify offline via JWKS
DI-->>C: session_handle
C->>DI: POST /resolve
DI-->>C: session_token (iss=lattice-director, aud=lattice-gameserver, TTL 2m) + endpoint
C->>GS: connect(endpoint, session_token)
GS->>DI: verify offline via JWKS
- Access tokens —
iss=lattice-auth,aud=lattice,alg=EdDSA, TTL 10 min; refresh TTL 30 days. Claims:sub, sid, platform, roles[], region, iss, aud, iat, exp, jti. - Session tokens —
iss=lattice-director,aud=lattice-gameserver,alg=EdDSA, TTL 2 min. Claims:sid, hdl, ep, sub, region, iat, exp, jti.
Both are verified offline against /.well-known/jwks.json published by their issuer. kid in
the header selects the public key.
Header conventions¶
| Header | Used by |
|---|---|
Authorization: Bearer <jwt> |
everywhere (access token / developer session) |
X-Lattice-Api-Key + X-Lattice-Api-Secret |
game API key — console + analytics + tenancy |
X-Fleet-Token |
director fleet endpoints (shared secret, constant-time compared) |
X-Api-Key + X-User-Id (+ X-User-Handle) |
social server-to-server (impersonation) |
X-Lattice-Game-Key / X-Lattice-Game-Secret |
social / analytics tenancy (cross-game visibility) |