Access Control - Casbin
I was trying to read about RBAB (Role-Based Access Control) and ABAC(Attribute-Based Access Control); after some reading - I realized, as a software engineer - it’s way more easier when you get to read code - So, I started to search for open source project which implements access control infrastructure, and stumbled upon Casbin.
Snip from Readme: In Casbin, an access control model is abstracted into a CONF file based on the PERM metamodel (Policy, Effect, Request, Matchers). So switching or upgrading the authorization mechanism for a project is just as simple as modifying a configuration. You can customize your own access control model by combining the available models. For example, you can get RBAC roles and ABAC attributes together inside one model and share one set of policy rules.
The interesting part here is how Casbin - has designed the whole system behind a simple yet flexible configuration file and grammars to describe predicates. Intent of this blog is - just to get you curious about Casbin. Casbin has reasonally good documentation on their site.
ProTip: Best way to understand an open source is to start with the test cases, look at each test case - review the context and assert statements.
Lets look at a simple RBAC Model Config
[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.act
p, alice, data1, read
p, bob, data2, write
p, data2_admin, data2, read
p, data2_admin, data2, write
g, alice, data2_admin
Basically there are four parts: Request, Policy, Matcher and Effect. Ref
Request: Defines the parameter name and order which we should provide for access control matching function. This enables the code/model to be setup when the data is read from the source.
Policy: It’s the Access stratergy. This is how our internal system is designed. It defines the name and order of the fields in the Policy rule document.
Matchers:: This is similar to a predicate function - which shall describe if the request allowed. Rules which help us to match the request and the policy.
Effect: It’s useful, when there are multiple patterns which would match and you would need to make a decision. There are defaults, here you get to override both allow and deny defaults. Refer: PolicyEffect.
Inheritance:
- If A has role B, B has role C, then A has role C. This transitivity is infinite for now
- Casbin doesn’t distinguish role from user in its RBAC. They are all treated as strings.
p, data2_admin, data2, read
g, alice, data2_admin
In the above example,
- data2_admin has read access to data2
- alice inherits/is a member of role data2_admin. alice here can be a user, resource or a role.
rm = get_role_manager()
#1
rm.add_link("u1", "g1")
rm.add_link("u3", "g2")
self.assertTrue(rm.has_link("u1", "g1"))
self.assertFalse(rm.has_link("u1", "g2"))
self.assertCountEqual(rm.get_roles("u1"), ["g1"])
self.assertCountEqual(rm.get_roles("u2"), ["g1"])
#2
rm.add_link("u1", "g1", "domain1")
self.assertTrue(rm.has_link("u1", "g1", "domain1"))
self.assertFalse(rm.has_link("u1", "g1", "domain2"))
What Casbin does NOT do:
- Authentication (aka verify username and password when a user logs in)
- manage the list of users or roles.
Reference: Casbin