Skip to content
intermediate Phase 31 · Admin & System XML

acl.xml — ACL Resource Tree

ACL resource tree definitions, admin permissions, role management, and access control configuration.

45m
0 problems
Topic Progress 0%

ACL Resource Tree Structure

ACL (Access Control List) defines a hierarchical tree of permissions for admin resources.

acl.xml structure:

<?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::stores">
                    <resource id="Magento_Backend::stores_settings">
                        <resource id="Magento_Backend::config"/>
                    </resource>
                </resource>
                <resource id="Vendor_Module::menu">
                    <resource id="Vendor_Module::menu_items"/>
                    <resource id="Vendor_Module::menu_settings"/>
                </resource>
            </resource>
        </resources>
    </acl>
</config>

Resource hierarchy:

Magento_Backend::admin (root)
├── Magento_Backend::stores
│   └── Magento_Backend::stores_settings
│       └── Magento_Backend::config
├── Vendor_Module::menu
│   ├── Vendor_Module::menu_items
│   └── Vendor_Module::menu_settings
└── Magento_Catalog::products
    ├── Magento_Catalog::products_create
    ├── Magento_Catalog::products_edit
    └── Magento_Catalog::products_delete

Resource ID naming:

  • Format: Vendor_Module::resource_name
  • Root: Magento_Backend::admin
  • Use underscores, not hyphens

Module ACL Configuration

Each module defines its own ACL resources that extend the main tree.

Module acl.xml:

<?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="Vendor_Blog::blog" title="Blog Management">
                    <resource id="Vendor_Blog::blog_posts" title="Blog Posts"/>
                    <resource id="Vendor_Blog::blog_categories" title="Blog Categories"/>
                    <resource id="Vendor_Blog::blog_settings" title="Blog Settings"/>
                </resource>
            </resource>
        </resources>
    </acl>
</config>

System configuration ACL:

<!-- system.xml uses ACL for section access -->
<section id="vendor_blog" type="text" sortOrder="300" showInDefault="1">
    <label>Blog Settings</label>
    <resource>Vendor_Blog::blog_settings</resource>
    <!-- Only users with Vendor_Blog::blog_settings permission see this -->
</section>

Menu ACL:

<!-- menu.xml uses ACL for menu visibility -->
<add id="Vendor_Blog::blog" title="Blog" module="Vendor_Blog"
     sortOrder="80" resource="Vendor_Blog::blog"/>

Controller ACL:

namespace Vendor\Blog\Controller\Adminhtml\Post;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;

class Save extends Action
{
    const ADMIN_RESOURCE = 'Vendor_Blog::blog_posts';
    
    public function execute()
    {
        // Only accessible with Vendor_Blog::blog_posts permission
    }
}

API ACL:

<route url="/V1/blog/posts" method="GET">
    <service class="Vendor\Blog\Api\PostRepositoryInterface" method="getList"/>
    <resources>
        <resource ref="Vendor_Blog::blog_posts"/>
    </resources>
</route>

Admin Roles and Permissions

Admin roles control what resources each admin user can access.

Role hierarchy:

All (root)
├── Roles
│   ├── Administrator (all permissions)
│   ├── Marketing Manager
│   │   ├── Catalog
│   │   ├── CMS
│   │   └── Blog
│   └── Customer Service
│       ├── Sales
│       └── Customer

Role configuration:

-- Admin roles table
SELECT * FROM acl_role;
-- role_id, role_name, parent_id, tree_level, sort_order, role_type, user_id, is_active

-- Role-resource assignments
SELECT * FROM acl_role_resources;
-- role_id, resource_id, permission (allow/deny)

-- Admin user roles
SELECT * FROM admin_user;
-- user_id, username, ... (roles assigned via admin user form)

Managing roles via CLI:

# Create admin role
php bin/magento admin:user:create --role="Marketing"

# List roles
php bin/magento admin:roles:list

# Assign permissions (typically done via admin UI)

Role-based system config:

<!-- Restrict config section to specific role -->
<section id="vendor_settings" type="text" sortOrder="100">
    <label>Vendor Settings</label>
    <resource>Vendor_Module::settings</resource>
    <!-- Only users with this resource can see/edit -->
</section>

Permission inheritance:

  • Child resources inherit parent permissions
  • If user has Vendor_Blog::blog, they have access to all children
  • Can explicitly deny specific children

ACL Debugging and Best Practices

Debugging ACL issues and best practices for permission design.

Debugging ACL:

# Check ACL tree
php bin/magento setup:di:compile 2>&1 | grep acl

# Verify resource exists
grep -r "Vendor_Module::resource" app/code/Vendor/Module/etc/

# Check role assignments
mysql -u root -p magento -e "SELECT * FROM acl_role_resources WHERE resource_id LIKE '%Vendor%';"

# Test permission in code
if ($this->authorization->isAllowed('Vendor_Module::resource')) {
    // User has permission
}

Common ACL issues:

1. Resource not in tree → 403 Forbidden
2. Role doesn't include resource → Access denied
3. Wrong resource ID format → Resource not found
4. Missing parent resource → Children not accessible

Best practices:

<!-- 1. Use descriptive resource names -->
<resource id="Vendor_Blog::posts_manage" title="Manage Posts"/>

<!-- 2. Create granular permissions -->
<resource id="Vendor_Blog::posts">
    <resource id="Vendor_Blog::posts_view" title="View"/>
    <resource id="Vendor_Blog::posts_create" title="Create"/>
    <resource id="Vendor_Blog::posts_edit" title="Edit"/>
    <resource id="Vendor_Blog::posts_delete" title="Delete"/>
</resource>

<!-- 3. Follow Magento naming convention -->
<!-- Vendor_Module::resource_subresource -->

<!-- 4. Always add title for UI display -->
<resource id="Vendor_Blog::posts" title="Blog Posts"/>

ACL in controllers:

// Check permission before action
public function execute()
{
    if (!$this->_isAllowed()) {
        return $this->_redirect('adminhtml/*/denied');
    }
    // ... action logic
}

protected function _isAllowed(): bool
{
    return $this->_authorization->isAllowed(self::ADMIN_RESOURCE);
}

Quiz

1. What is the root ACL resource in Magento?

Question 1 options

2. How do you check ACL permission in a controller?

Question 2 options

3. What format do ACL resource IDs follow?

Question 3 options

4. How does permission inheritance work in ACL?

Question 4 options

Flashcards

Question

What is the root ACL resource?

Answer

Magento_Backend::admin

Question

What XML file defines ACL resources?

Answer

acl.xml

Question

How do you check permission in PHP?

Answer

$this->_authorization->isAllowed('Vendor_Module::resource')

Question

What is the resource ID naming format?

Answer

Vendor_Module::resource_name

Question

Where are admin roles stored?

Answer

acl_role and acl_role_resources database tables

Revision Notes

Key Takeaways

  • 1. ACL defines a hierarchical permission tree rooted at Magento_Backend::admin
  • 2. Each module defines resources in acl.xml
  • 3. Resources are referenced in system.xml, menu.xml, controllers, and webapi.xml
  • 4. Child resources inherit parent permissions
  • 5. Roles assign sets of resources to admin users
  • 6. Use isAllowed() in controllers to check permissions

Interview Tips

  • Explain the ACL resource hierarchy
  • Describe how to create custom ACL resources
  • Discuss role-based permission management
  • Know how to check permissions in controllers

Cheat Sheet

ACL Cheat Sheet

Root resource: Magento_Backend::admin
Naming: Vendor_Module::resource_name
File: acl.xml in module etc/ directory

Usage locations:

  • system.xml: tag
  • menu.xml: resource attribute
  • controllers: ADMIN_RESOURCE const
  • webapi.xml:

Check permission:

$this->_authorization->isAllowed('Vendor_Module::resource')

Role tables:

  • acl_role: Role definitions
  • acl_role_resources: Role-resource mapping