Skip to content

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 by VerifyJWT.
  • RS256: InitializePlayerJwtPublicKey(FString PublicKeyPem) — loads an RS256 public key for local player join JWT verification. Called by UMIPServerDataSubsystem on startup from the Agones JWT_PUBLIC_KEY_PEM_B64 annotation.
  • 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