JWT¶
Overview¶
UMIPJwtSubsystem is an Engine subsystem wrapping the jwt-cpp library. It supports HS256 (shared secret via InitializeJwt) and optional RS256 verification for player join tokens using a PEM public key (InitializePlayerJwtPublicKey). Blueprints can call VerifyJWT and GetPayload for generic token inspection.
All paths below are relative to Plugins/ModularInventoryPlus/Source/ModularInventoryPlus/.
Key Classes & Files¶
| Class | File |
|---|---|
UMIPJwtSubsystem |
Public/Jwt/MIPJwtSubsystem.h |
UMIPJwtSubsystem¶
- HS256:
InitializeJwt(FString SecretKey)— initializes the shared-secret verifier used byVerifyJWT. - RS256:
InitializePlayerJwtPublicKey(FString PublicKeyPem)— loads an RS256 public key for local player join JWT verification. Called byUMIPServerDataSubsystemon startup from the AgonesJWT_PUBLIC_KEY_PEM_B64annotation. - Join validation:
VerifyPlayerJoinJwtIfConfigured— checks the join JWT signature when RS256 is configured; passes through otherwise (see table below). - Blueprint:
VerifyJWT,GetPayload→ map of claim strings.
Verification Behavior¶
VerifyPlayerJoinJwtIfConfigured applies the following logic. jwt-cpp rejects alg: none by default; that case never reaches this table.
Token alg header |
RS256 public key loaded | Result |
|---|---|---|
RS256 |
Yes | Signature verified locally — throws on failure, returns false |
RS256 |
No | Returns false — a key is required when the token declares RS256 |
Other (e.g. HS256) |
No | Returns true — passthrough (dev / PIE / non-Agones) |
Other (e.g. HS256) |
Yes | Returns true — the loaded key is RS256-only; non-RS256 tokens are not verified by it |
PIE / local dev
Editor and PIE runs do not load a public key (no Agones allocation). VerifyPlayerJoinJwtIfConfigured therefore returns true for any non-RS256 join token, which is the intended behavior for local development. RS256-signed tokens in PIE still require a loaded key and will be rejected without one.
Agones Integration¶
UMIPServerDataSubsystem::SetValuesFromAnnotations reads the Agones annotation JWT_PUBLIC_KEY_PEM_B64 (a base64-encoded UTF-8 PEM string), decodes it, and calls InitializePlayerJwtPublicKey. This happens at allocation time, before any player can connect.
The local RS256 check is defense-in-depth: it verifies the cryptographic signature without a network round-trip, complementing the backend's single-use VERIFY_JOIN_GAME_TOKEN Socket.IO check. The backend check must pass first (consuming the Redis key); the local check must then succeed before FMIPPlayerInfo is trusted.
See Dedicated Server for the full annotations reference and Auth & Join Flow for where these checks sit in the player join sequence.
Integration¶
- Dedicated Server —
JWT_PUBLIC_KEY_PEM_B64annotation →InitializePlayerJwtPublicKey. - Auth & Join Flow — local RS256 check position in Phase 4.
- Backend API — HTTP
access_tokenis separate from join JWTs.