Users & Roles
Users & Roles
Section titled “Users & Roles”Users represent identities in Seamless Auth and carry the global role data your application uses for authorization.
Organizations add membership roles and scopes for tenant-style access, but they do not replace the global user record.
Mental Model
Section titled “Mental Model”User -> global roles -> credentials -> sessions -> organization membershipsImportant User Fields
Section titled “Important User Fields”| Field | Description |
|---|---|
id | Unique user ID |
email | Unique email |
phone | Unique phone |
roles | Array of global roles |
revoked | Whether authentication is disabled |
emailVerified | Email verification status |
phoneVerified | Phone verification status |
verified | Fully verified status |
challenge | In-progress auth challenge |
challengeContext | Context for the in-progress auth challenge |
lastLogin | Last successful login |
Related records hold passkeys, OAuth identities, TOTP credentials, sessions, organization memberships, and auth events.
Global Roles
Section titled “Global Roles”Global roles are stored directly on the user record.
Example:
["user", "admin:read"]That makes role checks explicit in both frontend and backend code.
System config shapes role behavior through:
default_rolesavailable_roles
Those values control which roles new users receive by default and which roles are allowed in the system.
Scoped Admin Roles
Section titled “Scoped Admin Roles”Admin access now supports scoped roles.
| Granted role | Satisfies |
|---|---|
admin | admin, admin:read, admin:write |
admin:write | admin:write, admin:read |
admin:read | admin:read only |
The legacy admin role remains broad for backwards compatibility. Use admin:read and
admin:write for new admin-facing route checks when you want clearer least-privilege behavior.
Application Authorization
Section titled “Application Authorization”Seamless Auth gives you identity, global roles, session context, and membership data. Your application still decides how to enforce access.
That can look like:
- UI checks with
hasScopedRole('admin:read') - backend middleware such as
requireRole('admin:write') - product-specific role combinations in your own application code
- organization membership checks for tenant-specific actions
Example:
const { hasScopedRole } = useAuth()
if (hasScopedRole('admin:read')) { return <AdminLink />}On the backend:
app.post('/settings', requireAuth({ cookieSecret }), requireRole('admin:write'), updateSettings)Organization Memberships
Section titled “Organization Memberships”Organization membership records connect users to organizations.
Each membership has:
organizationIduserIdrolesscopes
Use global roles for system-wide permissions. Use membership roles and scopes when the decision is specific to one organization.
Verification State
Section titled “Verification State”Users move through a verification lifecycle:
Unverified -> Email verified -> Phone verified -> Fully verifiedThe exact path depends on the auth flow your app enables.
Credentials And MFA
Section titled “Credentials And MFA”A user can have:
- WebAuthn credentials/passkeys
- OAuth identities
- TOTP credentials
Passkeys are stored in credentials. OAuth links are stored in oauth_identities. TOTP enrollment
state is stored in totp_credentials with encrypted secrets.
Revoked Users
Section titled “Revoked Users”If a user is revoked:
- they should no longer be able to authenticate
- existing sessions should be treated as invalidated
Revocation distinguishes an identity record that still exists from one that is still allowed to participate in auth flows.
Admin Users
Section titled “Admin Users”Admins are normal users with admin, admin:read, or admin:write roles.
That simplicity matters because it keeps authorization explicit across:
- admin dashboard access
- backend route protection
- operator actions