← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Role-Based Access Control (RBAC)

Security Intermediate
debt(d7/e7/b7/t5)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). Missing authorisation checks on routes/controllers are rarely caught by static tools; SAST may flag some patterns but most gaps surface only via code review or penetration testing. No detection_hints provided, so citing category-appropriate review/testing practices.

e7 Effort Remediation debt — work required to fix once spotted

Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix names spatie/laravel-permission or Symfony Voters, but adopting these means replacing ad-hoc is_admin checks scattered across routes, controllers, middleware, and views — a cross-cutting change, not a one-line patch.

b7 Burden Structural debt — long-term weight of choosing wrong

Closest to 'strong gravitational pull' (b7). Authorisation is load-bearing: every route, controller, and API endpoint consults the RBAC layer. The role/permission model shapes how features are built, and changing the model (e.g. moving to ABAC) ripples everywhere.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap (a documented gotcha)' (t5). The misconception conflates authentication with authorisation — a common confusion that most developers eventually learn, but which causes real bugs (assuming logged-in means authorised). Other gotchas like checking roles in views compound this.

About DEBT scoring →

Also Known As

role-based access control roles permissions authorisation RBAC authz

TL;DR

An authorisation model where permissions are assigned to roles, and roles are assigned to users — checking 'can this role perform this action?' rather than 'can this specific user?'

Explanation

RBAC assigns permissions to named roles (admin, editor, viewer, moderator) and assigns one or more roles to each user. When a user attempts an action, the system checks whether any of the user's roles includes the required permission. This is more maintainable than direct user-permission assignment (ACL) because changing what a role can do updates all users with that role simultaneously. Implementation patterns: flat RBAC (roles have permissions, users have roles); hierarchical RBAC (admin inherits all editor permissions); constrained RBAC (separation of duty — no user can have conflicting roles like 'requester' and 'approver'). In PHP, RBAC is implemented directly in framework Gate/Policy systems (Laravel Gates, Symfony Voters) or via libraries (spatie/laravel-permission for Laravel). The alternative to RBAC is Attribute-Based Access Control (ABAC) which evaluates policies based on attributes of the user, resource, and environment — more flexible but more complex.

Common Misconception

RBAC and authentication are the same thing. Authentication verifies identity ('who are you?'); authorisation determines permissions ('what can you do?'). RBAC is an authorisation model — it answers the second question. A user can be fully authenticated but have no permissions to perform a specific action. The two systems are separate: authenticate first (validate credentials, establish session), then authorise each action (check roles/permissions).

Why It Matters

Without a clear authorisation model, PHP applications grow a collection of ad-hoc permission checks scattered throughout the codebase — if ($user->is_admin) here, if ($user->type === 'editor') there. When requirements change (editors should now be able to publish; admins should no longer delete users), every ad-hoc check must be found and updated. RBAC centralises permission definition: change what the 'editor' role can do in one place, and every route, controller, and API endpoint that checks that role automatically reflects the change.

Common Mistakes

  • Checking roles in views instead of controllers or middleware — business rules belong in the access control layer, not templates.
  • Using string comparison for role checks without normalising case — 'Admin' !== 'admin'; use constants or enums for role names.
  • Not checking authorisation on every route — a missing auth check on one endpoint is a privilege escalation vulnerability.
  • Over-engineering with ABAC when RBAC is sufficient — start with roles and permissions; only add attribute-based policies when RBAC cannot express the required rules.

Code Examples

✗ Vulnerable
// Ad-hoc checks scattered everywhere — unmaintainable
class PostController {
    public function publish(Post $post) {
        if ($user->type !== 'admin' && $user->type !== 'editor') {
            abort(403);
        }
        // What if 'moderator' should also publish?
        // Must find every check and update it
    }
    public function delete(Post $post) {
        if ($user->type !== 'admin') abort(403); // different check!
    }
}
✓ Fixed
// Centralised RBAC — change roles once, applies everywhere
// Migration: roles table, permissions table, role_user pivot

// Define permissions once
// Role 'editor' => ['publish-posts', 'edit-posts']
// Role 'admin'  => ['publish-posts', 'edit-posts', 'delete-posts']

class PostController {
    public function publish(Post $post) {
        $this->authorize('publish-posts'); // checks user's roles
        // Adding 'moderator' role with 'publish-posts' permission
        // is a database change — no code changes needed
    }
    public function delete(Post $post) {
        $this->authorize('delete-posts');
    }
}

Added 23 Mar 2026
Views 53
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 1 ping F 1 ping S 0 pings S 1 ping M 1 ping T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 9 Perplexity 7 Google 5 Ahrefs 4 SEMrush 4 ChatGPT 3 Scrapy 3 Claude 2 Bing 2 Meta AI 1 PetalBot 1
crawler 37 crawler_json 4
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Medium
⚡ Quick Fix
Use spatie/laravel-permission for Laravel or Symfony Voters for Symfony — both provide RBAC with database-backed roles and permissions out of the box


✓ schema.org compliant