๐ FireMUD System Architecture: Authentication & Authorization
This document describes how FireMUD authenticates clients, issues internal JWTs, manages session state, and enforces role-based access across services.
Authentication is performed via plaintext LOGIN
commands. Clients are stateless; session state is managed server-side in Redis and restored via the Game Session Service.
๐ Login and Session Flow
All clients โ whether connecting via Telnet or WebSocket โ must authenticate using the LOGIN
command:
LOGIN
โ Starts prompt-based login (username โ password)LOGIN <username> <password>
โ Attempts immediate loginLOGON
โ Alias forLOGIN
Clients must re-authenticate only after disconnecting (TCP or WebSocket loss).
If a valid Redis session exists (accountId + playerId
), the Game Session Service resumes gameplay seamlessly.
๐ For session resumption and reconnect edge cases, see Reconnection Strategy
๐ฅ Multi-Client Behavior and Session Takeover
Each character can only be controlled by one session at a time.
If a new login is received for the same playerId
:
- The existing session is terminated
- The Redis session is rebound to the new socket
- Tick state, command queues, and timers are preserved
This enables:
- Clean device handoff
- Forced logins (e.g., โkick and take overโ)
- Seamless resumption without gameplay loss
๐ All session rebinding is enforced by the Game Session Service using Redis locks. ๐ See Redis Session Keys
๐งพ JWT Format and Role Claims
Internal JWTs are issued by the Account Service and used for backend gRPC authorization. Gameplay clients never store or transmit tokens. Admin UIs may supply JWTs for optional validation at the Spring Cloud Gateway.
๐ง Claims
Field | Description |
---|---|
accountId | Identity of the authenticated account |
globalRoles | Cross-game privileges (e.g., platformAdmin , moderator ) |
scopedRoles | Map of gameId โ roles (e.g., "game-abc": ["admin", "designer"] ) |
๐งพ Example JWT Payload
accountId
:"user-123"
globalRoles
:["moderator"]
scopedRoles
:"game-abc"
โ["admin", "designer"]
"game-def"
โ["moderator"]
Tokens are short-lived and internal only. Gameplay context (e.g.,
playerId
,worldId
) is stored in Redis and sent via command envelopes.
๐ฎ Role-Based Authorization
Access to services is governed by roles from the JWT:
Context | Description |
---|---|
globalRoles | Platform-wide access (e.g., moderation, admin dashboards) |
scopedRoles | Per-game access (e.g., designer tools, admin features for a game) |
JWT Usage Scope
- โ Meta/control services (e.g. Game Design, Admin, Account) validate JWTs to authorize access
- ๐ซ Gameplay services (e.g. Game Logic, Entity, World) do not validate JWTs โ they rely on the Game Session Service to enforce access
๐ Mid-Session Role Updates
If roles change during an active session (e.g., a player is promoted to admin):
- The Game Session Service detects or requests a role refresh
- It contacts the Account Service to obtain a new JWT
- Updated claims are injected into subsequent gRPC calls
โ This process is invisible to the client โ no re-login is needed.
๐ง Session and Identity Management
The Game Session Service is responsible for:
- Authenticating sockets and binding identity context
- Managing Redis session state (e.g.
playerId
,worldId
, tick region) - Managing JWTs for backend interactions
๐ See Session Keys and Gameplay Binding for Redis structure and gameplay rebinding.
โ Summary
Topic | Description |
---|---|
Auth Command | LOGIN (or LOGON ) โ supports prompt or argument input |
JWT Usage | Internal-only for backend gRPC auth |
Claims | accountId , globalRoles[] , scopedRoles{} |
Session State | Stored in Redis; bound to socket by Game Session Service |
Reauthentication | Required after disconnect; resumes via Redis if valid |
Role Enforcement | Meta/control services only; gameplay services trust Game Session Service |
Role Updates | Refreshed in-session; no client interaction needed |
Multi-Client Behavior | One session per character; new login replaces old session |