In the previous article we explained how to configure and delimitate access rights for the Magento 2 admin panel users. In this article, you will learn how to create your own access rules (Role Resources).

User Role Reasources in Magento 2

You need to create ACL file (ACL - Access Control List) in your module folder:

etc/acl.xml

add the following code there:

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
    <acl>
         <resources>
             <resource id="Magento_Backend::admin">
                 <resource id="Magento_Backend::content">
                     <resource id="VendorName_ModuleName::key1" title="Title 1" sortOrder="10">
                         <resource id="VendorName_ModuleName::key2" title="Title 2" sortOrder="10" />
                     </resource>
                 </resource>
                 <resource id="Magento_Backend::stores">
                     <resource id="Magento_Backend::stores_settings">
                          <resource id="Magento_Config::config">
                              <resource id="VendorName_ModuleName::key3" title="Title 3" />
                          </resource>
                     </resource>
                  </resource>
             </resource>
         </resources>
     </acl>
</config>

After clearing the Magento cache, you will see new items in the Role Resources tab on the User Roles edit page.

The first two resources (key1, key2) relate to menu items. Their hierarchy can match the menu hierarchy. These resources should be specified in the menu.xml  (resource attribute), for example:

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
    <menu>
       <add id="VendorName_ModuleName::key1" title="Title 1" module="VendorName_ModuleName" parent="OtherVendorName_OtherModuleName::content" sortOrder="10" resource="VendorName_ModuleName::key1"/>
        <add id="VendorName_ModuleName::key2" title="Title 2" module="VendorName_ModuleName" parent="VendorName_ModuleName::key1" sortOrder="10" action="path/controllerName" resource="VendorName_ModuleName::key2"/>
    </menu>
</config>

The third resource (key3) added for the Magento 2 configuration page section (Stores> Configuration). Note: the parent element for key3 is Magento_Config::config. In order for it to work, it must be specified in the system.xml file, for example:

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <tab id="tab_id" translate="label" sortOrder="110">
            <label>My Tab</label>
        </tab>
        <section id="section_id" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
            <class>separator-top</class>
            <label>My Section</label>
            <tab>tab_id</tab>
            <resource>VendorName_ModuleName::key3</resource>
            ....

After changing the configuration XML files, clear the Magento 2 cache.

If your module uses its own admin panel controllers, set the access rights for them. In the controller class, add a constant with the ACL key name, for example:

const ADMIN_RESOURCE = 'VendorName_ModuleName::key1';

You can also restrict access to some blocks of the admin panel using the \Magento\Framework\Authorization::isAllowed method, for example:

if ($this->_authorization->isAllowed('VendorName_ModuleName::key1')) {
    //є доступ
} else {
    //доступ заборонений
}

In the examples, we create a module for FAQ. The modified module code can be viewed on GitHub.