enhanced centralized authorization / permission control

Events happening in the community are now at Drupal community events on www.drupal.org.
garthee's picture

I am Garthee from Sri Lanka, who did uLink (universal filtering of links at real time and auto completion of links through AJAX ) for GSOC ’07. As I am still at University, I would like to apply once more and here is my idea…

The problem at hand is authorization / permission control in Drupal.

Why it is needed?I think the permission system currently available addresses only the basic needs of a community site and numerous modules (ACL, FORUM ACCESS) try to extend it for specific needs. However it would be better to handle the following needs in a more structured way, to enable drupal to be used in enterprise systems, intranets or sites with variety of admin control needs like levels of moderator. Open ID and LDAP integration encourages the use of Drupal in such environments and the proposed system will improve it further

  1. Users can be individually GRANTED permission in addition to the default ROLE permissions (eliminates the need of creating excess amount of roles)
  2. Users / Roles can be DENIED permission. (effective permission is evaluated and a page to filter out / display effective permissions)
  3. Nested roles (Enables several levels of moderators for forums, torrent sites / community sites)
  4. Permission control for each user / role (collection of users) to each object (node – say node/1, comments – say node/1#commment-2, files – say file:2 (fid)) or collection of objects (nodes as a whole or a type of node – story, for instance) with external hooks allowed, which means some external module can decide how / what level of permission should be granted.
    >> The aforementioned is a huge requirement for an enterprise / large system. For instance with this support, roles can be created for a particular object only . ie a particular term or node (also some modules deal with this requirement partly or distantly, by including it in the core we could create more centralized permission system)
  5. As a whole permission system this will takeover the permission / role related tasks from user.module and let it be a user object alone which along with roles (another object in this new view) will interact with other objects under the supervision of permission system to which other modules can hook into and implement additional GRANT / DENY options.

I tried to briefly explain what I have in the mind, and hope it is understandable 

Please give your suggestions and feedbacks on this..

Garthee
www.theebgar.net

Comments

I like the idea and I

dldege's picture

I like the idea and I mentored Garthee last year on his project and I know he's sharp and a hard worker.

Dan DeGeest
Software Developer
Somewhere or Another

There's some talk about

catch's picture

There's some talk about refactoring the node_access table, this would probably have to include that and/or work alongside any changes. If I can find the issue (if there is one) I'll post it back here.

You should also look at the field permissions discussion in the Data Architecture Design Sprintgroup.

node_access unnecessary ??

garthee's picture

The proposed solution could make node_access unnecessary as every type of object and every single object (a particular node in this case) will be permission controlled and of course with some optionals granted / denied for a particular user on top of roles permission.

However, if possible, i am hoping to see this get integrated with core, where it will become more relevant to the discussion going on in Data Architecture Design Sprintgroup.

does less feedback mean the idea is rejected?

garthee's picture

I saw the necessity of such a module when using drupal for an intranet.. however as a general purpose CMS, I would like to receive the feedback from the community on the need of such an extensive centralized role and user based permission mechanism similar to a domain / workstation environment such as windows2003 permissions with possibilities of allowing hooks to define policies as well

This sounds great!

jstoller's picture

I've been dying to see an overhaul of user.module with many of the features you propose here. I even submitted a feature request to this effect at http://drupal.org/node/217934. I, for one, would love to see you take this on and sincerely hope it finds its way into core in the near future.

my road map

garthee's picture

thanks jstoller for pointing me that.

exactly this is what I am looking forward to handle here, and my road map is
1. implement it as a separate module providing necessary functions (other modules have to call these api /hooks to use them)
2. patch to user module, to effect that and enforce it for all modules with in D6
3. Integration with core in D7, such that user.module will be used for creation and user management (profile and other stuff), and possibly authentication integrated (but with expanding authentication options I hope this is handled separately) and this permission.module to oversee all authorization, role, permission management and policy management related tasks with hooks to implement policies.

I have already coded a skeleton module to work along with user.module for user based permissions.. which, with community feedbacks, i m looking forward to develop as a standalone permission module.

Legacy support

jstoller's picture

What will happen with existing modules, none of which are aware of your module, when I install permission.module? Do you foresee me having to manage users in two different places? Or will there be some sort of backwards compatibility layer in there, so calls to the old user.module will be redirected to your permission.module? Until this is fully integrated into core, I see legacy support as being a major hurdle.

Certainly there will be

garthee's picture

Thats what I mentioned in the road map.

  1. Considering all modules will implement our functions, create an independent api / hooks, pages, tables
  2. To work with previous versions (D5 / D6) patches to user.module (user_access()) is the central location for most of the permission handling.
  3. Once it gets integrated to core, patch becomes unnecessary and a restructured user.module results, in future D releases.

Within GSOC scope (assuming integration with user.module or core is not happening) this will provide a complete way to use the new permission system in existing / new Drupal releases.

If it can be integrated with core, as all of us will be glad, this becomes the supervising module!

Great Idea!

houndbee's picture

The "patch" the user.module idea didn't go down very well with me. I would recommend dropping the assumption of integration into core when you start working on the module and looking at more modular ways to achieve this.

I love the module idea, definitely think a fine-grained permissions API like the one proposed is needed. Ideally, once installed, this module should give you the control to decide on whether your module should override all other pemissions. Provide an API which other module developers can work with to use your permissions system.

Cheers,
-K

Agreed

gdd's picture

As has been pointed out on several proposals, patching core has been notoriously troublesome for SoC projects in the past. A modular approach is definitely best. That said I love houndbee's idea of creating a permissioning API which opens up a permission system for others to use. A great many modules are starting to take the approach of laying the foundation for others to build on (see Services, Faceted Search, etc.) I'd welcome a proposal in that direction.

Agree to some extent!

garthee's picture

Thanks houndbee for the feedback.

I didn't assume the absorption into the core, and I m sure, people will be reluctant to let a considerably new face into core-development ;-)

As I said in roadmap, I would like to the cover the following within GSOC
1. A parallel permission module to user.module, which will of course use some of the existing tables, while using new to address everything from object perspective (user object inherits permissions from role object, and together with its own permission, access the other objects / groups of objects - eg nodes or node/11 over the permission system) with APIs / HOOKS to implement policies. However modules will have to call our permission APIs, for instance to evaluate a permission to a node perhaps xxx_authorize($node) or xxx_authorize($module, $object_id), which will certainly affect the implementation over legacy modules.
2. Certainly at least a single line patch is needed at user.module if existing permissions to be controlled as everything is routed through user_access function in legacy modules, and it doesn't provide any hooks. However if there is any workarounds available in this context I am willing to follow.

And beyond the scope of GSOC I will leave the community to adopt to core this depending on its functionality. However, I have built a module implementing a part of idea and available for demo at
www.project.theebgar.net

Please contact me at admin/at/theebgar/dot/net to obtain the account to test it, and I am sure you will understand the significance of the security related with that account (as it needs permission to sets permissions) :D

PS: Along with my GSOC proposal (application) I am hoping to provide few interaction diagrams, and database structures I am having in mind so that community can help me refining it

More "why do we need this"

alex_b's picture

As to "why this is needed" could you describe some real-world issues that are not solvable with the current permission system but would be with the approach you suggest here? While I see the technical limitations of Drupal's permissioning, I like the fact that it is SIMPLE.

One problem that I am aware of is that there is no way in Drupal to grant users particular roles for particular areas/groups of your web site - this leads to all kinds of messiness in OG.

Simple?

jstoller's picture

I would never call Drupal's permission scheme simple. Limited, yes, but not simple. Not from a usability standpoint. Just being able to define a child role that inherits the permissions of its parent would be an enormous improvement in simplifying the administration of a large site.

I've been slowly trying to figure out how to move my organization's web presence over to Drupal and the lack of flexible, fine-grain permission control is arguably the largest single obstacle in my path.

Adding a little complexity to the underlying system, if well designed, will vastly simplify its use.

Exactly

garthee's picture

Drupal permission system is powerful but limited and inadequate for an enterprise application with fine control needs. Just give me a day, as I am currently reviewing my proposal, and I will publish my GSOC proposal here with the problems it addresses and the features (some expected and some not :) ) it can present.

