Use of hook_node_access()

Drupal 7 has the interesting hook hook_node_access(), that allows managing access to a specific content and, herewith, overrides the control of any other modules. For example, if we return NODE_ACCESS_DENY, we will close access to the content regardless of using any other access control system.
Furthermore, hook_node_access() is ignored by Views, a menu system and any other content request. In other words, if we have a link in a menu or output a link to the content header with Views, we will still see this link. Access will be denied only if we try to view the content by clicking on this link. The hook hook_node_access() also is not called for the user with uid=1, i.e. someone has an access to all the materials. So hook_node_access() should be used carefully.

As an example, we forbid viewing all the page type materials.

function mymodule_node_access($node, $op, $account) {
  if ($op == 'view' && $node->type == 'page') {
    return NODE_ACCESS_DENY;

Use of “Grant API”

The correct approach is using a “grant” system. The key hooks here are hook_node_access_records() and hook_node_grants(). The former one is “a lock”, and the second one is “a key”.

The hook hook_node_access_records() defines whether the particular node should be blocked. The hook adds a record to the table {node_access} with realm specified by us (a zone,where user should possess granted ID) and gid (granted ID). For easier identification, the name of a module is usually used as realm, where the hook is declared. It is worth noting, that hook_node_access_records() is called only when saving node.

The hook hook_node_grants() purpose is to inform the node access system about permissions (“keys”) that the user posses.

In the following example we give full access to the page type materials user with rid=3 role.

function mymodule_node_access_records($node) {
  $grants = array();
  if ($node->type == 'page') {
    $grants[] = array(
      'realm' => 'mymodule',
      'gid' => 3,
      'grant_view' => TRUE,
      'grant_update' => TRUE,
      'grant_delete' => TRUE,
  return $grants;

function mymodule_node_grants($account, $op) {
  $grants = array();
  foreach ($account->roles as $rid => $role) {
    $grant_rids[] = $rid;
  $grants['mymodule'] = $grant_rids;
  return $grants;