Magento 2's role-based access control (RBAC) system uses Access Control Lists (ACL) to define granular permissions for admin users. This guide covers creating custom roles, configuring permissions, understanding resource hierarchies, and implementing advanced ACL configurations.
Understanding Magento ACL
ACL Architecture
Access Control List (ACL) defines which resources a role can access.
Key Components:
- Resources: System features and functions (catalogs, orders, reports)
- Roles: Named permission sets assigned to users
- Rules: Allow/deny permissions for specific resources
- Scope: Global, website, or store view level access
Permission Inheritance
Permissions follow a hierarchical structure:
Magento_Backend::admin (Root)
├── Magento_Sales::sales (Sales)
│ ├── Magento_Sales::sales_order (Orders)
│ │ ├── Magento_Sales::actions (Actions)
│ │ ├── Magento_Sales::create (Create)
│ │ └── Magento_Sales::cancel (Cancel)
│ ├── Magento_Sales::sales_invoice (Invoices)
│ └── Magento_Sales::sales_shipment (Shipments)
├── Magento_Catalog::catalog (Catalog)
│ ├── Magento_Catalog::products (Products)
│ └── Magento_Catalog::categories (Categories)
└── Magento_Customer::customer (Customers)
Inheritance Rules:
- Granting parent permission grants all child permissions
- Denying parent permission denies all child permissions
- Child permissions can be individually managed
Creating Custom Roles
Via Admin Panel
1. Navigate to Roles:
System > Permissions > User Roles > Add New Role
2. Role Information Tab:
Required Fields:
- Role Name: Descriptive name (e.g., "Marketing Manager", "Catalog Editor")
- Your Password: Current admin password for verification
3. Role Resources Tab:
Resource Access Options:
- All: Full access to all resources (not recommended except for administrators)
- Custom: Select specific resources
4. Configure Permissions:
For Marketing Manager:
- Content
- Pages
- Blocks
- Widgets
- Marketing
- Promotions
- Email Templates
- SEO & Search
- Reports
- Marketing Reports
- System
- Stores
5. Save Role:
- Click "Save Role"
- Role appears in roles grid
Via Database (Advanced)
Create role programmatically:
<?php
use Magento\Authorization\Model\RoleFactory;
use Magento\Authorization\Model\RulesFactory;
class RoleCreator
{
protected $roleFactory;
protected $rulesFactory;
public function __construct(
RoleFactory $roleFactory,
RulesFactory $rulesFactory
) {
$this->roleFactory = $roleFactory;
$this->rulesFactory = $rulesFactory;
}
public function createRole($roleName, $resources)
{
// Create role
$role = $this->roleFactory->create();
$role->setName($roleName)
->setPid(0) // Parent ID (0 = root)
->setRoleType('G') // G = Group
->setUserType(2); // 2 = Administrator
$role->save();
// Set permissions
$rules = $this->rulesFactory->create();
$rules->setRoleId($role->getId())
->setResources($resources)
->saveRel();
return $role;
}
}
// Usage
$resources = [
'Magento_Catalog::catalog',
'Magento_Catalog::products',
'Magento_Catalog::categories'
];
$roleCreator->createRole('Catalog Manager', $resources);
Resource Permissions
Core Resource Groups
1. Dashboard
Magento_Backend::dashboard
- View admin dashboard
- Sales statistics
- Best sellers
- Last orders
2. Sales
Magento_Sales::sales
├── Magento_Sales::sales_order
│ ├── Magento_Sales::actions (View, Edit, Create, Delete)
│ ├── Magento_Sales::create
│ ├── Magento_Sales::actions_view
│ ├── Magento_Sales::actions_edit
│ ├── Magento_Sales::email
│ ├── Magento_Sales::reorder
│ ├── Magento_Sales::cancel
│ ├── Magento_Sales::hold
│ └── Magento_Sales::unhold
├── Magento_Sales::sales_invoice
├── Magento_Sales::sales_shipment
├── Magento_Sales::sales_creditmemo
└── Magento_Sales::transactions
3. Catalog
Magento_Catalog::catalog
├── Magento_Catalog::products
├── Magento_Catalog::categories
├── Magento_Catalog::inventory
│ └── Magento_Catalog::products (Manage Stock)
└── Magento_Catalog::update_attributes
4. Customers
Magento_Customer::customer
├── Magento_Customer::manage
├── Magento_Customer::actions
│ ├── Magento_Customer::create
│ ├── Magento_Customer::edit
│ ├── Magento_Customer::delete
│ └── Magento_Customer::view
├── Magento_Customer::group
└── Magento_Customer::online
5. Marketing
Magento_Backend::marketing
├── Magento_CatalogRule::promo (Catalog Price Rules)
├── Magento_SalesRule::quote (Cart Price Rules)
├── Magento_Email::template
├── Magento_Newsletter::template
├── Magento_Review::reviews_all
└── Magento_Search::search
6. Content
Magento_Backend::content
├── Magento_Cms::page
├── Magento_Cms::block
├── Magento_Widget::widget_instance
├── Magento_Theme::design_configuration
└── Magento_PageBuilder::template (Page Builder)
7. Reports
Magento_Reports::report
├── Magento_Reports::salesroot (Sales Reports)
├── Magento_Reports::product (Products Reports)
├── Magento_Reports::customers (Customers Reports)
├── Magento_Reports::marketing (Marketing Reports)
└── Magento_Reports::search (Search Terms)
8. Stores
Magento_Backend::stores
├── Magento_Backend::stores_settings
│ ├── Magento_Config::config (Configuration)
│ ├── Magento_Store::store (Stores)
│ ├── Magento_Config::config_general
│ └── Magento_Tax::manage_tax
├── Magento_Backend::stores_attributes
│ ├── Magento_Catalog::attributes_attributes
│ └── Magento_Catalog::sets
└── Magento_Backend::stores_other_settings
9. System
Magento_Backend::system
├── Magento_Backend::cache
├── Magento_Indexer::index
├── Magento_Backend::tools
├── Magento_User::acl (Permissions)
│ ├── Magento_User::acl_roles (Roles)
│ └── Magento_User::acl_users (Users)
└── Magento_Integration::integrations
Common Role Configurations
Marketing Manager Role
Permissions:
Dashboard
Marketing
Promotions (Cart Price Rules, Catalog Price Rules)
Email Templates
Newsletter Templates
SEO & Search
Content
Pages
Blocks
Widgets
Design Configuration
Reports
Marketing Reports
Sales Reports (Read-only)
Customers (Read-only)
View Customers
Edit/Delete Customers
System
Stores Configuration
ACL Resources:
$resources = [
'Magento_Backend::dashboard',
'Magento_Backend::marketing',
'Magento_CatalogRule::promo',
'Magento_SalesRule::quote',
'Magento_Email::template',
'Magento_Newsletter::template',
'Magento_Search::search',
'Magento_Backend::content',
'Magento_Cms::page',
'Magento_Cms::block',
'Magento_Widget::widget_instance',
'Magento_Theme::design_configuration',
'Magento_Reports::report',
'Magento_Reports::marketing',
'Magento_Reports::salesroot',
'Magento_Customer::customer',
'Magento_Customer::actions_view'
];
Catalog Manager Role
Permissions:
Dashboard
Catalog
Products (Create, Edit, Delete)
Categories
Inventory
Product Attributes
Attribute Sets
Reports
Products Reports
Inventory Reports
Pricing (Optional restriction)
Sales
System
ACL Resources:
$resources = [
'Magento_Backend::dashboard',
'Magento_Catalog::catalog',
'Magento_Catalog::products',
'Magento_Catalog::categories',
'Magento_Catalog::inventory',
'Magento_Catalog::attributes_attributes',
'Magento_Catalog::sets',
'Magento_Reports::product'
];
Customer Service Role
Permissions:
Dashboard
Sales
Orders (View, Edit, Cancel, Hold)
Invoices
Shipments
Credit Memos
Customers
All Customers (View, Edit)
Customer Groups
Reports
Sales Reports
Customer Reports
Catalog
System
Pricing Rules
ACL Resources:
$resources = [
'Magento_Backend::dashboard',
'Magento_Sales::sales',
'Magento_Sales::sales_order',
'Magento_Sales::actions_view',
'Magento_Sales::actions_edit',
'Magento_Sales::email',
'Magento_Sales::cancel',
'Magento_Sales::hold',
'Magento_Sales::sales_invoice',
'Magento_Sales::sales_shipment',
'Magento_Sales::sales_creditmemo',
'Magento_Customer::customer',
'Magento_Customer::manage',
'Magento_Customer::actions',
'Magento_Reports::salesroot',
'Magento_Reports::customers'
];
Content Editor Role
Permissions:
Dashboard
Content
Pages (Create, Edit, Delete)
Blocks
Widgets
Page Builder Templates
Design
Themes
Design Configuration
Catalog
Sales
Customers
System
ACL Resources:
$resources = [
'Magento_Backend::dashboard',
'Magento_Backend::content',
'Magento_Cms::page',
'Magento_Cms::block',
'Magento_Widget::widget_instance',
'Magento_PageBuilder::template',
'Magento_Theme::design_configuration'
];
Reports/Analytics Role (Read-Only)
Permissions:
Dashboard
Reports (All - Read Only)
Sales Reports
Products Reports
Customers Reports
Marketing Reports
Customers (View Only)
Sales (View Only)
Catalog (View Only)
Any Write Operations
System
Configuration
Advanced Permission Scenarios
Website/Store Scope Permissions
Restrict users to specific websites in multi-site setup.
Configuration:
System > Permissions > User Roles > [Role] > Role Resources > GWS Scope
Options:
- All Websites: Access all sites
- Specific Websites: Select websites
- Default Store View: Limit to specific store view
Database Implementation:
public function setWebsiteScope($roleId, $websiteIds)
{
$rule = $this->rulesFactory->create();
$rule->setRoleId($roleId)
->setResources(['Magento_Backend::all'])
->setWebsiteIds($websiteIds) // Array of website IDs
->saveRel();
}
Time-Based Permissions
Implement temporary elevated access (requires custom module).
Custom ACL with expiration:
<?php
namespace Vendor\Module\Plugin;
use Magento\Framework\Authorization;
class TemporaryPermissions
{
public function afterIsAllowed(
Authorization $subject,
$result,
$resource,
$privilege = null
) {
// Check if user has time-limited permission
$expiration = $this->getPermissionExpiration($resource);
if ($expiration && time() > $expiration) {
return false; // Permission expired
}
return $result;
}
protected function getPermissionExpiration($resource)
{
// Retrieve from custom table
// Return timestamp or null
}
}
API-Only Roles
Create roles specifically for API access.
Integration Permissions:
System > Extensions > Integrations > Add New Integration
Set API Resources:
- Same ACL structure as admin roles
- OAuth-based authentication
- Token-based access
Example:
// Create integration with specific permissions
$integration = $this->integrationFactory->create();
$integration->setName('Third-Party Integration')
->setEmail('api@partner.com')
->setStatus(1);
$integration->save();
// Set permissions
$this->authorizationService->grantPermissions(
$integration->getId(),
[
'Magento_Catalog::products',
'Magento_Sales::sales_order'
]
);
Custom ACL Resources
Defining Custom Resources
File: app/code/Vendor/Module/etc/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">
<!-- Main resource group -->
<resource id="Vendor_Module::main" title="My Module" sortOrder="100">
<!-- Sub-resource: Manage -->
<resource id="Vendor_Module::manage" title="Manage Items" sortOrder="10">
<resource id="Vendor_Module::create" title="Create" sortOrder="10"/>
<resource id="Vendor_Module::edit" title="Edit" sortOrder="20"/>
<resource id="Vendor_Module::delete" title="Delete" sortOrder="30"/>
</resource>
<!-- Sub-resource: View -->
<resource id="Vendor_Module::view" title="View Items" sortOrder="20"/>
<!-- Sub-resource: Reports -->
<resource id="Vendor_Module::reports" title="View Reports" sortOrder="30"/>
<!-- Sub-resource: Configuration -->
<resource id="Vendor_Module::config" title="Configuration" sortOrder="40"/>
</resource>
</resource>
</resources>
</acl>
</config>
Checking Permissions in Code
Controller:
<?php
namespace Vendor\Module\Controller\Adminhtml\Item;
use Magento\Backend\App\Action;
class Edit extends Action
{
const ADMIN_RESOURCE = 'Vendor_Module::edit';
public function execute()
{
// Automatic ACL check based on ADMIN_RESOURCE constant
// If permission denied, user redirected to access denied page
}
}
Block:
<?php
namespace Vendor\Module\Block\Adminhtml;
use Magento\Backend\Block\Template;
use Magento\Framework\AuthorizationInterface;
class Items extends Template
{
protected $authorization;
public function __construct(
Template\Context $context,
AuthorizationInterface $authorization,
array $data = []
) {
$this->authorization = $authorization;
parent::__construct($context, $data);
}
public function canEdit()
{
return $this->authorization->isAllowed('Vendor_Module::edit');
}
public function canDelete()
{
return $this->authorization->isAllowed('Vendor_Module::delete');
}
}
<?php if ($block->canEdit()): ?>
<button>Edit</button>
<?php endif; ?>
<?php if ($block->canDelete()): ?>
<button>Delete</button>
<?php endif; ?>
Permission Testing
Test Role Permissions
1. Create Test User:
php bin/magento admin:user:create \
--admin-user="test_marketing" \
--admin-password="Test123!" \
--admin-email="test@example.com" \
--admin-firstname="Test" \
--admin-lastname="Marketing"
2. Assign Role:
- System > Permissions > All Users
- Edit test user
- Assign "Marketing Manager" role
3. Login as Test User:
- Logout current admin
- Login with test credentials
- Verify accessible/restricted areas
4. Document Results:
- Can access: Dashboard, Content, Marketing
- Cannot access: System, Stores, Configuration
- Expected behavior confirmed
Troubleshooting
Permission Denied Errors
Issue: User sees "Access Denied" despite role assignment
Solutions:
Clear ACL cache:
php bin/magento cache:clean config php bin/magento cache:flushVerify role assignment:
SELECT u.username, r.role_name FROM admin_user u JOIN authorization_role r ON u.user_id = r.user_id WHERE u.username = 'username';Check resource exists:
grep -r "Vendor_Module::resource" app/code/Rebuild ACL:
php bin/magento setup:upgrade php bin/magento cache:flush
Inherited Permissions Not Working
Issue: Child permissions not inherited from parent
Solution: Verify ACL hierarchy in etc/acl.xml:
- Ensure proper nesting
- Check resource IDs match
- Verify sortOrder values
Best Practices
- Principle of Least Privilege: Grant minimum necessary permissions
- Regular Audits: Review roles quarterly
- Descriptive Names: Use clear, descriptive role names
- Documentation: Document custom roles and purposes
- Test Thoroughly: Test new roles before production deployment
- Avoid "All" Permission: Create custom roles instead
- Separate Concerns: Create focused, single-purpose roles
- Monitor Changes: Enable admin action logging
Next Steps
- Adding and Removing Users - User lifecycle management
- Security Best Practices - Harden admin security
Additional Resources
- Magento ACL Documentation - Official ACL guide
- Authorization Module - Authorization architecture
- User Roles Guide - Admin user guide