lattice-console — Developer & game registry, RBAC/tenancy authority¶
Developer accounts, game registration + API keys, server-module build admission, and user↔game
registration. It is the platform's RBAC / tenancy authority — social and analytics resolve game
keys and visibility against it. Source: control-plane/lattice-console/src/LatticeConsole/Program.cs.
- Port:
http://localhost:3004(hard-coded). - Auth: developer bearer token (
Authorization: Bearer); RBAC roles super-admin / developer. Game API-key auth viaX-Lattice-Api-Key+X-Lattice-Api-Secret. A configurable single super-admin is seeded at startup. - DTOs use PascalCase.
Developer accounts¶
| Method · Path | Auth | Body → Response |
|---|---|---|
POST /developers/register |
anonymous | {Email, Password, DisplayName} → AuthResponse{Token, DeveloperId, Email, Role} |
POST /developers/login |
anonymous | {Email, Password} → AuthResponse |
GET /admin/developers |
super-admin | DeveloperView[]{Id, Email, DisplayName, Role, CreatedAt} |
Games¶
Developer-scoped (super-admin sees all). Bearer.
| Method · Path | Purpose |
|---|---|
POST /games |
{DisplayName, LaunchCommand?} → GameWithSecretView{Game, ApiSecret} (secret revealed once) |
GET /games |
GameView[]{GameId, DeveloperId, DisplayName, ApiKey, LaunchCommand, Settings, CrossGameVisibility, CreatedAt, UpdatedAt} |
GET /games/{gameId} |
one GameView |
PATCH /games/{gameId} |
{DisplayName?, LaunchCommand?, Settings?, CrossGameVisibility?} → GameView |
DELETE /games/{gameId} |
delete |
POST /games/{gameId}/regenerate-key |
GameWithSecretView (new secret) |
GET /games/{gameId}/users |
UserRegistrationView[]{Id, UserId, GameId, DisplayName, RegisteredAt} |
Server-module builds¶
Dev-scoped. Bearer. This is the upload → scan → register flow for managed-hosted modules — see 09 — WASM Managed Hosting and the managed WASM walkthrough.
| Method · Path | Purpose |
|---|---|
POST /games/{gameId}/modules |
{Packaging:"wasm"\|"native", Version, WasmBase64?} → ModuleBuildView{BuildId, GameId, Packaging, Version, SizeBytes, Sha256, Admitted, Schedulable, Imports[], CreatedAt} |
GET /games/{gameId}/modules |
ModuleBuildView[] |
A wasm upload runs the import-allowlist scan (WasmImportScanner): admitted ⇒ stored with
the seen imports + SHA-256 + Schedulable=true; rejected ⇒ 400 with the offending imports named
and nothing stored.
Super-admin & game-API-key¶
| Method · Path | Auth | Purpose |
|---|---|---|
GET /admin/users |
super-admin | all UserRegistrationView[] |
POST /auth/validate-key |
anonymous (body-validated) | {ApiKey, ApiSecret} → ValidateApiKeyResponse{Valid, GameId?} (401 when invalid) |
POST /games/register-user |
game API-key headers | {UserId?, DisplayName?, Provider?, ExternalId?, Ticket?, Email?, Password?} → RegisterUserResult{Registration, Sub, AccountCreated} (resolves the player's third-party identity to a Lattice account via lattice-auth) |
GET /healthz |
— | liveness |
Register a game, get the API key + secret
TOKEN=$(curl -s -X POST http://localhost:3004/developers/login \
-H 'content-type: application/json' \
-d '{"Email":"you@studio.gg","Password":"..."}' | jq -r .Token)
curl -s -X POST http://localhost:3004/games -H "authorization: Bearer $TOKEN" \
-H 'content-type: application/json' \
-d '{"DisplayName":"My Game","LaunchCommand":"./mygame"}' | jq
# => { "Game": { "GameId": "...", "ApiKey": "lat_pub_..." }, "ApiSecret": "lat_sec_..." }