Every request runs as a database role chosen from its key and token. Access tokens are JWTs signed with your project's secret.
#Roles
| Role | Used when |
|---|---|
anon | A request uses the anon key without a signed-in user |
authenticated | A request carries a signed-in user's access token |
service_role | A request uses the service_role key. It bypasses Row Level Security, so keep it on the server. |
#Token claims
| Claim | Value |
|---|---|
sub | The user id (auth.uid()) |
role | authenticated for users; the anon and service_role keys carry anon and service_role |
aud | authenticated |
email, phone | The user's contact details |
app_metadata | Set by the server only (provider, providers); safe for authorization |
user_metadata | Set by the user with updateUser({ data }); never trust it for authorization |
aal, amr | Assurance level (aal1 or aal2) and how the user signed in |
session_id | The session the token belongs to |
is_anonymous | true for anonymous users |
exp, iat | Expiry and issue time |
#Token claims in SQL
SQL
select auth.uid(), auth.jwt() ->> 'email', auth.jwt() -> 'app_metadata' ->> 'provider';#Verify tokens on your server
Access tokens are signed with HS256 using the project's JWT secret. Copy it from the dashboard (project → Settings → API keys) to verify tokens on your own servers, or call auth.getUser(token) to let StitchDB check it:
JavaScript
import { jwtVerify } from 'jose'
const { payload } = await jwtVerify(token, new TextEncoder().encode(process.env.STITCHDB_JWT_SECRET))