rbaccasbin

How can I link a collection of users to policy rules of a single resource using Casbin RBAC?


Unable to come up with appropriate RBAC model for linking collection of users to policy rules of a single resource.

[request_definition]
r = resource_id, module, action
[policy_definition]
p = priority, resource_id, module, action, eft
[role_definition]
g = _, _
[policy_effect]
e = priority(p.eft) || deny
[matchers]
m = p.resource_id == r.resource_id && ((g(p.module, r.module) || ((p.module == r.module) && (p.eft == 'allow'))) && p.action == r.action || p.module == 'admin')

The model above allows me to create granular policy rules for individuals. For example: Jason can view, create and edit users but they can't delete users. This would be described as:

p, 1, jason, users, view,   allow
p, 1, jason, users, create, allow
p, 1, jason, users, edit,   allow
p, 1, jason, users, delete, deny

What I need is a way to link a collection of users to a resource. Let me explain: let's say you have a group in your system that houses 10 users. The intent is to be able to assign permissions to that group and have those permissions be linked to all 10 members. Why? Less data to manage if you just have to update the policy rules of a single resource instead of 10.

Here's what I think it would look like in terms of group/policy rules:

g, group1, ken
g, group1, roman
g, group1, shiv

p, 1, group1, users, view,   allow
p, 1, group1, users, create, allow
p, 1, group1, users, edit,   allow
p, 1, group1, users, delete, allow

With the above in mind, ken trying to 'view' users module would resolve as true.

I have not been able to figure out the matcher I need for this use-case. Any help would be appreciated.


Solution

  • I managed to figure out the model I needed to meet my requirements. Here it is:

    [request_definition]
    r = user, module, action
    
    [policy_definition]
    p = priority, user, module, action, eft, is_exception
    
    [role_definition]
    g = _, _
    
    [policy_effect]
    e = priority(p.eft) || deny
    
    [matchers]
    m = (r.user == p.user || g(p.user, r.user)) && (r.module == p.module || g(p.module, r.module)) && r.action == p.action
    

    I hope this is helpful!