1. 8.3.x core/modules/node/node.module node_access
  2. 8.0.x core/modules/node/node.module node_access
  3. 8.1.x core/modules/node/node.module node_access
  4. 8.2.x core/modules/node/node.module node_access
  5. 8.4.x core/modules/node/node.module node_access
  6. 4.6.x modules/node.module node_access
  7. 4.7.x modules/node.module node_access
  8. 5.x modules/node/node.module node_access
  9. 6.x modules/node/node.module node_access
  10. 7.x modules/node/node.module node_access

The node access system determines who can do what to which nodes.

In determining access rights for a node, node_access() first checks whether the user has the "bypass node access" permission. Such users have unrestricted access to all nodes. user 1 will always pass this check.

Next, all implementations of hook_node_access() will be called. Each implementation may explicitly allow, explicitly deny, or ignore the access request. If at least one module says to deny the request, it will be rejected. If no modules deny the request and at least one says to allow it, the request will be permitted.

If all modules ignore the access request, then the node_access table is used to determine access. All node access modules are queried using hook_node_grants() to assemble a list of "grant IDs" for the user. This list is compared against the table. If any row contains the node ID in question (or 0, which stands for "all nodes"), one of the grant IDs returned, and a value of TRUE for the operation in question, then access is granted. Note that this table is a list of grants; any matching row is sufficient to grant access to the node.

In node listings (lists of nodes generated from a select query, such as the default home page at path 'node', an RSS feed, a recent content block, etc.), the process above is followed except that hook_node_access() is not called on each node for performance reasons and for proper functioning of the pager system. When adding a node listing to your module, be sure to use a dynamic query created by db_select() and add a tag of "node_access". This will allow modules dealing with node access to ensure only nodes to which the user has access are retrieved, through the use of hook_query_TAG_alter(). Tagging a query with "node_access" does not check the published/unpublished status of nodes, so the base query is responsible for ensuring that unpublished nodes are not displayed to inappropriate users.

Note: Even a single module returning NODE_ACCESS_DENY from hook_node_access() will block access to the node. Therefore, implementers should take care to not deny access unless they really intend to. Unless a module wishes to actively deny access it should return NODE_ACCESS_IGNORE (or simply return nothing) to allow other modules or the node_access table to control access.

To see how to write a node access module of your own, see node_access_example.module.


modules/node/node.module, line 2925
The core that allows content to be submitted to the site. Modules and scripts may programmatically submit nodes using the usual form API pattern.


Namesort descending Location Description
hook_node_access modules/node/node.api.php Control access to a node.
hook_node_access_records modules/node/node.api.php Set permissions for a node to be written to the database.
hook_node_access_records_alter modules/node/node.api.php Alter permissions for a node before it is written to the database.
hook_node_grants modules/node/node.api.php Inform the node access system what permissions the user has.
hook_node_grants_alter modules/node/node.api.php Alter user access rules when trying to view, edit or delete a node.
node_access modules/node/node.module Determines whether the current user may perform the operation on the node.
node_access_acquire_grants modules/node/node.module Gets the list of node access grants and writes them to the database.
node_access_grants modules/node/node.module Fetches an array of permission IDs granted to the given user ID.
node_access_needs_rebuild modules/node/node.module Flags or unflags the node access grants for rebuilding.
node_access_rebuild modules/node/node.module Rebuilds the node access database.
node_access_view_all_nodes modules/node/node.module Determines whether the user has a global viewing grant for all nodes.
node_access_write_grants modules/node/node.module Writes a list of grants to the database, deleting any previously saved ones.
node_list_permissions modules/node/node.module Helper function to generate standard node permission list for a given type.
node_node_access modules/node/node.module Implements hook_node_access().
node_permissions_get_configured_types modules/node/node.module Returns an array of node types that should be managed by permissions.
node_query_entity_field_access_alter modules/node/node.module Implements hook_query_TAG_alter().
node_query_node_access_alter modules/node/node.module Implements hook_query_TAG_alter().
_node_access_rebuild_batch_finished modules/node/node.module Implements callback_batch_finished().
_node_access_rebuild_batch_operation modules/node/node.module Implements callback_batch_operation().
_node_query_node_access_alter modules/node/node.module Helper for node access functions.


danielb’s picture

There are also some Devel hooks which are documented on this API site, that aren't mentioned here.

hook_node_access_explain() - Explain your records in the {node_access} table.
Recommended to developers of node access modules as it helps site admins debug their setups.

hook_node_access_acknowledge() - Acknowledge ownership of 'alien' grant records.
Never used this, but it might be useful for someone.

mavaddat’s picture

user 1 will always pass this check.

This is unclear and grammatically incorrect (capitalization). Much better is the wording on the hook_node_access page:

The administrative account (user ID #1) always passes any access check [...]