Skip to main content
๐Ÿ›ก๏ธ Verified Technical Content: Written by Serhii Hrekov. | Last reviewed & updated in Git: July 21, 2026

Casbin RBAC Guide: Standard vs. Hierarchical Roles, Maintenance, and Configuration

ยท 9 min read
Serhii Hrekov
Senior Software Engineer & System Architect specializing in Python, Web Systems, Cloud Infrastructure & Automation

A common misconception about using Casbin Hierarchical RBAC is that the entire policy storage must be updated every time a user performs an action or changes state. This is incorrect. The system is designed to separate the static, structural hierarchy (which rarely changes) from the dynamic user assignments (which change frequently).

The efficiency of Hierarchical RBAC lies in this separation, minimizing the required policy updates and reducing redundancy.


The Two Types of Relationships in Policy Storageโ€‹

Hierarchical RBAC requires two primary types of grouping rules in the policy storage (e.g., a database or CSV file), typically defined by the g and g2 rules in the policy file.

1 Static Relationships: Role Inheritance (g2 Rules)โ€‹

The g2 rules define the fixed, structural relationships between roles, establishing the inheritance chain. These are managed by application administrators and reflect the organizational structure.

  • Rule Format: g2, child_role, parent_role
  • Purpose: To define a single source of truth for cascading permissions. When a child role is defined as a successor of a parent role, the child automatically inherits all permissions granted to the parent.
  • Update Frequency: Low (Administrative). You only update these rules when the company's roles or internal structure fundamentally change (e.g., merging a department, creating a new top-level role). They are not tied to user activity.

Example: Static Inheritance

If an Admin inherits from a Manager, this rule is defined once and stays constant until a structural change.

Policy RuleAnnotation
g2, admin, managerThe admin role inherits all permissions of the manager role.
p, manager, reports, viewThe manager role can view reports.
Result: An admin can automatically view reports without a separate p, admin, reports, view rule.

2 Dynamic Relationships: User-to-Role Assignment (g Rules)โ€‹

The g rules link a specific subject (user) to a starting role in the hierarchy. This link represents the user's current status and is the only element that changes frequently based on user lifecycle events.

  • Rule Format: g, subject, role
  • Purpose: To assign a user to the starting point of their effective permissions chain.
  • Update Frequency: High (Dynamic/User Lifecycle). These rules are updated when a new user is onboarded, promoted, transferred, or deleted. This is typically managed via Casbin's API methods (e.g., enforcer.addGroupingPolicy or enforcer.deleteGroupingPolicy).

Example: Dynamic User Assignment

When a new user, Alice, is hired as an Admin, only the g rule is updated.

Casbin API CallPolicy Rule AddedAnnotation
enforcer.addGroupingPolicy("alice", "admin")g, alice, adminA single entry is created linking Alice to the admin role.
Maintenance Benefit: If the admin role inherits permissions from 5 parent roles, you still only make one policy update (g rule) instead of updating 5 separate permission groups for Alice.

Why Hierarchical RBAC is Efficientโ€‹

The entire system relies on Casbin's Role Manager to handle the recursive lookup [2].

  1. Request: User Alice asks to access /reports.
  2. Lookup 1 (Dynamic): Casbin checks the g rules and finds that Alice is assigned to the admin role.
  3. Lookup 2 (Static): Casbin checks the g2 rules and discovers that admin inherits from manager, and manager inherits from executive.
  4. Enforcement: Casbin checks permissions for admin, manager, and executive against the /reports resource.

Because the g2 hierarchy is loaded and cached by the Role Manager upon initialization, authorization checks are fast, and the policy storage remains tidy. You only modify the storage when a user's role changes, or the organization's structure changes.


Standard RBAC vs. Hierarchical RBAC: When to Choose Eachโ€‹

The choice between standard Casbin RBAC and Hierarchical RBAC depends on the complexity of your application's user structure and the need for role inheritance.

Casbin Standard RBAC (Model: g only)โ€‹

Standard RBAC assigns permissions to roles, and then assigns users to those roles. The core is the grouping policy (g), which maps a subject (user) to a role.

When to Choose Standard RBAC:

  • Flat Organizations: Small to medium-sized applications where roles (e.g., Admin, Editor, Viewer) have distinct, non-overlapping permission sets.
  • Simple Auditing: When you need a direct, explicit list of every permission assigned to a user without having to trace an inheritance chain.
  • Performance: For very high-traffic applications, avoiding a deep recursive lookup for role inheritance can slightly speed up authorization checks.

Example Model (rbac_model.conf):

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_manager]
rm = rbac_api

[policy_effect]
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))

[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act

Example Policy (rbac_policy.csv):

p, editor, articles, read
p, editor, articles, edit
g, alice, editor
g, bob, viewer

Casbin Hierarchical RBAC (Model: g and g2)โ€‹

Hierarchical RBAC introduces g2 that maps roles to other roles. A child role automatically inherits all permissions granted to its parent.

When to Choose Hierarchical RBAC:

  • Inheritance is Key: Define permissions once at a high-level role and let lower-level roles inherit them.
  • Reduced Policy Management: Eliminates redundant permission lines across similar roles.
  • Simulating Organizational Charts: Maps well to traditional org structures.

Example Model (rbac_hierarchy_model.conf):

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_manager]
rm = rbac_api

[policy_effect]
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

Example Policy:

p, manager, reports, view
p, manager, audits, create
p, executive, reports, view
g, alice, director
g2, director, manager
g2, manager, executive

Decision Summaryโ€‹

FeatureStandard RBACHierarchical RBAC
Role InheritanceNo (Must explicitly assign all permissions).Yes (Child roles inherit parent permissions).
ComplexityEasier to trace and debug.Reduces policy file size, but more complex lookups.
Policy LinesHigher redundancy (many duplicated p lines).Lower redundancy (single g2 lines manage many permissions).
Best ForFlat applications, simple permission needs, high performance.Large enterprises, complex hierarchies, reduced maintenance.

If you find yourself constantly duplicating permission lines across different roles that logically should share permissions, switch to Hierarchical RBAC. If your structure is simple and static, Standard RBAC is sufficient.


Sources and Further Readingโ€‹

  1. Casbin Documentation - RBAC with Hierarchical Roles
  2. Casbin Documentation - Role Manager
  3. Understanding RBAC Hierarchies (NIST Special Publication on RBAC)
  4. Casbin GitHub Repository (Source Code)
  5. Role-Based Access Control (RBAC) Overview

Related articles