Skip to main content
Multi-tenancy is among the harder problems in SaaS. You have to isolate data so one customer never sees another’s, handle authentication across organizational boundaries, manage two levels of admin, scope every query to the current tenant, and keep buggy code from crossing those lines. Feather provides all of it. Choose multi-tenant when you run feather new.

How it works

Tenants are identified by email domain. When a user signs in as bob@acme.com:
1

Extract the domain

Feather reads acme.com from the email.
2

Match a tenant

It looks up the tenant registered to that domain.
3

Assign the user

The user is attached to that tenant.
4

Scope every query

All later queries are scoped to it.

Public email domains

Gmail, Outlook, Yahoo and other consumer providers are blocked by default, so users sign in with a work address. For apps serving both businesses and individuals:
.env
Users with public addresses are then created with tenant_id=None. Use the post-login callback to create their account and tenant.

The two-axis authority model

Feather separates tenant authority, what you can do inside your organization, from platform authority, operator power across organizations.
Tenant admins do not bypass tenant isolation. An admin at Acme Corp cannot reach data belonging to Beta Inc. That requires platform admin rights.

Tenant admin

Approves and suspends users in their tenant, changes roles within it, and reads error logs scoped to it. Cannot see other tenants.

Platform admin

Creates tenants and assigns domains, approves and suspends them, and views all users and platform-wide analytics. Granted only through the CLI, never the web UI.
Granting platform admin

Admin pages in multi-tenant mode

Data isolation at three layers

get_current_tenant_id() returns the authenticated user’s tenant.
require_same_tenant() is a hard stop that tenant admins cannot bypass. Cross-tenant operations belong on platform admin routes with an explicit @platform_admin_required decorator.
feather check reports a query on a tenant-scoped model with no tenant filter as the tenant-isolation error, so a missing filter fails CI instead of leaking data.

The Tenant model

The scaffolded model covers both domain-based and individual tenants.
  • Business tenants. Set domain to assign users by email automatically.
  • Individual tenants. Leave domain as None and create them in the post-login callback.
  • type. Classify tenants for billing, features or reporting.

Tenant lifecycle

1

Platform admin creates the tenant

Through /admin/tenants. Sets name, slug and optionally an email domain, and creates the first tenant admin, auto-approved. The tenant starts pending.
2

Platform admin approves the tenant

It becomes active.
3

Users sign up with a matching email domain

They are assigned to the tenant and created suspended.
4

Tenant admin approves the users

Through /admin/users.
The result is an approval gate at both the platform and the tenant level.