However I believe everything in Drupal begins from "Why don't we have this?" and "Wouldn't it be a nice to have this?" and, certainly unless there is already a module implementing this, "Why do we need this?" is irrelevant after many use cases have been cited and await for few more in the proposal :)

Part of my proposal...

garthee's picture

OBJECTIVE:

I propose an authorization system to run along with
user.module in current implementations as a separate
module, and supersede user.module’s functions wherever
appropriate and eventually, in future strip user.module
of permission related tasks and perform all on its own,
which I hope will happen in reality.

PROJECT DETAILS:

The following description is also expected to answer the
question why this module is needed.

I am expecting to achieve the following within GSOC scope.

  1. Enable assigning permissions to users (currently only
    possible through roles)
  2. Nested roles (Currently flat and no hierarchy is
    possible) with permission inheritance.
  3. Enable both GRANT and DENY permissions for both ROLES
    and USERS currently only grant is possible, due to the
    cumulative nature of design. However with permission
    inheritance in nested roles and user based permission
    assignment will require DENY permission too.
  4. Policies (currently not available in this context, but
    node_access is somewhat related, and applying this to
    nodes). See (5)
  5. Virtual groups (users can be grouped by location, time
    zone or any other option profile module could present)
    so that policies can be applied implicitly. As this is
    somewhat new, to explain it further, it is like a user
    from Canada is allowed to view Canada pages without
    assigning him a specific role. Or users from UK are
    allowed to access check_uk_stock module and
    Buckingham_jabber module’s all features except admin
    configurations of those modules.
  6. Default admin role – A role where a user can be
    assigned to admin position with access to all features,
    except permission control page. Only root user will be
    able to add / remove users from this role and
    permissions are hardcoded for this role.
  7. User area and admin area (which is somewhat related
    to memory management :) ) Through our API, we will
    require modules to define two different sets of
    permissions, and user area permissions are flexible
    and granted through policies implicitly as well.
    However admin area permission is critical of nature
    and requires explicit control which is provided only
    to admin_role (or perhaps to other roles explicitly
    assigned – a design dilemma)
  8. Permissions are applied to an object (node/1) or
    collection of objects.

    This opens up a lot of new implementations. For
    instance in node module for node objects, the
    following example explains an awesome possibility.

    a. Node module can define four permissions namely,
    view_node, create_node,
    create_node_with_set_permissions, adminster_nodes
    b. And it can restrict access to view_node to
    virtual group of Canadian users, create_node to
    a virtual group of Canadian parliament members
    – virtual group and
    c. create_node_with_set_permissions
    to only whips (or party leaders)- virtual group
    where all these permissions belong to user area.
    Adminster_nodes – which is an admin area permission,
    can be granted to site_adminstrator role and not
    to any virtual groups
    d. The roles or virtual groups with
    create_node_with_set_permission can decide who can
    view/edit/delete each node when they create, and
    this is only possible because of object wise
    permission available

  9. Object containers – objects will be collected through
    some means. For instance, all nodes belong to node
    container or perhaps story container. (Which can be
    again nested, but only of single hierarchy to avoid complications).
  10. Finally policies and virtual containers (Very much similar to node_access
    implementation)

