Enterprise Architecture: Scaling with Multi-Role RBAC and Advanced Tenancy
Karl Gusta
Instructor & Founder
The Enterprise Transition
In the early days of a SaaS, you only have "Users." But as you scale toward B2B and Enterprise customers, your permission model must evolve. Companies don't just want accounts; they want Organizations where an "Admin" can invite "Members," and a "Billing Manager" can see invoices but not source code.
In 2026, building these layers manually is a recipe for security vulnerabilities. In this guide, we are moving into advanced territory: Role-Based Access Control (RBAC) and Hierarchical Tenancy using Next.js 16 and MongoDB.
The Problem: The "Flat" Permission Model
A flat model, where every user has equal power over their data, fails in a professional setting:
- Over-privileged Users: A junior employee accidentally deleting the company's production database because they had "Admin" rights.
- Complex Logic: Writing
if (user.isAdmin)on every single button, leading to a "Spaghetti UI." - Data Leakage: Failing to properly isolate "Organization A" from "Organization B" in shared MongoDB collections.

The Shift: Attribute and Role-Based Security
In 2026, we utilize Next.js Middleware (or proxy.ts in v16) as a first-line defense, combined with JWT-augmented sessions. Instead of querying the database for roles on every click, we bake the user's role and organization ID into their encrypted session token.
Deep Dive: Implementing Advanced RBAC
1. Augmenting the Session with Roles
We update our Auth.js configuration to fetch the user's role from MongoDB and store it in the JWT. This makes the role available instantly on the server without extra database hits.
javascript// src/lib/auth.ts export const { handlers, auth } = NextAuth({ callbacks: { async jwt({ token, user }) { if (user) { token.role = user.role; // e.g., "ADMIN", "MEMBER" token.orgId = user.orgId; } return token; }, async session({ session, token }) { session.user.role = token.role; session.user.orgId = token.orgId; return session; } } });
2. Guarding the Middleware
With the role inside the token, our middleware can now perform "Edge-level" authorization. If a user tries to access /admin but doesn't have the "ADMIN" role, they are redirected before the page even begins to render.
javascript// src/middleware.ts export default auth((req) => { const role = req.auth?.user?.role; const isPendingAdmin = req.nextUrl.pathname.startsWith("/admin"); if (isPendingAdmin && role !== "ADMIN") { return Response.redirect(new URL("/dashboard", req.nextUrl)); } });
3. Database-Level Multi-Tenancy
The most secure way to handle multi-tenancy in MongoDB is the "Logical Isolation" pattern. Every document in your database must include an orgId.
The Rule: Your query must always include the organization ID from the server-side session.
javascript// Secure Query Pattern const session = await auth(); const projects = await Project.find({ orgId: session.user.orgId }).lean();
Organizations and role-based access control in Next.js
Key Benefits and Learning Outcomes
- Granular Control: You can restrict features (like "Export to CSV") to higher-paying tiers easily.
- Audit-Ready: Having clearly defined roles makes it easier to pass security audits for enterprise clients.
- Clean Code: By using a centralized permission helper, your components stay clean:
<Can do="edit_project"> <EditButton /> </Can>.
Common Mistakes
- Client-Side-Only Checks: Never assume a user is an admin just because you hid the button in CSS. Always verify the role in the Server Action or API Route.
- Hardcoding Strings: Use an enum or a constants file for roles (e.g.,
ROLES.ADMIN) to avoid typos. - Implicit Tenancy: Forgetting the
orgIdin a single query can lead to Organization A seeing Organization B's data—the #1 SaaS "Death Sentence."

Pro Tips and Best Practices
- The "Switch Organization" Feature: If your users can belong to multiple companies, implement a "Current Org" state in their session that they can toggle from the header.
- Role Inheritance: Make "Admin" inherently include all "Member" permissions so you don't have to duplicate logic.
- Permission Mapping: Instead of checking roles (
if Admin), check permissions (if can_delete_user). This allows you to change what an "Admin" can do in one place.
How This Fits Into the Zero to SaaS Journey
You are no longer building a tool; you are building a Platform. By implementing these enterprise features early, you make your SaaS attractive to larger teams with bigger budgets. This is the difference between a $19/mo prosumer tool and a $500/mo enterprise solution.
Action Plan: What to Build Next
- Update User Schema: Add
roleandorgIdfields to your MongoDB user model. - Setup Enums: Create a
/src/lib/permissions.tsfile defining your roles. - Gate the UI: Create a
<HasRole />wrapper component to show/hide features. - Enforce Tenancy: Audit your existing Server Actions to ensure every
.find()query includes anorgIdfilter.
Ready to close your first big ticket? Check out the Why You Should Use Next.js for Your SaaS (2026 Guide) for a deeper look at enterprise scaling.
Next Steps: Vertical SaaS Strategies: Finding Your Niche and Dominating a Market.
Next.js Role-Based Access Control (RBAC) & Protected Routes | Full Tutorial with MongoDB & Auth CRUD