Skip to main content
This legacy approach uses trusted_metadata on the User object to store role information and enforce authorization in your application. For new integrations, use native RBAC policies instead.
This guide is provided for backward compatibility. Native RBAC provides a dedicated policy model, Dashboard management, and SDK support.
1

Define your roles and permissions

Decide on the roles your application needs (for example admin, editor, viewer) and what actions each role should allow.
2

Store roles in trusted metadata

Use trusted_metadata to store roles when creating or updating a User. Only your backend can write trusted metadata.
curl --request POST \
  --url https://test.stytch.com/v1/users \
  -u 'PROJECT_ID:SECRET' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "user@example.com",
    "trusted_metadata": {
      "roles": ["admin"]
    }
  }'
3

Read roles during authentication

After authenticating a session, fetch the User and read roles from trusted_metadata.
const stytch = require('stytch');

const client = new stytch.Client({
  project_id: 'PROJECT_ID',
  secret: 'SECRET',
});

const sessionResp = await client.sessions.authenticate({
  session_token: 'SESSION_TOKEN',
});

const userResp = await client.users.get({
  user_id: sessionResp.user_id,
});

const roles = userResp.trusted_metadata?.roles || [];
4

Enforce authorization in your backend

Use the roles stored in trusted_metadata to decide whether to honor requests.
if (!roles.includes('admin')) {
  return res.status(403).send('unauthorized');
}

What’s next