~ 3 min read

Implementing user-specific, role-based access control per node type, per group. (Part 2)

share this story on
Understanding Drupal's node access system and how to hook into it to implement

More in-depth node access system overview

So what is that node access system?
The involved components are a few hooks that modules define if they want to hook into the way the node access system work; Furthermore, there’s the node_access table in the database which maintains all of the grants for each node in the system.

The node_access table

This table is joined against queries and it’s holding all of the nodes in the system and their grants. The table is updated with every node that gets created or possibly it can be recreated at any point in time, which is useful if a new module that implements a different access control is installed. The table’s structure:


  • nid - the node id, and there’s at least one record for each node that exists.
  • gid – the grant id. A grant id is something abstract. It can be anything upon which you may decide to grant access (within the constraints of the field type – it’s an unsigned int).
  • realm – a name to identify this grant type.
  • grant_view, grant_update, grant_delete – either 1 or 0, stating if that grant record allows view, update or delete permission.

Module hooks

  • Modules define the grant records – modules which define hook_node_access_records() get the current node being processed as an argument and decide what to set as the realm and grant id. This hook should return an array of grants which is basically composed of the fields in the node_access table. This process happens when the node access rebuild action fires or anytime a node is being created.

  • Modules define the grants – when a node access check is being made, modules implementing hook_node_grants() are called with the user account and current node being accessed and should return their grants.

To put this together, when a node is being accessed and goes through a node access check: we have in one side the node_access database table which holds all of the grant records, upon which the user should be granted access to a node, and in the other side we call up modules with the node being accessed and tell them to return their grant records. This yields a WHERE clause where the module’s returned grants are then compared against the database. Since Drupal’s node access system uses an OR to concatenate all of the modules’ grants, it’s enough that one realm or one grant will approve access to the node for the user to gain access to it.