Overview
TokenSmith implements JSON Web Tokens (JWT, RFC 7519) for Unreal Engine 4.27 and 5.8. Use it to issue session tokens on a dedicated server, to check tokens your backend hands to clients, or to read the claims of a token your login service returned.
- Generate signed tokens with your own payload and header claims, an optional issued-at claim, not-before and expiry times.
- Registered claims: type (
typ), content type (cty), key id (kid), subject, audience and token id.
- Verify the signature plus issuer, subject, audience, token id and any custom claim, with a clock-skew leeway.
- Read every payload claim of a token into a String-to-String map.
- HMAC (HS256, HS384, HS512) with a shared secret and RSA (RS256, RS384, RS512) with PEM keys.
- 17 Blueprint nodes on the
UTokenSmithSubsystem engine subsystem, plus a C++ API.
- Uses the engine’s own OpenSSL; no network access, no external services.
Requirements
| Requirement | Details |
| Unreal Engine | 4.27 and 5.8 (verified clean on both) |
| Modules | TokenSmith (Runtime), TokenSmithVerifier (Runtime), TokenSmithGenerator (Runtime) |
| Dependencies | None (engine modules only; signing uses the engine’s OpenSSL module). |
| Language | Blueprints and C++ |
| Platforms | Win64, Linux and Linux ARM64 (LinuxAArch64 on UE 4.27, LinuxArm64 on UE 5.8), as listed in the plugin descriptor. Win64 is the platform built and verified by Alpha XP; the Linux targets are supported by the code, not verified by Alpha XP. |
Installation
- Copy the
TokenSmith folder into your project’s Plugins folder (or install it to the engine from Fab).
- Open the project; C++ projects build the plugin modules on the first start.
- Enable TokenSmith in Edit > Plugins and restart the editor.
- C++ only: add
"TokenSmith", "TokenSmithGenerator" and "TokenSmithVerifier" to your module’s dependencies and set bEnableExceptions = true; in that module’s Build.cs — the public headers include the JWT library, which reports errors with C++ exceptions.
Verifying the installIn any Blueprint graph, search for Generate Signed JWT: the TokenSmith nodes are listed under TokenSmith > Generator and TokenSmith > Verifier. At startup the Output Log shows TokenSmithGenerator Startup and TokenSmithVerifier Startup.
Quick start
Blueprint
- Place the TokenSmith Subsystem getter (search for TokenSmith Subsystem; it is an engine subsystem and works in any Blueprint).
- Call Initialize JWT Generator with your secret and
HS256.
- Call Generate Signed JWT: tick IATClaim, fill Claims (for example
role → admin), leave Not Before Sec at 0 and Expire After Sec at 900. The return value is the token.
- Call Initialize JWT Verifier with the same secret and
HS256, then Verify JWT with the token: it returns true.
- Call Get Claims to read the payload as a map.
C++
// MyModule.Build.cs:
// PrivateDependencyModuleNames.AddRange(new string[] { "TokenSmith", "TokenSmithGenerator", "TokenSmithVerifier" });
// bEnableExceptions = true;
#include "TokenSmithSubsystem.h"
#include "Engine/Engine.h"
void IssueAndCheckToken()
{
UTokenSmithSubsystem* Tokens = GEngine->GetEngineSubsystem<UTokenSmithSubsystem>();
Tokens->InitGenerator(TEXT("my-shared-secret"), ETokenSmithGeneratorAlgorithm::HS256);
Tokens->SetSubject(TEXT("player-42"));
TMap<FString, FString> Claims;
Claims.Add(TEXT("role"), TEXT("admin"));
const FString Token = Tokens->GenerateJwtToken(true, Claims, TMap<FString, FString>(), 0, 900);
Tokens->InitVerifier(TEXT("my-shared-secret"), ETokenSmithVerifierAlgorithm::HS256);
Tokens->WithSubject(TEXT("player-42"));
const bool bValid = Tokens->VerifyJWT(Token);
const TMap<FString, FString> Payload = Tokens->GetClaims(Token);
UE_LOG(LogTemp, Display, TEXT("Valid: %d, role: %s"), bValid ? 1 : 0, *Payload.FindRef(TEXT("role")));
}
Generator nodes
Category TokenSmith | Generator, on UTokenSmithSubsystem. Settings made with these nodes stay on the shared generator and apply to every token generated afterwards.
| Node | Type | Description |
| Initialize JWT Generator | Callable | Key, Algorithm. Sets the signing key and algorithm: the shared secret for HS256/384/512, the PEM private key for RS256/384/512. |
| Set Type | Callable | Sets the typ header claim. |
| Set Content Type | Callable | Sets the cty header claim. |
| Set Key ID | Callable | Sets the kid header claim. |
| Set Subject | Callable | Sets the sub payload claim. |
| Set Audience | Callable | Sets the aud payload claim. |
| Set ID | Callable | Sets the jti payload claim. |
| Generate Signed JWT | Callable | IATClaim, Claims, Header Claims, Not Before Sec (default 0), Expire After Sec (default 900) → String. Adds iat (now) when IATClaim is set, nbf = now + Not Before Sec and exp = now + Expire After Sec, plus your string claims, and signs the token. Returns an empty string on failure. |
Verifier nodes
Category TokenSmith | Verifier, on UTokenSmithSubsystem. Requirements added with the With nodes stay on the shared verifier for the rest of the session.
| Node | Type | Description |
| Initialize JWT Verifier | Callable | Key, Algorithm. Allows the algorithm with the given key: the shared secret for HS256/384/512, the PEM public key for RS256/384/512. |
| With Issuer | Callable | Requires the iss claim to equal the value. |
| With Subject | Callable | Requires the sub claim to equal the value. |
| With Audience | Callable | Requires the aud claim to contain the value. |
| With Leeway | Callable | Leeway (seconds) tolerated when checking exp, nbf and iat against the local clock. |
| With ID | Callable | Requires the jti claim to equal the value. |
| With Custom Claim | Callable | Name, Value. Requires a string claim with that name and value. |
| Verify JWT | Callable | Input → Boolean. True when the token decodes, its algorithm is allowed, the signature matches, it is within its time window and every requirement holds. Failures are logged with the reason. |
| Get Claims | Callable | JWTToken → String-to-String map. All payload claims; strings without quotes, numbers and other JSON values as their JSON text. Does not verify the token — call Verify JWT first. |
Algorithms
| Node | Type | Description |
| ETokenSmithGeneratorAlgorithm | Enum | Input of Initialize JWT Generator: HS256, HS384, HS512, RS256, RS384, RS512. |
| ETokenSmithVerifierAlgorithm | Enum | Input of Initialize JWT Verifier: the same six values. |
Keys are passed as text: for HMAC the secret itself, for RSA the complete PEM block including the -----BEGIN ...----- and -----END ...----- lines. Keys, claim names and claim values are handled as UTF-8.
C++ API
| Node | Type | Description |
| UTokenSmithSubsystem | Class | Engine subsystem with all the nodes above as C++ functions: InitGenerator, SetType, SetContentType, SetKeyID, SetSubject, SetAudience, SetID, GenerateJwtToken, InitVerifier, WithIssuer, WithSubject, WithAudience, SetLeeway, WithID, WithCustomClaim, VerifyJWT, GetClaims. Get it with GEngine->GetEngineSubsystem<UTokenSmithSubsystem>(). |
| GetTokenSmith | Callable | TSharedPtr<FTokenSmithModule> GetTokenSmith() on the subsystem. |
| FTokenSmithModule | Class | GetGenerator() and GetVerifier() return the generator and verifier the subsystem uses. |
| FTokenSmithGeneratorModule | Class | InitGenerator, SetType, SetContentType, SetKeyID, SetSubject, SetAudience, SetID, GenerateJwtToken(bool IATClaim, int32 NotBeforeSec, int32 ExpireAfterSec, TMap<FString, FString> Claims, TMap<FString, FString> HeaderClaims). |
| FTokenSmithVerifierModule | Class | InitVerifier, WithIssuer, WithSubject, WithAudience, SetLeeway, WithID, WithCustomClaim, VerifyJWT, GetClaims. |
ExceptionsEvery module that includes a TokenSmith header must set bEnableExceptions = true; in its Build.cs. Without it MSVC reports warning C4530 and the build may fail. Blueprint-only projects are not affected.
Troubleshooting
| Symptom | Cause and fix |
| Verify JWT returns false | The Output Log (LogTokenSmithVerifier) shows the reason. Usual causes: wrong key or algorithm, the token expired (exp) or is not valid yet (nbf), or an issuer / subject / audience / id / custom claim requirement does not match. Use With Leeway when server and client clocks differ. |
Generate Signed JWT returns an empty string, log Error generating JWT. | For RS256/384/512 the generator key must be a valid PEM private key (the verifier takes the public key). Call Initialize JWT Generator before generating. |
| A token stops verifying after other code used the subsystem | The generator and verifier are shared engine-wide and keep every setting and requirement for the session. Set the requirements you need in one place, early, rather than per call. |
| C++ build error or warning C4530 in your module | Add bEnableExceptions = true; to the Build.cs of every module that includes TokenSmith headers. |
| Get Claims returns an empty map | The input is not a well-formed JWT (three dot-separated Base64URL parts), or it is empty. |
Numbers come back as text such as 1767225600 | Get Claims returns every claim as a string; convert numeric claims (for example exp) with the usual string conversion nodes. |
| Plugin modules are missing on Mac, Android or iOS | The plugin descriptor enables the modules for Win64, Linux and Linux ARM64 only. |