WardenAuth
AuthorizationAgent SecurityDocsPricingCompareBlogLearn
Sign inStart free
Learning Center

Multi-Tenant Authorization

In B2B SaaS, the worst possible bug is one tenant seeing another tenant's data. This guide covers the patterns, pitfalls, and best practices for multi-tenant authorization at scale.

On this page

The isolation problemPattern 1: Scope-per-tenantPattern 2: Shared vs per-tenant rolesPattern 3: Cross-tenant support accessPattern 4: Tenant-aware API keysIsolation pitfalls (and how to avoid them)Pricing: flat-rate vs per-tenantImplementation guides

The isolation problem

Every authorization decision must be answered within a tenant boundary. "Can this user delete invoice 123?" is meaningless without "in which tenant?" The tenant must be an explicit, non-optional input to every check — never inferred from the resource alone. Inferring the scope from a resource ID or JWT claim is exactly how cross-tenant data leaks happen.

Common vulnerability

If your access check resolves the tenant ID from the invoice ID (invoiceIdToTenant(invoiceId)), a crafted request with a tenant B invoice ID in a tenant A session leaks data across tenants. Always require the tenant ID as an explicit parameter gated by the user's session, not the resource.

Pattern 1: Scope-per-tenant

Model each tenant as a scope — a hard boundary that namespaces all roles, permissions, and policies. Every permission, role, and access policy lives under exactly one scope. Subjects' access in one scope is completely independent from another.

// At tenant creation:
await createScope({ id: 'acme-corp', name: 'Acme Corp' })
await seedDefaultRoles('acme-corp') // Admin, Member, Viewer

// On every access check:
await hasAccess({
  subjectId: user.id,
  scopeId: 'acme-corp',  // explicit, never optional
  resource: 'invoice',
  action: 'delete',
})

Pattern 2: Shared vs per-tenant roles

Most SaaS products want common roles (Admin/Member/Viewer) across all tenants, but let enterprise customers define custom roles. Support both by seeding a default role set into each new scope, while allowing per-scope additions. Enterprise customers add roles inside their own scope — invisible to other tenants.

Pattern 3: Cross-tenant support access

Your support team occasionally needs into a customer's workspace. Do not give them a god-mode API key. Instead, grant time-boxed, audited, per-scope access — and log every action with the support agent's identity, the target scope, and the reason. Cross-tenant access should be the rare, loud exception.

Pattern 4: Tenant-aware API keys

Issue scoped API keys so your customers' backend services can call your API on behalf of their workspace. Keys are bound to a scope and a permission set — a key for Tenant A cannot access Tenant B's data. Rotate and audit independently.

Isolation pitfalls

PitfallConsequenceMitigation
Scope inferred from resourceCross-tenant data leakRequire scope as explicit parameter
Global admin rolesOne compromised key exposes all tenantsScope every role; time-box support access
Shared role IDs across tenantsEdits bleed between customersNamespace roles under the scope
No per-tenant auditCannot answer "who accessed my data"Log every decision with scope + subject

Pricing: flat-rate vs per-tenant

Many authorization platforms charge per tenant (Permit.io caps free tier at 20 tenants) or per connection (WorkOS charges $125/connection/month for SSO). WardenAuth has unlimited tenants on every tier — including Free. Your bill is based on the number of access checks, not the number of customers.

Implementation guides

Multi-Tenant Authorization Patterns for B2B SaaS

Deep dive into scope-per-tenant, shared roles, and support access.

Multi-Tenant RBAC in Next.js with Cognito

Step-by-step implementation guide.

WardenAuth vs Alternatives

Feature-by-feature comparison of multi-tenant authorization platforms.

Start building multi-tenant today

Unlimited scopes on every tier. No per-tenant charges. Start free — no credit card.

Get started
© 2026 WardenAuth · Built by Ezequiel Carrizo
AuthorizationAgent SecurityPricingUse casesDocsCompareBlogLearnChangelogStatusGlossarySecurityAboutContactTermsPrivacyDPA