How It Works
1
Your backend signs a JWT
After your own auth system verifies the user, your server signs a JWT using
your Sublay project’s RSA private key. The token identifies the user by
their ID in your system.
2
The SDK exchanges the JWT
Call
verifyExternalUser (available via the useAuth hook or directly) with
the signed JWT. Sublay verifies the signature, looks up or creates the user,
and returns Sublay access and refresh tokens.3
The user is authenticated
From this point, the user is signed into Sublay and all SDK hooks work
normally. Token refresh is handled automatically.
JWT Requirements
Your backend must sign the JWT using RS256 (RSA 256-bit) with your project’s private key. The payload must include:userData fields
All fields in userData are optional. If a user already exists and any field has changed, Sublay updates the stored value.
Backend Example (Node.js)
Frontend Integration
Pass the signed JWT directly toSublayProvider (or SublayIntegrationProvider if you manage your own Redux store) via the signedToken prop. The SDK exchanges the token automatically on initialization — no manual API calls required.
signedToken changes (e.g., after a new user signs in), the SDK re-initializes auth with the updated token automatically.
The Account Limit
A device stores at most 5 accounts (Multi-Account). If the verified token identifies a sixth, distinct user, the exchange is refused: the session Sublay just created is signed back out, the stored accounts are left untouched, and the app renders signed-out withaccountLimitReached set.
- A
signedTokenfor an already-stored user is never refused. The check is keyed on the user id Sublay resolves from the token, not on anything inuserData, so returning users sign in normally at the limit. - The refusal is not silent, and it does not fall back. Because the provider exchanges the token on every launch, a refused exchange would otherwise repeat invisibly forever — or quietly restore some other stored account instead. Instead the SDK surfaces the reason and sets
accountLimitReached. The auth gate still opens, so the app renders normally in its signed-out state rather than hanging. - The refusal is not recorded as a sign-out. Nobody signed out — an admission was refused — so the selection is left exactly where it was and
signedOutis not set. The next launch therefore behaves as it would have without the refused attempt, rather than reproducing the same dead end forever. See Reaching the account limit.
User Identity
When a user signs in via external auth, Sublay stores thesub claim as foreignId on the user record and creates a UserIdentity entry with provider: "external". On subsequent sign-ins, the user is looked up by identity first, then by foreignId as a fallback, then by email.

