Customizing the JWT
Add custom claims to the access token without bloating it.
You'll often want extra fields on the JWT — subscriptionTier, appUserId, a feature-flag bundle. Two hooks give you control.
session.customizeSessionData(default, user)
Reshapes the session row (server-side state). Stored once at session creation, available on every refresh. Cheap to extend.
These fields don't go into the JWT unless you also write customizeTokenPayload.
session.customizeTokenPayload(default, session)
Reshapes the JWT claims (what the client sees on the access token). Be mindful — every byte here is on every authenticated request.
Reading from the client
In React, just use useUser() — anything you put in customizeSessionData (and surfaced via getSessionUserData) shows up there.
Don't put secrets in the JWT
The JWT is only signed, not encrypted. Anyone with the token can read every claim. Don't put PII you wouldn't want logged.
Don't put large arrays
If you need to ship 50 permissions, keep them on the session row, retrieved server-side via the request context. Frontend role checks should read from useUser() (which pulls them from getSessionUserData), not from the JWT directly.
What defaultPayload already contains
Don't remove these — guards depend on them. Add fields, don't replace.
Per-tenant claims
The customizeTokenPayload hook fires on every session create + refresh, so this re-resolves on tenant switch automatically.
Related
- Sessions & Tokens.
- Hooks Reference — full hook surface.
- User Model — the
getSessionUserDatacompanion hook. - Custom JWT claims recipe.