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

Role-Based Access Control (RBAC)

security Intermediate

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 32
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 1 ping M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 2 pings S 0 pings M 0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S
No pings yet today
No pings yesterday
Amazonbot 8 Perplexity 7 Google 3 Ahrefs 2 SEMrush 2 ChatGPT 1
crawler 22 crawler_json 1
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