The role hierarchy lets you define which roles are included in other roles, so you don't have to assign all of them to each user. In applications with many roles, this configuration grows quickly and it's hard to tell which exact roles belong to a given user. Symfony 8.2 makes role hierarchies shorter to write and easier to debug.

Wildcards in the Role Hierarchy

Nicolas Rigaud
Contributed by Nicolas Rigaud in #52099

Role hierarchies list their roles one by one. If your application defines e.g. ROLE_BLOG_AUTHOR, ROLE_BLOG_EDITOR and ROLE_BLOG_MODERATOR, and all of them should include ROLE_BLOG_READER, you need one entry for each of them, plus another one whenever you add a new blog role.

In Symfony 8.2, the keys of the role hierarchy can include the * wildcard to match an entire family of roles:

1
2
3
4
5
6
7
8
9
# config/packages/security.yaml
security:
    # ...

    role_hierarchy:
        ROLE_*:              ROLE_USER
        ROLE_*_MODERATOR:    ROLE_MODERATOR
        ROLE_BLOG_*:         ROLE_BLOG_READER
        ROLE_BLOG_MODERATOR: [ROLE_BLOG_DELETE_POST, ROLE_BLOG_LOCK_POST]

Roles don't need to be listed in the hierarchy to match a wildcard. With this configuration, a user with ROLE_BLOG_COMMENTER also gets ROLE_BLOG_READER and ROLE_USER, even if that role doesn't appear anywhere in the configuration.

The * character is only considered a wildcard when it's wrapped by underscores (ROLE_*_FOO) or placed after an underscore at the end of the role name (ROLE_BAR_*). Keys such as ROLE_BLOG* or ROLE_*BLOG are still regular role names.

Wildcards are patterns, not roles, so you can only use them in the keys of the hierarchy. For example, is_granted('ROLE_BLOG_*') still looks for a role with that exact name and wildcards are never returned by the getReachableRoleNames() and getParentRoleNames() methods.

The debug:roles Command

Nicolas Rigaud
Contributed by Nicolas Rigaud in #65345

Wildcards simplifies role configuration but can make debugging a bit more difficult. If you need to know the exact roles granted to a user, Symfony 8.2 adds a debug:roles command that does that for you:

1
2
3
4
5
6
7
8
9
10
11
12
# displays the whole role hierarchy
$ php bin/console debug:roles

# displays all the roles granted by the given role(s)
$ php bin/console debug:roles ROLE_BLOG_MODERATOR

 * ROLE_BLOG_MODERATOR
 * ROLE_BLOG_DELETE_POST
 * ROLE_BLOG_LOCK_POST
 * ROLE_USER
 * ROLE_MODERATOR
 * ROLE_BLOG_READER

Add the --tree option to see why each role is granted, including the wildcards that were matched:

1
2
3
4
5
6
7
8
9
10
11
$ php bin/console debug:roles ROLE_BLOG_MODERATOR --tree

ROLE_BLOG_MODERATOR
├── ROLE_*
│   └── ROLE_USER
├── ROLE_*_MODERATOR
│   └── ROLE_MODERATOR
├── ROLE_BLOG_*
│   └── ROLE_BLOG_READER
├── ROLE_BLOG_DELETE_POST
└── ROLE_BLOG_LOCK_POST

Role Hierarchy Graph in the Profiler

Damien Fernandes
Contributed by Damien Fernandes in #61786

Symfony 7.4 introduced the debug:security:role-hierarchy command to dump the role hierarchy as a Mermaid chart. In Symfony 8.2, that chart is displayed directly in the Security panel of the profiler, so you can check the roles available in your application without running any command:

Symfony 8.2 profiler showing the role hierarchy graph in the Security panel
Published in #Living on the edge