OrBAC
What is OrBAC?
OrBAC (Organisation-Based Access Control) extends RBAC with abstractions and an organization dimension. Policies refer to roles, activities, and views; concrete users, actions, and objects are mapped to them per organization. That keeps policy stable when entities change.
Three mappings (all scoped by organization):
- Empower — user → role
- Use — action → activity
- Consider — object → view
Permission is granted when the request’s (subject, action, object) maps to a (role, activity, view) that has permission in that org.
Model
[request_definition]
r = sub, org, obj, act
[policy_definition]
p = role, activity, view, org
[role_definition]
g = _, _, _
g2 = _, _, _
g3 = _, _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.role, r.org) && g2(r.act, p.activity, r.org) && g3(r.obj, p.view, r.org) && r.org == p.org
g— subject has role in org (Empower)g2— action is activity in org (Use)g3— object is in view in org (Consider)r.org == p.org— same organization
Policy Examples
Permission rules specify which roles can perform which activities on which views in each organization:
# Permission: role, activity, view, organization
p, manager, modify, document, org1
p, manager, consult, document, org1
p, employee, consult, document, org1
p, manager, modify, report, org2
p, manager, consult, report, org2
p, employee, consult, report, org2
Empower rules assign roles to subjects within organizations:
# Empower: subject, role, organization
g, alice, manager, org1
g, bob, employee, org1
g, charlie, manager, org2
g, david, employee, org2
Use rules map concrete actions to abstract activities:
# Use: action, activity, organization
g2, write, modify, org1
g2, read, consult, org1
g2, write, modify, org2
g2, read, consult, org2
Consider rules map concrete objects to abstract views:
# Consider: object, view, organization
g3, data1, document, org1
g3, data2, document, org1
g3, report1, report, org2
g3, report2, report, org2
Code Example
import "github.com/casbin/casbin/v3"
e, _ := casbin.NewEnforcer("examples/orbac_model.conf", "examples/orbac_policy.csv")
// alice is a manager in org1, can read and write documents
ok, _ := e.Enforce("alice", "org1", "data1", "read") // true
ok, _ = e.Enforce("alice", "org1", "data1", "write") // true
// bob is an employee in org1, can only read documents
ok, _ = e.Enforce("bob", "org1", "data1", "read") // true
ok, _ = e.Enforce("bob", "org1", "data1", "write") // false
// charlie is a manager in org2, can read and write reports
ok, _ = e.Enforce("charlie", "org2", "report1", "read") // true
ok, _ = e.Enforce("charlie", "org2", "report1", "write") // true
// Cross-organization access is denied
ok, _ = e.Enforce("alice", "org2", "report1", "read") // false
ok, _ = e.Enforce("charlie", "org1", "data1", "read") // false
Benefits
- Abstraction — Policies use roles, activities, and views; you can change concrete mappings without rewriting policy.
- Per-organization — Each org has its own mappings and permissions; one model covers all.
- Scalability — Fewer, clearer rules in multi-org setups.