For instance someone can pick and apply permissions to
all modules coming under taxonomy term north_america.

SOLUTION DESCRIPTION:

Most of the following discussion is subject to change in
the implementations as per the guidelines of the mentor
and the community.

Additional field in {role} table to specify the parent
role’s rid (if available) will give us a single hierarchy
nested roles. A role can be assigned to admin role through
configurations, and member need to be explicitly assigned to this
role, where they will gain all access except access control.
A table similar to {permission} with uid can be used to
record user based permissions, and I am bit against using
{users} table for this. Permissions are always cumulated
on GRANTS through inheritance and all DENYs are removed
from the list of GRANTed. Which guarantees higher precedence
for DENY.

Without affecting the existing functionality, when modules
register for permissions through hook_perm() they can
provide two additional parameters (or possibly single
associative array – new approach in Drupal 6 – which is
more extensible) area (user / admin) where user (=0) is
default, and whether specific to any object (otherwise null).

Most of the background control will be handled through
hook_db_rewrite_sql, however depending on the workarounds'
availability, a patch to user.module at user_access () maybe
needed, which I will try my best to avoid. However as
user.module says “All permission checks in Drupal should go
through this function. This way, we guarantee consistent
behavior, and ensure that the super user can perform all
actions.” - it is where exemptions from permission control
and final decisions are made at times, and it may be
unavoidable to workaround other way.

