Most B2B SaaS is multi-tenant: each customer (a tenant) gets their own workspace, users, and permissions. Authaz handles the isolation — you don't write the filters.
application
├── tenant A → users pool A
├── tenant B → users pool B
└── tenant C → users pool C
Each tenant gets its own pool. No cross-tenant identity at all — same email in two tenants = two separate users.
For healthcare, finance, government, anything where tenants must not see the existence of each other's identities.
The user-pool model is one decision. Which features each tenant can customize on its own — branding, email templates, email provider, the auth stack — is a separate set of switches. See Tenancy Customization.
GET /v1/applications/{appId}/tenants/{tenantId}/users
Send invitation
POST /v1/invitations
POST /v1/applications/{appId}/tenants/{tenantId}/invitations
Assign a role
POST /v1/role-assignments
POST /v1/applications/{appId}/tenants/{tenantId}/role-assignments
Provider config
PUT /v1/applications/{appId}/auth/...
PUT /v1/applications/{appId}/tenants/{tenantId}/auth/...
You'll never see ?tenantId=... in a URL. The path is the contract.
Tenant scope can also come from the caller: a Bearer token with a tenant_id claim auto-scopes the call, even on the application-scoped path. That's what powers your end-customers' self-service admin pages — same endpoints, narrower view.