Admin Role Access Control
/
On a multi-store Adobe Commerce and Magento Open Source installation, every back-office user who can open the Orders grid sees orders from every website and store view. A brand running three regional storefronts with an outsourced support team has no native way to stop agents reading each other's orders: admin roles govern what a user may do, but not where. Role Permissions, an extension for Magento Open Source and Adobe Commerce, adds that missing dimension – it limits each admin role to a chosen set of websites and store views, so regional teams, outsourced support agents and secondary-brand staff work only their own storefronts' data.
Administrators configure scope on a Store Scope tab added to each role under System → Permissions → User Roles: a checkbox tree of every website and its store views, plus an Allow access to ALL toggle. Ticking a website grants all of its store views. A freshly created role is restricted by default (zero-trust) until it is explicitly granted access; the built-in Administrator role always remains unrestricted.
The boundary is enforced on three independent layers, so an out-of-scope record cannot be reached even by guessing its id or URL: grid collections are filtered to the role's allowed scope; mass-action collections are filtered the same way; and single-entity controllers reject an out-of-scope Order, Invoice, Shipment, Credit Memo, Customer or Product with a 404. The grid filter and the controller gate back each other up.
The same boundary covers the surfaces a store-scoped admin actually works through. Categories are scoped by the root category of each granted store view, across the category tree, the product form's picker, autocomplete, the widget chooser and admin global search – and creating, saving, moving or deleting a category outside that scope is refused. The admin store switcher offers only granted store views, on every screen that renders it, and the store a request is addressed to is validated before the page runs, so a store view that is not offered cannot be reached by editing the URL either. Reports and the dashboard's bestsellers figures cover granted store views only, including when no store filter is set at all.
A second dimension controls what fields a role may see. Attribute Permissions hide chosen product and category attributes, and whole attribute groups, from an admin role: pick Deny mode (hide the selected) or Allow mode (show only the selected), per entity. Hidden fields disappear from the product and category edit forms, and – for products – are removed from the save request, so a restricted admin cannot change a field they cannot see even with a crafted request; hiding a required field does not break saving. Use it to keep Cost, margin or supplier fields out of a content editor's reach.
Role Permissions is a rule-based, deterministic, on-premise extension for Magento Open Source and Adobe Commerce. It calls no external service and performs no profiling – access is resolved purely from the websites, store views and attributes you assign. It adds its own database tables with cascade cleanup on role deletion and modifies no core tables. Admin-only: there is no storefront footprint, so it is theme-agnostic.
Key Features
- Per-role category scope – the category tree, product-form picker, new-category dialog, autocomplete, widget chooser and global search show granted category trees only
- Category write protection – creating, saving, moving or deleting a category outside the role's scope is refused, including moving one into it
- Filtered admin store switcher – every screen that renders it offers granted store views only
- Store-context validation – the store a request is addressed to is checked before the page runs, on categories, products, mass attribute updates, custom variables, configuration and admin order creation
- Scoped report screens – reports and the dashboard bestsellers tab cover granted store views only, including when no store filter is set
- Per-role Attribute Permissions – hide product and category attributes and attribute groups, in Deny mode (hide the selected) or Allow mode (show only the selected), per entity
- Server-side enforcement – hidden product attributes are stripped from the save request, not just hidden in the form
- Hiding a required field does not break saving (stored values are preserved)
- Covers extension-added attributes automatically; the Administrator role always sees every field
- Per-role website and store-view scoping via a Store Scope tab on each admin role; ticking a website automatically grants all of its store views
- Zero-trust default – new roles are restricted until explicitly granted
- "Allow access to ALL" toggle to opt a role out of scoping; the built-in Administrator role stays unrestricted automatically
- Enforcement across Orders, Invoices, Shipments, Credit Memos, Customers and Products
- Grid and mass-action filtering – out-of-scope records never appear in admin grids, and no bulk action can reach them
- Single-entity 404 gate – direct URLs to out-of-scope entities are rejected
- Dedicated ACL resource controlling who may edit a role's scope
- Customizable out-of-scope message shown to restricted admins
- Health-check CLI command reporting per-role scope status
- Read API for other modules that must honour the same scope
- Cascade cleanup – scope rows are removed when a role is deleted
Versions
Store scope now covers the whole admin, not only the record grids: categories, the store switcher, the store a write is addressed to, and the report screens.
Show details Hide details
Added
- Category scope. Categories are scoped per role across every admin surface that lists them – the Catalog → Categories tree, the product form's category picker, the new-category dialog, autocomplete, the widget chooser and global search. A role sees the category trees belonging to the store views it was granted, and nothing else. Categories carry no store column in Magento, so the scope is derived from the root category of each granted store view.
- Category write protection. A restricted admin can no longer open, save, move or delete a category outside their scope by pasting a link – the request is refused before it reaches the category, and so is creating or moving a category into one. Categories that appear only so the tree can render are visible but never editable.
- Store switcher filtering. Every admin screen with a store switcher – 20 of them, from the dashboard to product edit to system configuration – now offers only the store views the role was granted. Websites and store groups whose store views are all out of scope disappear from the control entirely.
- Store context validation. The store a request is addressed to is checked against the role's grants before the page runs, on categories, products, mass attribute updates, custom variables, system configuration and admin order creation. Together with the filtered switcher this means the control never offers what the server would refuse.
- Report scope. The 15 admin report screens that carry a store switcher – the seven sales reports, ordered products, viewed products, customer reports, abandoned carts and the rest – now report on granted store views only. Leaving the store filter empty previously meant all stores; for a restricted role it now means all granted stores. The dashboard's Bestsellers tab is scoped the same way.
Fixed
- Admin global search no longer discloses out-of-scope orders. A restricted admin searching in the admin header could receive order numbers – and the customer names carried in the result text – for orders belonging to store views outside their scope. Order contents were never exposed, and opening one always answered "not found"; what leaked was the existence of the order, its identifier and the customer name. Searching now returns granted store views only.
- Opening Catalog → Categories without choosing a category used to land a restricted admin on the default store's root category, which may sit outside their scope. It now opens their own granted root instead.
- The Ordered Products report returned an error for restricted admins. The report failed with a database error rather than rendering. It now renders, scoped to the role.
- Changing a role's grants takes effect immediately in the product form's category picker. The picker previously kept serving the tree built from the role's previous grants until an unrelated category was saved or the block cache was flushed by hand.
Upgrade notes
- The three behaviours below are properties of Magento's own scope model rather than limits of this extension; the User Guide documents each one with what to do instead.
- A value saved at a broader scope – the "All Store Views" default, or a website or store group containing a granted store view – reaches store views the role was not granted, unless those store views override it. This is Magento's scope fallback. Where a role must be fenced out of a store view's values entirely, make sure that store view overrides them.
- The Low Stock and Downloads reports carry no store-scoped data to filter: their rows are catalogue-wide stock levels and globally summed download counts. Their store switcher is filtered, their data is not store-specific to begin with.
- If your deployment enables Magento's asynchronous configuration saving
(the
config/asyncdeployment flag, off by default), system-configuration saves are queued before the store check runs. Every other screen, and the filtered switcher on all of them, is unaffected.
FAQ
Adobe Commerce scopes admin roles to websites and store views. Magento Open Source does not: a role is a list of admin resources, with no notion of which website, store view or category it may act on. So a store with more than one market closes the gap by agreement – this person only touches that store view – and the agreement holds until someone is in a hurry.
This extension turns the agreement into a rule the server applies. A role is given a scope, and everything downstream respects it: grids, mass actions, direct URLs, the store switcher, reports and the dashboard. What stops being manual is the supervision.
- You run more than one website or store view on Magento Open Source. This is the case the extension exists for.
- People outside your company have admin access. An agency, a contractor, a supplier's merchandiser. Scoping is what makes that a bounded decision.
- A role should edit products but not prices. Per-role Attribute Permissions hide fields and attribute groups, and the hiding is enforced on save, not only in the form.
- A team owns part of the catalogue. Category scope covers the tree, the product form's picker, the new-category dialog, autocomplete, the widget chooser and admin global search.
- You need the configuration to be auditable. A health-check command reports each role's scope from the command line, and a read API lets your own code honour the same scope.
- You need to know who changed what. That is an audit log, and this is not one – it governs reach, and records nothing about actions. Admin Activity Audit Log is the product for that question and is sold separately.
- You are on Adobe Commerce and already use its role scopes. The platform covers websites and store views natively there; this extension installs and works, but it earns its price on Open Source. Its category and attribute scoping are the parts that still add something.
- You want the cheapest scoping available. On the Adobe Commerce Marketplace, MageAnts listed USD 69 one-time on the Open Source tier when we read it on 2026-09-03, and its feature list covers website, store view and category scoping too. AITOC is USD 185 one-time on every edition (read 2026-10-08). If server-side enforcement is not the thing you are buying, MageAnts is the honest answer.
- You need SSO, two-factor policy or user provisioning. Different products.
- Per-role website and store-view scoping, on a Store Scope tab on the admin role form. Ticking a website grants all of its store views. New roles start restricted; an "Allow access to ALL" toggle opts a role out; the built-in Administrator role stays unrestricted automatically.
- Enforcement across Orders, Invoices, Shipments, Credit Memos, Customers and Products – out-of-scope records never appear in grids, no mass action can reach them, and a direct URL to one returns 404.
- A filtered store switcher on every screen that renders it, and store-context validation before a page runs: categories, products, mass attribute updates, custom variables, configuration and admin order creation.
- Scoped reports – reports and the dashboard's bestsellers tab cover granted store views only, including when no store filter is set.
- Per-role category scope – the tree, the product-form picker, the new-category dialog, autocomplete, the widget chooser and global search show granted trees only. Creating, saving, moving or deleting a category outside the scope is refused, including moving an outside one in.
- Per-role Attribute Permissions – hide product and category attributes and attribute groups, in Deny mode (hide the selected) or Allow mode (show only the selected), per entity. Attributes added by other extensions are covered automatically. Hiding a required field does not break saving, because stored values are preserved.
- Server-side enforcement – hidden product attributes are stripped from the save request rather than merely omitted from the form.
- Nine ACL resources, including a dedicated one controlling who may edit a role's scope, so widening your own access is itself a permission.
- A health-check CLI command reporting per-role scope status, a read API for other modules, a customisable out-of-scope message, and cascade cleanup so a deleted role leaves no scope rows behind.
- It does not log anything. No record of who changed what, when, or from where. If that is the requirement, buy an audit-log extension – ours is Admin Activity Audit Log – and treat the two as complementary rather than overlapping.
- It does not scope the command line, cron or data imports. Those paths run without an admin session, so there is no role to apply. A CLI import can write anything, by design of the platform, and this extension does not change that.
- It does not scope the REST or GraphQL APIs. Enforcement is on admin requests.
- It does not touch the storefront. No theme markup, no customer-facing behaviour, nothing rendered outside the admin panel.
- It does not do SSO, two-factor policy, password rules or user provisioning. It scopes roles that already exist.
- It does not scope every third-party admin screen automatically. Grids, mass actions, URLs and the store switcher are covered through the platform's own mechanisms, and an extension that queries the database directly, outside those mechanisms, is outside the reach of any scoping extension including this one. The read API exists so such a module can opt in.
- It adds six database tables, and no core table is modified. Uninstalling removes the extension's own data and nothing else.