Finally hooks and APIs are provided to support, virtual
groups, containers and policy implementations. In the
case of virtual groups roles can be created and users are
assigned to on the fly or users are directly assigned to
the relevant permissions on the fly (see the use case
above) or a new table can be used (need to be discussed).
Policies are what assigning permissions to virtual groups
and a filtering system similar to views selection can be
adopted here. As objects also inherit permissions, i.e. all
pages will inherit the permissions for ‘page’ container,
unless overridden for a user of child role. This will be
done through a cached real time evaluation of permissions.
At necessary points, hooks will be allowed to modify the
default behavior, especially in policies and permission
evaluations, and hope to provide the GUI for admin settings
through hooks and APIs, thus we would provide the examples
to expand the module within the module and make it more modular.

ROADMAP:

This module will address the aforementioned needs in its
own way independently and modularly as explained above,
and will seldom interact with user.module.

Once most of the user.module is shown to be handled by
this module effectively, it can substitute user.module
for permission related tasks in future releases.

So basically cascading ACL's?

macgirvin's picture

It sounds more or less like the Windows access model, but with a few minor differences. This type of thing works well for operating systems, but on the web there are usually implementation issues to consider.

One test case that will prove the concept or doom it to failure is the case of listing/viewing items 40-60 of the most recent 'articles'. But the catch is that we're now talking about items 40-60 of the subset of articles that the viewer has permission to list/view.

Ideally the security needs to be implementable in the SQL itself to make this test case work, but there are few models this ambitious which can return the desired results using SQL alone, without resorting back to looping through code to check further up the access tree, expand groups, etc. How many results do you have to fetch from the DB in order to ensure that you get twenty that are visible? (Answer - potentially all of them). This doesn't scale. There are currently a few ways out -

  • Restructure the entire platform so that listing aggregated items isn't possible.
  • List items 40-60 (of all the articles) and upon evaluation of inadequate permissions in code, mark the item 'Locked. Keep out'. User experience folks hate this, but it's one of the few ways to make it work.
  • Use a simpler security model. (Such as Anonymous, registered, owner - which can be implemented completely in SQL.)

I guess what this is pointing to isn't that we want to know what you're going to do. This kind of thing has been proposed before. Where the rubber meets the road is how it scales and plays out in the wild.

Nothing to do with ACL and over feared

garthee's picture

Thanks for your thoughts / ideas into this.

  1. The problem addressed has wider scope not limited to node view, or even node access.
  2. Handling at SQL through rewrite is one of the method that will be used.
  3. Windows model (was even mentioned in the proposal) is from user interaction perspective - used as an example to explain abstract idea - implementation is totally different.
  4. Performance is a concern, but these have been implemented, but decentralized.
    Here the main idea is to restructure user.module permission (where there will be no additional overhead) and extending what is provided through node_access and other various modules to all objects.

For the example you provided we could select only 40 nodes through sql rewrite for those with permissions in a single call. Basically, we will keep roles and user (which is new) based permissons (which is of less overhead than roles), and many features (virtual groups) wil mostly be rolled back to roles / user permission, thus at run time no additional overhead .

Most of the proposed ideas are desperately needed, could be simply hacked (but improperly) with another LEFT JOIN or two. We will restructure, provide hooks and apis and do it drupalisticallly.

Scalability / performance is a concern but not a problem, but in the basic mode it will be faster / powerful than what is currenly available, and for a enterprise intranet this will mostly be acceptable provided we embrace proper measures.

I think its great. I'm not

JK_drupal's picture

I think its great. I'm not really good at programing at all, but seems like your module will be similar in effect to http://groups.drupal.org/node/10231 Hope this helps! =)

So did you do well with your application?

SoC 2008

Group categories

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: