Authentication uses Laravel Sanctum in stateful (cookie) mode. The portal and the API share a session, so the browser never handles a bearer token and there is no token to leak from local storage.
Roles
| Role | Scope |
|---|---|
| super_admin | Platform owner. Tenants, plans, licensing, platform settings. |
| tenant_owner | Owns a workspace. Full administration within it. |
| tenant_admin | Full workspace administration, without ownership. |
| billing_manager | Invoices, payments and the ledger. |
| support_agent | Tickets and client correspondence. |
| client_user | End customer, client portal only. |
Permissions
Roles carry named permissions such as dashboard.view or clients.manage, and endpoints check the permission rather than the role. Adding a role therefore does not require touching controllers.
Multi-factor authentication
- TOTP with an authenticator app, plus one-time recovery codes.
- Passkeys (WebAuthn) as either a second factor or a passwordless sign-in.
- Per-workspace policy: MFA can be disabled, optional or required, separately for owners/admins, staff and clients.
Session isolation
Sessions carry the tenant they were established for. If a session's tenant no longer matches the user's, it is invalidated rather than silently re-scoped.