---
title: "Best practices for Drupal permissions"
date: "2022-02-11T05:31:00+00:00"
summary:
image:
type: "article"
url: "/acquia-cloud-platform/help/92666-best-practices-drupal-permissions"
id: "80ecd1d1-64ee-4c4d-9cda-bf6004f18306"
---

Table of contents will be added

Although Drupal has a rich and extensible role and permissions system, there are some common mistakes and associated best practices to consider when working with the system.

Use permissions appropriately
-----------------------------

User roles and permissions are the two administrative building blocks of the Drupal permissions system. You can manage these through the user interface [site path](/node/92336), and they provide a granular system for granting rights to users. The [User Roles](https://www.drupal.org/node/1803614) page on Drupal.org contains additional information that you can use to become familiar with users and permissions.

Make reviewing your user permissions a regular administrative task and be sure to [secure your website and permissions after an employee leaves](/node/56062). Acquia customers can also use [Teams and Permissions](/node/56052) to instantly and easily add users to their subscriptions, which can grant or limit user access to their websites.

Programmatic changes
--------------------

You can programmatically allow or revoke permissions in code.

### Drupal 7 and hook\_permission

If you use Drupal 7, the [`hook_permission`](http://api.drupal.org/api/drupal/modules--system--system.api.php/function/hook_permission/7) function (which replaces `hook_perm`) allows module developers to declare more information about a permission. See the explanation following the code block for information about how to use each value.

    <?php
    function hook_permission() {
      // Read the explanation below. When copying, modify values as appropriate. 
      return array(
        // First an example of a relatively harmless permission - accessing content.
        'access imported twitter content' => array(
          'title' => t('Access imported Twitter content'), 
          'description' => t('Allows users to view imported tweets.'),
          'restrict access' => FALSE, // This is the default so it could be excluded for brevity.
        ),
        'alter imported twitter styles' => array(
          'title' => t('Alter imported Twitter feed styles '), 
          'description' => t('Change CSS classes/rules via the administration settings.'),
          'restrict access' => TRUE,
          'warning' => t('CSS classes and styles can contain Javascript making this a potential attack vector.'),
        ),
      );
    }
    ?>

*   The updated hook is now **keyed** off of a string that is used internally to check the permission.
*   The internal string can and should be different from the user-facing `title` value. The title is meant to be descriptive and short.
*   Developers can use the `description` value to provide additional information about the kinds of rights this permission will grant to a user.
*   The `restrict access` boolean indicates to Drupal core whether or not to display a warning message on the Permissions page, and based on the [Drupal Security team's policy](https://www.drupal.org/security-advisory-policy), will not produce a security advisory for any permission that has `restrict access` set to `TRUE`.
    
    Set `restrict access` to `TRUE` only for permissions that, by their very purposes, could allow a malicious user who has the permission to take over the website. For example, the core permission **Administer users** on the website is an example of a permission where the nature of the task already allows a malicious user to take over the website. Administering the text of a node does not, by its nature, allow a malicious user with that permission to take over the website and `restrict access` should not be set to `TRUE`.
    
*   Use the `warning` message to describe situations when using a permission inappropriately can cause errors or problems with a website.

### Drupal 8

To implement the permissions used on the same page in Drupal 8, you can use the following example. This code would be added to a file called `[modulename].permissions.yml` which would sit in the root of the module file (on the same level as `[modulename].module`. `hook_permission()`in a module file will no longer work in Drupal 8. Here's the change record ([https://www.drupal.org/node/2311427](https://www.drupal.org/node/2311427)).

The same keys of title, description, restrict access and warning are still used, but are implemented in the yaml file rather than in a `hook_permission()`. As an example:

    access imported twitter content:
      title: 'Access imported Twitter content'
      description: 'Allows users to view imported tweets.'
      restrict access: FALSE
    alter imported twitter styles:
      title: 'Alter imported Twitter feed styles'
      description: 'Change CSS classes/rules via the administration settings.'
      restrict access: TRUE
      warning: 'CSS classes and styles can contain Javascript making this a potential attack vector.'

Ensure that information can be accessed but not changed
-------------------------------------------------------

When creating a module, it's a best practice to create new permissions for specific features of your module. You can associate the administration page or administrative functions with **Administer mymodule**, while other features might use **Access mymodule** or **Use mymodule's feature**.

However, if your module is very small and you feel that the functionality it provides is similar to core functionality, you can use some basic permissions that are available with every website with the system module:

*   **Administer site configuration**
*   **Use the administration pages and help**

When using these built-in permissions, consider what you're granting access to. If users will be able to change the configuration of your website, then it's appropriate to use **Administer site configuration** as the permission to protect that functionality. If the module is just for viewing information, then it would be appropriate to use **Use the administration pages and help**.