Skip to main content

Identity and tenancy

Overview​

Tenant boundary, users, memberships, platform roles, tenant roles, permissions, settings, subscriptions, legal entities, tax registrations, and document sequences.

Responsibilities​

  • Authenticate users and issue access and refresh tokens. Controllers for that live in src/common/auth.
  • Bind a user to tenants through Membership.
  • Resolve permission strings for PermissionsGuard.
  • Keep tenant settings and subscription flags that the sync scheduler reads.

Architecture​

JWT carries tenantId. JwtAccessGuard rejects the token if that tenant no longer exists. Prisma then applies the tenancy extension. See Tenancy and Authentication.

Code map​

PiecePath
Featuressrc/modules/identity (tenant, user, user-setting, tenant-setting, tenant-role, role-permission)
Authsrc/common/auth
Schema10-tenant.prisma, 11-identity.prisma

Data model​

Tenant, TenantSetting, TenantSubscription, LegalEntity, TaxRegistration, DocumentSequence, User, Membership, TenantRole, TenantRolePermission, MembershipRole, Permission, PlatformRolePermission, UserSetting, Device.

Permission and PlatformRolePermission are global. They are not filtered by tenant.

Business rules​

  • Non-public routes require an access JWT, except @PublicRoute and the metrics bypass.
  • Sync scheduling requires tenant.isActive and subscription.isActive.
  • Unknown: whether an inactive subscription blocks HTTP, and what SubscriptionTier means commercially.

API surface​

Tenant, user, role, and auth routes. OpenAPI is the field list. Invite email uses email_queue job tenant-invite-email.

Events and queues​

No outbox types were found for identity. Email jobs are Bull.

Failure scenarios​

Stale tenant on the JWT returns auth.error.staleSession. Forgot-password does not reveal whether the email exists.

Development​

New tenant-owned tables must be classified in the tenancy extension. New routes that should not be world-to-authenticated need @RequirePermissions.

Troubleshooting​

Authentication failures.