Sessions and tokens
How a signed-in session works: access and refresh tokens, automatic refresh and rotation, auth events in your app, devices, signing out everywhere, verifying tokens on your server and the session settings.
Signing in gives the app a session: a short-lived access token sent with every request, and a refresh token the SDK uses to get new access tokens. The SDKs handle all of this; this page explains what they do so you can reason about it.
Access and refresh tokens
| Access token | Refresh token | |
|---|---|---|
| Lives | 15 minutes by default (at most 60) | 7 days by default |
| Sent | With every request: Authorization: Bearer … | Only to POST /api/v1/auth/refresh |
| Format | A signed JWT (ES256) with sub, email, role, app_roles, aal, exp | Opaque |
| When used | — | Replaced on every refresh (rotation): each refresh token works once |
Rotation means a stolen refresh token is useful only until the real app refreshes; using an old refresh token fails. Signing out revokes the refresh token and the current access token immediately.
React to sign-in and sign-out
const stop = sovaria.auth.onAuthStateChange((event, session) => {
// INITIAL_SESSION (right away), SIGNED_IN, TOKEN_REFRESHED, SIGNED_OUT
if (event === 'SIGNED_OUT') router.push('/login')
else setUser(session?.user ?? null)
})
const session = sovaria.auth.getSession() // current session or null, no network call
// later: stop()In browsers the session is kept in storage and survives reloads; a session that can't be refreshed (revoked, expired, user banned) fires SIGNED_OUT.
Sessions and devices
A signed-in user can see and end their own sessions:
const sessions = await sovaria.auth.sessions.list() // device, IP, last used
await sovaria.auth.sessions.revoke(sessionId) // one
await sovaria.auth.sessions.revokeOthers() // everywhere but here- Changing or resetting the password signs the user out on every other device.
- Banning or deleting a user ends all their sessions (Users and app roles).
- Mobile apps register each device; signing a device out also stops its push notifications (Sign-in for mobile apps).
Session settings
Under Authentication › Sessions: access and refresh token lifetimes, a time-box (sessions end after a fixed time whatever happens), an inactivity timeout and single session (signing in elsewhere ends the old session). The last three need a paid plan.
| Free | Pro | Ultra | Team | Enterprise | |
|---|---|---|---|---|---|
| Session time-box, inactivity timeout and single session | — | ✓ | ✓ | ✓ | ✓ |
Check a token on your own server
To accept Sovaria users in your own API, verify the access token with the project's public keys. Never decode it without checking the signature.
import { createRemoteJWKSet, jwtVerify } from 'jose'
const JWKS = createRemoteJWKSet(new URL('https://<project-ref>.sovarias.in/auth/v1/.well-known/jwks.json'))
export async function userFrom(req) {
const token = req.headers.authorization?.replace(/^Bearer /, '')
const { payload } = await jwtVerify(token, JWKS, { algorithms: ['ES256'] })
return { id: payload.sub, email: payload.email, roles: payload.app_roles ?? [] }
}