WordPress access control for users with multiple roles

Advanced Access Manager supports multiple roles per user with version 5.5.0 or higher. Prior to 5.5.0, AAM was taking in consideration only the first user’s role and ignored others. By default, the multiple roles support is disabled and you can enable it on the AAM Settings Area with Multiple Roles Support option.


For the longest time we’ve been opposed to the idea of multiple roles per user as this causes a lot of conflicts with access settings and properties. For example if Role X has access to Post A, however Role Y does not, then what should we do with a user that has both roles? Shall we grand access to Post A or restrict? Depending on the website requirements we might want to grand access to restricted resource if any role allows it; and on other website we definitely want to restrict access to protected resource when any role states so.

This type of access ambiguity was the main reason why we were against multiple roles implementation. However, market demanded otherwise and we’ve been getting more and more requests to add multiple roles support. So, finally, after many hours or refactoring, project planning and testing, this feature was implemented in AAM 5.5.0.

What is “multi-roles”?

Generally speaking, multiple roles per user is when some active account has two or more existing roles assigned to it. The emphasis here is on existing roles because through many years supporting other projects we’ve seen guzzilian times user accounts that had corrupted data in the usermeta; and this was misleading developers.

FYI! When WordPress core initiates user account, it fetches list of capabilities from the user meta table and evaluates them through the WP_Roles::is_role method. This way any none-existing roles are treated as capabilities and not as roles.

Taking in consideration the fact that the WordPress website is a big collection of resources, (e.g. posts, pages, menus, widgets, physical files) and depending on the website’s purpose, some resources might have different “weight” or level or importance.

For instance, you want to be absolutely sure that if any role restricts access to the Backend Menu Settings, then this rule has to be enforced; however for Metaboxes & Widgets you want to have less restrictive approach. In this case you have the opportunity to define how access settings are going to be merged for each individual resource type.

How does AAM merges access settings

To keep it all backward compatible, if any of the roles restrict access to certain resource, then AAM will honor this preference, however, you have the ability to override this behavior with few simple ConfigPress settings. Because you might want to have different preferences based on the type of a resource (post, term, menu, metabox etc), you have to explicitly define them for each resource type as following:

; Preference value can be "allow" or "deny"
; The "allow" means that AAM will allow access to resource if any role allows it
; The "deny" means that AAM will deny access to resource if any role restricts it

; Manage access preference to the Backend Menu
core.settings.menu.merge.preference = "allow"
; Manage access preference to the Top Admin Toolbar
core.settings.toolbar.merge.preference = "allow"
; Manage access preference to the Metaboxes & Widgets
core.settings.metabox.merge.preference = "allow"
; Manage access preference to posts, pages, media and any custom post type
core.settings.post.merge.preference = "allow"
; Manage access preference to hierarchical terms (categories)
core.settings.term.merge.preference = "allow"
; Manage access preference to any post type like Posts, Pages, Products etc
core.settings.type.merge.preference = "allow"
; Manage access preference to any taxonomy object
core.settings.taxonomy.merge.preference = "allow"
; Manage access preference to URI Access
core.settings.uri.merge.preference = "allow"

Note! There are several access settings that are not merged due to its nature and these settings are: Login Redirect, Logout Redirect and Access Denied Redirect. The first role in the list of user’s roles is taken in consideration.

Get notified about important updates and new features (no more than one email per month).