While evaluating authorization frameworks for a banking use case, I came across Casbin, which turned out to be a strong fit. It provides a flexible way to manage permissions using RBAC models and policies — without hardcoding authorization logic.
Casbin is an open-source authorization library that cleanly separates authorization from authentication, making systems easier to scale and maintain.
After implementing basic RBAC, our next requirement was to support role hierarchy — where higher-level roles inherit permissions from lower-level roles. This is especially useful in banking systems where access flows naturally from roles like teller → manager → admin.
Problem Statement
We wanted to design an access control system where:
- Higher roles inherit permissions from lower roles
- Users automatically get permissions based on their role
- The system remains flexible and policy-driven (no code changes)
Understanding Role Inheritance in Casbin
In Casbin, role hierarchy is defined using the g function:
g, A, Bmeans role A inherits permissions from role B
This simple mapping enables hierarchical RBAC without additional complexity.
Role Hierarchy (Banking Example)
bank_super_admin
├── branch_manager
│ ├── relationship_manager
│ │ └── user_rahul
│ └── teller
│ └── user_priya
└── audit_userCasbin Model Configuration (model.conf)
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.actPolicy Configuration (policy.csv)
# Permissions
p, bank_super_admin, accounts, approve
p, branch_manager, loans, approve
p, relationship_manager, customer_data, read
p, teller, transactions, process
# Role hierarchy
g, bank_super_admin, branch_manager
g, branch_manager, relationship_manager
g, branch_manager, teller
# User-role mapping
g, user_rahul, relationship_manager
g, user_priya, teller
g, user_amit, branch_manager
g, user_sneha, bank_super_adminAccess Results
user_rahul:
accounts → false
loans → false
customer_data → true
transactions → false
user_priya:
accounts → false
loans → false
customer_data → false
transactions → true
user_amit:
accounts → false
loans → true
customer_data → true
transactions → true
user_sneha:
accounts → true
loans → true
customer_data → true
transactions → trueKey Takeaways
- Casbin supports hierarchical RBAC using simple role mappings (
g) g, A, Benables role inheritance, where A gets B's permissions- No application code changes are required — everything is policy-driven
- This approach scales well for complex systems like banking platforms
Advanced Concepts (Optional Extensions)
Once the basic hierarchy is in place, Casbin also supports more advanced patterns:
1. Multiple Role Definitions
You can define multiple role systems using g, g2, etc., for handling different dimensions like:
- User roles
- Resource roles
2. Domain-Based RBAC (Multi-Tenant)
For systems with multiple tenants (e.g., multiple bank branches), Casbin supports domain-based RBAC:
g, user_rahul, branch_manager, mumbai_branchThis ensures role inheritance is restricted within a specific domain.
3. Separation of Duties (Constraints)
You can enforce constraints to prevent conflicting roles, such as:
- A user cannot be both auditor and transaction processor
This is useful for compliance-heavy systems like banking.
Final Thoughts
Role hierarchy is a common requirement in enterprise systems, especially in domains like banking where structured access control is critical.
With Casbin, implementing this becomes straightforward and maintainable. Instead of duplicating permissions across roles, you can define a clear hierarchy and let inheritance handle the rest.
You can validate and experiment with this setup using the Casbin Policy Editor, which is useful for testing and debugging policies.