You are here

Drupal access controls need a major rewrite

Submitted by Peter on Thu, 2010-05-13 21:06

Drupal access controls are a long way ahead of typical web site access controls and are still a long way from perfect. The access controls are in need of a serious rewrite to remove the inconsistencies making life so difficult when you grow a site from simple to complex. Drupal 7 will brings some minor improvements over Drupal 6. With a little work, the future Drupal 8 could kill off all the major problems.

The ideal

You connect users to user groups. You connect resources to resource groups. You then connect user groups to resource groups. Adding a new person or resource is incredibly easy.

The reality is that most security systems try to misuse one set of groups for both users and resources. You are then stuck with the truely painful task of creating many groups and connecting either users or resources to many groups. Unix did it the wrong way. Even IBM made the mistake with their major access control system.

Take an example of a security system with the right architecture, ten user groups, and ten resource groups. To emulate that system using a single set of groups instead of the two sets of groups, you need a hundred groups to cover all combinations. Now move up to a large system with a thousand groups of users and a thousand groups of resources. The bad architecture has to use a million groups for comparable control.

Drupal 6 equivalents

Drupal groups users by role. A role is not the same as a user access group but is very close for most sites. Roles are also used for workflow and other controls. Roles work for access control when there is one organisation, one department, etc. Roles fail as access control groups when there are multiple branches and similar structural divisions requiring separate access controls but the same workflow and other role related controls.

A common Drupal resource is a node and nodes are grouped by node type. Nodes can also be grouped by taxonomy and other options. None of the common node classification and grouping controls are suitable for resource access groups. They all work for some sites where you use only simple combinations. Mixing several requirements makes life complicated and the results unpredictable.


Inconsistencies make development projects tough. Drupal has a user table separate from the node table. There are a lot of good reasons for the separate table. Unfortunately Drupal added a lot of descriptive information to the user table. What should have happened was the creation of a user node for each user and the placement of the descriptive information in the node table with the user table restricted to purely the login/logout requirement. Access to the user node could then be controlled by exactly the same access controls as the other nodes. D7 might have users moved into nodes.

The node module provides controls for creating, viewing, updating, and deleting nodes. The create, update, and delete controls also work by node type but the view control does not work by node type. You have to add another module to control viewing of nodes by node type.

The default administrator has all accesses switched on by default and does not have a defined role. Drupal 7 assigns the default administrator to a default administration role so you can assign workflow and other features to the administrator role.

There are a few other inconsistencies that make poor starting points for access control.

Fixing user groups

The user grouping for access control needs to be separate from the control of workflow. We need a user group function to bring together large groups of users. We then need separate workflow roles to assign by user group.

Separating user groups from workflow roles and other role related features is something suited to an optional core module for use on large sites. When you turn on the option, the role tables would be replicated into two sets then updated independently. A user group could have multiple roles.

Fixing resource groups

Current attributes misused as resource groups for access control include node type and taxonomy terms. There is no common system for presenting a full range of access controls or presenting controls based on their dependencies.

The Taxonomy Access Control module does one thing right. It displays some access controls with the options Allow, Deny, and Ignore. Ignore is the missing option in many of the access control modules and is the bit that lets access control modules define an access control rule as not applicable in specific circumstances.

The Ignore option could be named skip this rule or not applicable. The terminology is not important so long as it is consistent. By comparison, CSS has an equivalent but calls it none in some places, inherit in others plus uses several other terms for the same meaning.

Nodes should start with a default access of Allow, Deny, or Ignore. Every other level of control should have Allow, Deny, and Ignore. You can then add multiple layers of access control with each one being able to kill access or to grant access or to not contribute to access.

All the access control modules should then have their access control decisions displayed to the administrator.

There is a Devel module that has something to display access control decision results. That part of Devel should be a separate optional core module you can switch on when modifying access controls.

The access control modules can be given a priority through a weight but there is no consistency about the way they contribute to the decision because they all have to reply with yes or no then Drupal has to make a sometimes silly decision based on the inaccurate information. If modules had the option of not contributing to the decision, Drupal might end up with just one module supplying a yes or a no and that would simplify everything.

Take an example of an image gallery. You might use the image gallery type only for private user access. You want the image gallery node type controlled by a module giving access by user. There might be no other node types controlled by user and the access module could immediately reply with Ignore whenever the node type is not an image gallery. All the other access modules could be set to replay Ignore for nodes of type image gallery so the final decision can be based purely on the reply from one module.

Drupal 8

Drupal 8 is a long way off. Count back the huge time required to implement changes and you have a relatively small gap between Drupal 7 and Drupal 8. Changes for Drupal 8 need a really clear consistent approach defined before decisions are made on what should be included.

Often the problem is the Application Programming Interface available to module developers. Developers can create modules do provide wonderful new functions until they hit a point where there is no interface point to connect into Drupal. Drupal then needs a change to provide a socket where you can plug in your new idea. The sockets are called hooks.

If there is no hook in the right place, you need the hook added. Getting a hook added is a real problem. You have to prove a feature works to get the hook added. To prove the feature works, you have to build a working module. The module needs the hook to work. In reality you end up building the hook yourself then placing the hook in a demonstration system then fighting to make people take notice.

A great idea might not be first priority

Your improvement might be ignored many times then independently invented by several other people who need the same feature. One of the many separate inventions might then be accepted or they might all be ignored.

I contributed a lot of ideas and inventions for Drupal 4, 5 and 6. Some of those inventions are in Drupal but from different developers. I gave up promoting one memory conservation invention over a year before someone else contributed a similar improvement. I realised Drupal had a memory usage problem in one area and I invented a simple solution. I did not need it for my own sites because I kept my own sites clean and efficient. I did offer the invention to the community.

Lots of people said they wanted the feature, based on comments in forums and elsewhere, but none wanted it enough to take my idea or code and plug it in. A year later, someone felt some Web site pain enough to work on the same problem and develop the same solution. A huge improvement to one site might not translate to huge improvements for all sites. Even when my idea will make a huge improvement to your site, it might not be your first priority.


Remove the inconsistencies. Drupal 7 will remove some. Make the remainder a priority. Make the Ignore part of Allow, Deny, and Ignore a priority for every module that does not implement that choice. Then start work on modules to separate user groups from roles and resource groups from the many common substitutes.