Multi-Tenant SaaS Authorization
Multi-tenant SaaS is one of OpenFGA's most common production shapes. The same binary serves every tenant; tenant boundaries are enforced inside the authorization model rather than at the database or service layer.
The pattern
Model an organization (or tenant) type and make every other resource belong to it:
organizationhas members, admins, and owners.workspace,project, anddocumenttypes each declare aparentrelation pointing at anorganization.- Relations like
can_viewandcan_edittraverse the parent edge so organization membership grants the right access automatically.
This gives you:
- Hard tenant isolation by default. A user only has tuples for the organizations they belong to, so list-objects naturally returns nothing cross-tenant.
- Cross-tenant sharing when you want it. A document can also have individually granted users from other organizations — same model, no special case.
- A single store for all tenants. Operationally cheaper than per-tenant databases; the tuple count grows linearly with usage rather than fan-out.
Per-tenant custom roles
Most SaaS products eventually need tenant-defined roles — "Acme wants a billing-manager role; Globex wants a compliance-reviewer role" — without redeploying the model. The pattern is to make role a first-class type whose assignee relation can be a user, another role, or a group, and then bind those roles to organization-level permissions:
type user
type group
relations
define member: [user, group#member]
type role
relations
define assignee: [user, role#assignee, group#member]
type organization
relations
define admin: [user, role#assignee]
define billing_manager: [role#assignee] or admin
define document_manager: [role#assignee] or admin
define can_invite_user: admin
define can_edit_billing: billing_manager
define can_create_document: document_manager
type document
relations
define organization: [organization]
define editor: document_manager from organization
define viewer: document_manager from organization
define can_view: viewer or editor
define can_edit: editor
Each tenant creates its own role:acme-billing-manager, role:acme-document-management, etc., and binds them to the predefined organization-level relations (billing_manager, document_manager, admin). Users or groups become assignees of those roles, and document-level permissions inherit through the organization. The model itself stays static; tenants get full flexibility on which roles exist and who is in them.
The full working example — including tuples, group nesting (group:acme-data-engineering#member ∈ group:engineering#member), and list_users assertions — is in the multitenant-rbac sample store. You can run it locally with the FGA CLI to see the checks pass.