Auth Flow
How authentication works in NNO — per-platform auth Workers, session cookies, and service-to-service tokens.
Auth Flow
NNO uses Better Auth as its authentication framework. The design prioritises complete isolation between platforms: every platform gets its own dedicated auth Worker and its own D1 database. There are no shared user tables.
Per-platform auth Workers
When NNO onboards your platform, it deploys a dedicated auth Worker scoped exclusively to your platform:
Platform k3m9p2xw7q
└── Auth Worker: auth.svc.default.k3m9p2xw7q.nno.app
└── D1: k3m9p2xw7q-default-auth-db
├── users, sessions, accounts
├── organizations (= tenants)
├── members, invitations
└── roles, permission grantsThis means your users' credentials and sessions are never co-mingled with another platform's data, even though both platforms run on shared Cloudflare infrastructure.
Login and session flow
- The user submits credentials to
https://auth.svc.default.{platformId}.nno.app/api/auth/sign-in - Better Auth validates credentials against the platform's D1 database
- On success, a session cookie is set with domain
.<platformId>.nno.app - The console shell reads the session on every page load via
VITE_AUTH_API_URL - The active tenant (
session.activeOrganizationId) is included in the session and drives theShellContext.tenant
Cross-stack session sharing
Because the cookie domain is .<platformId>.nno.app, a single login covers every stack and app on that platform. A user who logs into:
dashboard.app.default.k3m9p2xw7q.nno.appis automatically authenticated when they navigate to:
crm.app.x7y8z9w0q1.k3m9p2xw7q.nno.appNo re-login is needed across stacks.
Role model
NNO has two role scopes:
Platform-level (on the user record):
| Role | Access |
|---|---|
platform-admin | Full access: all tenants, platform settings, billing |
user | Standard access governed by tenant roles |
Tenant-level (on the membership record):
| Role | Access |
|---|---|
owner | Full tenant control — invite, remove, change roles |
admin | Manage members, cannot delete tenant or change billing |
member | Standard access — feature permissions apply |
A user can hold different roles in different tenants simultaneously.
Service-to-service auth
NNO internal services authenticate to each other using short-lived JWTs issued by the IAM service (/api/nno/service-token). These tokens use HMAC-based validation and are cached by the Gateway's ServiceTokenCache to reduce latency on every proxied request.
Platform admins and features interact with NNO services using API keys issued by the IAM service (/api/nno/apikey). API keys are scoped to a platform ID and carry no user identity.
Auth template
The per-platform auth Worker is deployed from a template (services/auth) during platform onboarding. The CLI Service substitutes platform-specific values (platform ID, D1 IDs, auth secret) into the template and deploys it to the platform's GitHub repository. You can customise the auth configuration after initial provisioning.
For the full technical specification, see Internal → Auth Service.