Complex Righty System: ACL, RBAC and more what?
Asked Answered
K

2

8

We are currently developing a project management software. And we are having trouble deciding on the correct approach to implement security. We have looked at both ACL and RBAC and are already pretty certain that we need at least a combination of both for specific reasons. But there are a couple of problems that do not have a nice solution in either world. Let me explain:

Let's say you have the following entities:

  1. Users, with different roles, i.e.
    • Project Lead
    • Worker
    • Admin
  2. Projects
  3. Assigned Users
  4. Tasks in Project

Now the following rule should be expressed: A User with the Role Worker is only allowed to view Tasks, which are related to a project he is assigned to.

This results in that a User is only allowed to view some Tasks in the whole list.

We would use RBAC to give Roles the permission to actually read Tasks. But the condition is not applied as there are specific entities involved. ACL could be used, but we fear the nightmare of keeping the ACL entries consitent with the requirements (Users can change, Roles can change, new Tasks can be introduced an would have to get the correct entries, which is just as complex).

Of course there could be specific queries when viewing a specific project (WHERE project_id = 123), but this does not help for a "View of all my current Tasks", where basically every task can be considered for display, but the ACL would have to be checked for every single entriy.

And how do I ensure things like "Get the first 25 Tasks the current User is allowed to see" without loading all the tasks from the DB and then filtering based on the ACL, i.e. handling pagination.

Kiddush answered 27/11, 2012 at 9:10 Comment(0)
M
6

You need to look beyond ACL and RBAC and consider attribute-based access control (ABAC - see NIST's guide here). Gartner calls this space "externalized authorization management".

With ABAC, you can easily express any rules that take into account not just who the user is but also what the user wants to do, where, when, why, and how. Using attributes to define authorization, you can use XACML to implement policies. XACML is an OASIS standard (just like SAML).

With XACML, you get an API where you can ask questions e.g.: can Alice view this record? But in your case, it's not enough because you want to filter out records from the database. And, as you describe, you want the query to be the right from the start rather than going back and forth to the database until you have the right number of authorized records. This is where XACML becomes particularly interesting because it's technology-neutral. You can apply XACML to Java, C#, and other languages e.g. Python but also apply XACML to different layers (presentation, APIs, and... databases). XACML can be queried in a reverse query way to produce a SQL statement which you could then use to query your backend database for the relevant records:

  • Which records can Alice view?
  • Alice can view records in California which yields "SELECT * FROM records WHERE location='CA'"

HTH

Menard answered 30/9, 2013 at 16:44 Comment(0)
S
1

Well, I use Yii framework with its nice RBAC layer. I'm not too familiar with ACLs, nor did I need to be, lately.

In Yii RBAC terms, your key to the solution is using 'business rules'. Bizrules are small snippets of code that are attached to a 'permission' or a 'role' (an 'auth item' in Yii's terms). This code is run dynamically when the need to determine access to a certain 'permission' (lets say, but it could also be attached to a 'role'), and it recieves the 'item in question' (task in your example) and determine actual access to the specific task or not. Here's a more detailed example:

  • say you need to have the following permissions:
    • Edit task (which should be allowed to anyone with the role 'tasks administrator')
    • Edit own tasks (which should be allowed to the person who submitted this task).
  • Now, in the 'task edit' code section, you would first check for 'edit task' permission. if ok - allow.
  • if wasn't allowed, also check for 'edit own task' (using else-if construct). Now on the last mentioned permission there should be attached a bizrule (=php code) that accepts a 'task' object and compares its 'creator id' to the 'currently checked user id'. If equal, it returns true, meaning access should be granted.

That's in a nutshell. If you're interested in more, see this section of the official guide. There are also a bunch of other resources, should you need.

Solutrean answered 27/11, 2012 at 11:9 Comment(5)
Thank you for your answer. From my understanding those business rules are what I would call "filtering in application code", which does not solve my problem. I would make a query to retrieve the tasks (25) and then maybe some results are filtered out by the business rule. Then I would need to make another call to the DB and filter again until I can return 25 results. That is not very good in my opinion. In my mind I would want to apply the business rules to the SQL query and retrieve 25 results right away.Kiddush
This question is tagged with PHP. Can you shed light on what framework/library you're building on top, if any, if decided? It can make the discussion more fruitful... .Solutrean
We will be using ZF2. ZF2/ACL and ZfcRbac as the modules. But I guess PHP might be the wrong tag?Kiddush
First, I think that tagging with PHP is good, especially after you've laid out your technology decisions. I would have certainely added ZF or ZF2 tags as well since there are two ways to address this question - the first is from the theoretical aspect and the second is from the technical aspect. It could very well be a case where somebody in the ZF community has already tackled a similar use case and could reply with a skeleton design as a solution (without deep understanding of the theoretical background).Solutrean
As to your question, I'm partially drawing out of my sleeve: (1) business rule in the setup I described above can be considered as 'dynamic filtering in runtime' (in code, yep). (2) (this is where I draw out of the sleeve) If you setup a 'junction table' that links UIDs to task ids then I can you can in the SQL level, perhaps combined with some code to make this SQL, to implement the needed logic, which means that the "assigned user" entity you've detailed above will be expressed as a "relationship" and that relationship will be checked at runtime.Solutrean

© 2022 - 2024 — McMap. All rights reserved.