cartalyst / sentinel

A framework agnostic authentication & authorization system.
BSD 3-Clause "New" or "Revised" License
1.52k stars 240 forks source link

[4.0] Per-Object Roles #206

Open rodrigo-castillo opened 8 years ago

rodrigo-castillo commented 8 years ago

I read through the documentation and didn't find anything to this effect. Is it currently possible in Sentinel, and if not is it desirable to add, per-object roles? It appears that this (and pretty much any other) authorization package is geared toward system-wide roles.

I'd implemented this in Laravel 4 (without sentry/sentinel) and used a roles table with an optional 'object' column that contained the classname of an object, and an object_id column that contained the id of an object.

I kept permissions in a separate table, and didn't have any sort of hard constraints on what roles could be applied to what objects, though that might be desirable.

For implementing in sentinel it might be possible to create a new table, role_user_objects, with columns for user_id, role_id, object, object_id (or overload/replace the role_users table), and still keep all of the roles in the roles table.

brunogaspar commented 8 years ago

Are you talking about RBAC?

rodrigo-castillo commented 8 years ago

Yes, but one of the not-so-defined bits of it http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf section 7.4 "Permissions can be fine-grained (e.g., at the level of individual objects)..." which is talked about slightly more in http://profsandhu.com/journals/tissec/ANSI+INCITS+359-2004.pdf section 5.1

After more googling and trying more search terms I found https://github.com/BeatSwitch/lock , which does have object-specific permissions https://github.com/BeatSwitch/lock#setting-and-checking-permissions but has a few downsides: It is no longer maintained, for one, and it isn't clear if roles/permissions can be assigned in the way that I'm thinking.

Apologies in advance for a wall of text:

For example, an object of class Post with id 1 has attributes title, body, and summary. A Post is hidden except to those who have permission to view it. There are three types of roles for a Post, postAuthor, postContributor, and postReviewer, assigned to users A, B, and C respectively.

The postAuthor role has the permissions manage_users, edit_title, edit_body, edit_summary, and view. The postContributor role has the permissions edit_body, edit_summary, and view. The postReviewer role only has the permission view.

As a postAuthor for post 1, User A has permission to edit all attributes of the Post 1, and can also manage what users have what roles on Post 1. As a postContributor for Post 1, user B has permission to only edit the body or summary of post 1. As a postReviewer for Post 1, user C has permission to view post 1 but cannot make edits.

If there is a user D who is a postAuthor for Post 2, he has no permissions to view or edit Post 1, nor do users A, B, or C have any permissions to view or edit Post 2.

I did some thinking on how to implement this in Sentinel as-is, and I'd probably need to have a naming scheme for the roles that included the object type and id (e.g., Post:1:Author, Post:1:Contributor, Post:1:Reviewer, Post:2:Author, etc.) and stuff the appropriate permissions into each.

The issue I feel I'd run into is the duplication of the essential role names and their permissions. If I wanted to change all postContributor's permissions to remove the permission to edit the summary, or add the permission to edit the title, I'd need to update every row that matched the naming scheme.

What I'd rather have is a limited number of roles (e.g., Admin, Moderator, User, postAuthor, postContributor, postReviewer, etc) and then when associating a role with a user, have the option to scope it to a specific resource.

Is that perhaps clearer?

brunogaspar commented 8 years ago

I'll make this as a proposal for Sentinel 3 as i believe this was somewhat requested before.

alexweissman commented 8 years ago

I've actually been looking at replacing the in-house RBAC system I designed for UserFrosting with Sentinel, but I have this concern as well.

My system currently allows you to associate checkpoints with users and roles ("groups"), and even define conditions using a restricted subset of PHP (basically, expressions consisting of boolean operators, and methods that return boolean values). We store them in the database, so that they can be dynamically modified through the frontend interface.

Do you think it will be easy to implement this using Sentinel?