The mandate was clear: implement “role-based access control” (RBAC). The promised benefits were compelling—reduced administrative overhead, improved security, easier compliance, scalability as the company grows. Six months later, there are 147 roles. Nobody understands what half of them do. Users are in 8 roles at once. Administrative overhead is worse than before. This is RBAC gone wrong—where the theory is beautiful and the reality is a tangled mess.Documentation Index
Fetch the complete documentation index at: https://docs.provisionr.io/llms.txt
Use this file to discover all available pages before exploring further.
The RBAC Fantasy
Here’s how RBAC is supposed to work: Step 1: Define roles based on job functions- “Sales Engineer”
- “Marketing Manager”
- “Senior Developer”
- Sales Engineer gets: Salesforce, CRM tools, customer data
- Marketing Manager gets: Campaign tools, analytics, content management
- Senior Developer gets: Code repos, production access, deployment tools
- New Sales Engineer joins? Add them to the Sales Engineer role. They get all the right access automatically.
Why RBAC Explodes in Complexity
People don't fit into single roles
Sarah is a Sales Engineer (needs sales + engineering access), on the Enterprise team (needs enterprise customer access), leading the partner integration project (needs partner portal access), and in the San Francisco office (needs building access, regional Slack channels). Is she one role? Four roles? How many role combinations exist across the organization?
Permissions aren't role-specific
Some permissions are based on role. Others are based on department (everyone in Finance gets finance tools), location (everyone in EU gets EU compliance training), employment type (FTEs get benefits portal, contractors don’t), project (anyone on Project Phoenix gets phoenix-team Slack channel), or seniority (Senior Engineers get production access, Junior Engineers don’t). Shoving all of this into “roles” creates role explosion.
Exception handling breaks the model
Sarah is a Sales Engineer but also needs temporary access to the finance-reports group for commission calculation transparency. Option A: Create a new role called “Sales Engineer with Finance Reports”? Now there’s Sales Engineer, Sales Engineer with Finance Reports, Sales Engineer with Finance Reports and Partner Portal, and so on. Option B: Give her two roles: “Sales Engineer” + “Finance Reports Access”? Now she’s accumulating roles. After 3 years, she has 12 roles and nobody knows which ones are still relevant. Option C: Manually grant her access outside the role system? Now the purpose of RBAC is defeated. Half of access is role-based, half is ad-hoc.
Role changes are messy
Sarah gets promoted from Sales Engineer to Sales Manager. In traditional RBAC: remove her from “Sales Engineer” role (this revokes all access), then add her to “Sales Manager” role (this grants new access). But some Sales Engineer access should persist (she’s still in sales). Some should be removed (she’s no longer hands-on with customers). Some should be modified (read-only instead of full access). RBAC doesn’t handle this gracefully. The result is complex role hierarchies or manual cleanup.
The 147 Roles Problem
Here’s how organizations get 147 roles: Year 1: Start with 10 roles (Engineer, Sales, Marketing, Finance, etc.). Life is good. Year 2: Add department subdivisions. Engineer becomes Senior Engineer, Junior Engineer, Engineering Manager. Sales becomes Sales Engineer, Account Executive, Sales Manager, VP of Sales. Marketing becomes Marketing Manager, Content Manager, Demand Gen Manager. Now there are 30 roles. Year 3: Add cross-functional roles. Need “Engineering + Finance” for FinOps team. Need “Sales + Engineering” for Solutions Architects. Need “Marketing + Product” for Product Marketing. Now there are 55 roles. Year 4: Add special cases. “Sales Engineer - Enterprise” (different from standard Sales Engineer). “Senior Developer with PCI Access” (compliance requirement). “Marketing Manager - EMEA” (regional variation). Now there are 90 roles. Year 5: Give up trying to define atomic roles. Let teams create their own. “Phoenix Project Team.” “Q4 Launch Access.” “Temp Summer Interns with Extended Access.” Now there are 147 roles. Nobody knows what most of them do. Users are in 8-12 roles simultaneously. Auditors ask “what does the ‘Phoenix Project Team’ role grant access to?” and the answer is unknown.What RBAC Gets Right (And Where It Fails)
RBAC is correct about: access being based on job function rather than individual requests, permissions being grouped logically, and adding users to pre-defined groups being more scalable than one-off grants. RBAC is wrong about: “roles” being the only dimension that matters, one user equaling one role (or even a small number of roles), and all access fitting into neat role boundaries. The problem isn’t the concept. It’s the implementation model.What Actually Works: Attribute-Based Access Control (ABAC)
Companies that have successfully implemented scalable access control use attributes, not just roles. Attributes are facts about a user:job_title: "Sales Engineer"department: "Sales"team: "Enterprise"location: "San Francisco"employment_type: "FTE"seniority: "Senior"manager: "sarah@company.com"
Attributes are stable
department, title, location change infrequently. When they do change, access automatically adjusts.Combinations express complexity naturally
“Senior Sales Engineer in Enterprise team” is three attributes. Not a new role.
Exceptions are explicit
“Sarah needs finance-reports access” is a separate policy with justification and expiration. Not a role modification.
Changes are granular
When Sarah gets promoted, attributes update:
job_title: "Sales Engineer" becomes job_title: "Sales Manager", and seniority: "Senior" becomes seniority: "Manager". Policies re-evaluate. Some access persists (based on department = "Sales"). Some access changes (based on seniority = "Manager"). Some access is removed (based on job_title != "Sales Engineer").Implementing Attribute-Based Policies
Step 1: Identify stable attributes in the HRIS Map what the HRIS actually tracks:| Attribute | Example Value | Stability |
|---|---|---|
job_title | ”Sales Engineer” | Medium (changes with promotions) |
department | ”Sales” | High |
team | ”Enterprise Sales” | Medium (reorgs happen) |
location | ”San Francisco” | High |
employment_type | ”FTE” | Very high |
manager | ”sarah@company.com” | Medium (org changes) |
cost_center | ”R&D-West” | Medium |
- Re-evaluates all policies against her new attributes
- Calculates what should be added, removed, or kept
- Applies changes with graceful deprecation (some access persists for 30 days)
- Logs the entire transition
Rulesets vs. ABAC: When to Use Each
Use traditional Rulesets when:- The organization has fewer than 50 employees
- Job functions are simple and distinct
- Cross-functional work is minimal
- Role changes are infrequent
- Compliance requirements are straightforward
- The organization has more than 50 employees
- Job functions overlap (Sales Engineering, Solutions Architecture, etc.)
- Cross-functional projects are frequent
- Role changes are common (promotions, transfers, reorgs)
- Audit trails showing why access was granted are required
- “Sales Engineer” isn’t a role in the system. It’s a set of attributes (
department = Sales,job_family = Engineering). - Policies grant access based on those attributes, not the “role” label.
- When people talk about “the Sales Engineer role,” they’re referring to the policy that applies to users with those attributes.
What This Means for 147 Roles
Organizations stuck with 147 roles can refactor: Step 1: Audit what each role actually grants. For each role, document what systems it gives access to and what permissions. Step 2: Group roles by attribute patterns. Most roles cluster into patterns: department-based (Sales, Engineering, Marketing), seniority-based (Junior, Senior, Manager), location-based (US, EU, APAC), and project-based (temporary access for specific initiatives). Step 3: Convert to attribute-based policies. Instead of “Senior Sales Engineer - Enterprise” role, create:Common Objections
“But RBAC is simpler!” RBAC is conceptually simpler. Implementation is not. Managing 147 roles is not simple. Deciding which role someone needs is not simple. Handling role transitions is not simple. ABAC is slightly more complex to set up (attribute management is required). But it scales better. “Our compliance framework requires RBAC!” Compliance frameworks require that access be based on job function and be auditable. They don’t specifically require “roles” as a technical implementation. ABAC satisfies the same compliance requirements. ABAC policies can even be presented as “roles” for auditor consumption. “What if our HRIS attributes are wrong?” Then RBAC role assignments are also wrong. The problem isn’t ABAC. The problem is data quality. ABAC actually makes data quality issues more visible because it explicitly depends on attributes. RBAC hides the problem by using manual role assignments that drift from reality.The Bottom Line
RBAC promises scalability through roles. But roles don’t scale. They proliferate. The insight is that “role” is just shorthand for “a collection of attributes that correlate with job function.” Model the attributes directly, and the result is:- Fewer objects to manage (10 attributes vs. 147 roles)
- Clearer policies (explicit about what matters)
- Better handling of complexity (cross-functional, exceptions)
- Easier role transitions (attributes change, policies re-evaluate)
Next up: How to orchestrate access across multiple systems when each has its own permission model. Cloud providers, SaaS tools, and on-prem systems all think about access differently—here’s how to unify them.
Want to see attribute-based policies in action? Check out Provisionr’s policy engine →