SOFTWARE / SYSTEMS / AIEngineering news. Technical depth.
Authorization / 3 MIN READ

Escape role explosion in B2B SaaS authorization

Keep roles small and stable, move exceptions into permissions and scoped relationships, and plan migration, testing, and admin UX before custom roles.

Role explosion starts when a stable job label becomes a container for every customer exception. Keep roles for broad responsibility, express product actions as named permissions, and use resource relationships or attributes for scope. Customer-defined roles can come later, once the permission vocabulary and administrative experience are ready.

Preserve the useful core

An owner-admin-member model is valuable because people understand it. Owner can control billing and tenancy; admin can manage people and settings; member can do ordinary work. NIST’s archived RBAC page summarizes the classic model and its administrative advantage: users are assigned roles, roles are assigned privileges, and access management maps closely to organizational structure.

Problems begin with requests such as “member who may export,” “admin except billing,” or “project admin only for Phoenix.” Creating roles named Exporting Member, Restricted Admin, and Phoenix Admin encodes combinations instead of meaning. Ten binary exceptions already imply up to 1,024 combinations. The UI, documentation, tests, and support burden grow with them.

First separate role from permission. Roles become curated permission bundles. The application checks “invoice.export,” not “role is admin or finance-admin or reporting-admin.” A new standard bundle can reuse existing permissions without adding role checks throughout the code.

Classify each exception

Ask what varies in the customer request:

  • An action varies: add or remove a permission from a bundle.
  • A resource scope varies: represent a relationship such as editor of project Phoenix.
  • A subject or environment property varies: use an attribute, such as department or managed-device state, only when its source and refresh semantics are trustworthy.
  • The customer wants its own job labels: offer customer-defined roles that bundle a fixed product permission catalog.
  • A rule combines several facts: use policy logic with explicit inputs and tests.

The OWASP Authorization Cheat Sheet recommends enumerating users, resources, and operations during design, considering relevant attributes in access decisions, and creating tests that validate permissions are correctly enforced. In practice, teams often combine RBAC with relationship- or attribute-based checks for finer-grained scope rather than forcing every exception into another role.

Ory Keto is a strong fit when resource relationships and inherited permissions are the central problem. The Ory Keto documentation describes it as a fine-grained permission system based on Zanzibar design principles, with relationship-based models and permission inheritance. Evaluate the managed Ory Network service separately from operating the open-source project yourself.

Migrate checks before assignments

Inventory every role comparison and map it to an action on a resource. Introduce a single authorization interface, then translate existing roles into permissions behind it. For a time, compute both legacy and new decisions, enforce the legacy result, and retain every difference.

Backfill resource relationships from current ownership and membership data. Do not infer ambiguous scope. Put uncertain records into a remediation queue and keep the old decision for them. Roll out by tenant, starting with internal accounts, and retain a fast switch back to legacy evaluation.

Test for privilege expansion. Each role needs allow and deny cases, including cross-tenant identifiers, moved resources, removed group membership, and default behavior when context is missing.

Budget for the product surface

Custom roles are a product, not a database table. Administrators need permission descriptions, safe defaults, dependency warnings, a preview of affected users, audit history, and protection against removing their own final recovery path. Support needs a way to explain why access was granted. APIs need stable permission identifiers even when labels change.

Before adding another role, write the request as subject, action, resource, and conditions. If two proposed roles differ by one action or one resource boundary, keep one role and model that difference directly. Start this week by replacing the five most repeated role-name checks with named permission checks behind one shared interface.

SOURCES & REVIEW

Sources are linked throughout this guide. Product capabilities can change; consult the linked documentation for your deployment.

Read our editorial approach ↗