Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

ACL in Detail: Assigning Granular Permissions for Grid, Form, and Delete Separately

ACL in Detail: Assigning Granular Permissions for Grid, Form, and Delete Separately

~9 Min. Lesezeit Zuletzt aktualisiert am August 9, 2026

Since chapter 14, the testimonial module has used a single ACL node Mironsoft_Testimonial::testimonial for everything - grid, form, delete. Chapter 17 already got ahead of itself with Mironsoft_Testimonial::delete. This chapter builds out the full, granular ACL structure that chapter 3 previewed.

Why a single node isn't enough

In practice, there are often roles that should be able to view testimonials but not delete them - a support agent, for example, who should be able to review submitted testimonials but not permanently remove them. With a single ACL node, that separation is technically impossible: whoever has access has access to everything hanging off that node.

The complete ACL tree structure

app/code/Mironsoft/Testimonial/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">
                <resource id="Magento_Backend::content">
                    <resource id="Mironsoft_Testimonial::testimonial"
                              title="Testimonials" sortOrder="50">
                        <resource id="Mironsoft_Testimonial::save"
                                  title="Create/Edit Testimonials" sortOrder="10"/>
                        <resource id="Mironsoft_Testimonial::delete"
                                  title="Delete Testimonials" sortOrder="20"/>
                    </resource>
                </resource>
            </resource>
        </resources>
    </acl>
</config>

::testimonial stays the top node (menu item and grid view), ::save and ::delete hang below it as their own child resources. Worth remembering from chapter 3: whoever has access to ::testimonial automatically sees the menu item and the grid - ::save/::delete additionally control whether the form and delete are reachable, not instead of ::testimonial.

Mapping controllers to the right resource

  • Index (grid), Edit, Upload - read-oriented, so Mironsoft_Testimonial::testimonial.
  • Save, InlineEdit, Duplicate - write-oriented, so Mironsoft_Testimonial::save.
  • Delete, MassDelete - destructive, so Mironsoft_Testimonial::delete.
  • MassStatus - a change in substance, so also Mironsoft_Testimonial::save, not ::delete.

Achtung: A simple but consequential mistake: Upload (chapter 16) should point at ::save, not ::testimonial - otherwise a read-only role could still upload files to the server, since the upload endpoint technically has nothing to do with the actual save and is easy to overlook.

ACL inheritance, once more, concretely

As mentioned in chapter 3, permissions inherit downward: a role with access to Magento_Backend::content automatically also has access to Mironsoft_Testimonial::testimonial and all its children, even without an explicit checkbox for "Testimonials" in the role editor. Anyone building a restricted role must therefore not grant blanket access at a parent node, but instead deliberately enable individual leaves of the tree.

Verifying ACL in tests and review

Tipp: A pragmatic test after every ACL change: create a new test role with exactly one of the three resources, assign a test user, and deliberately try in the admin area whether exactly the expected (and only the expected) actions are possible. ACL bugs don't show up in normal day-to-day development with an administrator role, since that role can do everything anyway.

With this granular structure, the testimonial module is ready for different roles on a team - chapter 26 now switches to concrete troubleshooting.