How to restrict access to menu items in the WordPress admin

Recently I needed to restrict access to specific features in the WordPress admin. There are lots of ways to do this, but I needed a specific combination of restrictions that isn’t very common. I needed something akin to a site manager role, without full administration rights. My requirements were:

  • Access to all the features under the Settings menu
  • Ability to activate and deactivate existing plugins, but not install new plugins
  • Ability to manage features of the existing theme, without being able to install new themes
  • Deny access to create, edit, or delete user accounts
  • Deny access to create, edit, or delete any roles

There isn’t a built-in role in WordPress that matches these requirements. The closest thing is an Editor, but it’s really not even close. Editors lack the ability to manage settings, themes, and plugins. I could have customized the capabilities of the Editor role, but that would have affected all users with the role. What I needed was a new role with this particular set of capabilities. Here’s how I did that.

The Members Plugin

I’ve been using the Members plugin by Justin Tadlock for years. It’s beautifully simple, and it just works. The user interface is very simple and it has a lot of power under the hood. About a month and a half ago, Members received a major update that significantly improved the plugin. These major improvements made it even easier to manage custom roles. I knew it was the right tool for this job.

Roles and Capabilities

First, I created a new role called Manager so I could assign it the specific set of capabilities I needed. Adding a new role is easy. Go to Users > Roles and click Add New. Alternatively, you can clone the Administrator role (since it has all permissions already assigned), and then deny the capabilities you don’t want the Manager to have.

Second, I needed to ensure the role’s capabilities met my requirements. Here are some screenshots of the way I configured the capabilities for this new role:

Third, I needed to restrict the user’s ability to manage the Members plugin settings. As you can see in the screenshot above, the new Manager role has the manage_options capability. This is so the user can manage all the options in the Settings menu. By default, Members allows a user to manage the plugin’s settings if the user has the manage_options capability. I didn’t want this.

Fortunately, Members has a filter that lets you control the capability required to manage its settings. That filter is called members_settings_capability. All I needed to do was change that capability with this filter, and the user would no longer have access to the Members plugin settings. But, if you noticed in my requirements, I wanted to allow the user the ability to deactivate existing plugins. This means I couldn’t use this filter in a regular plugin because it would allow the user to disable the plugin and subsequently access the settings. That’s where the Must Use Plugins concept comes into play. If you’re not familiar with Must Use Plugins, or mu-plugins as they’re called, you can read all about that on the link above. I’ll quickly say that mu-plugins are special plugins, manually installed in a special folder, that cannot be edited or disabled in the WordPress admin.

To change the capability required to manage the Members plugin settings, here’s the mu-plugin code I used to change the capability to administrator:

function jp_filter_members_settings_cap() {
	return 'administrator';
add_filter( 'members_settings_capability', 'jp_filter_members_settings_cap' );

Now, you may be thinking that a clever user could edit an existing plugin and override this filter. But, that’s not possible. First, the assigned capabilities don’t allow it. Second, I had already disabled the plugin and theme editor capabilities on the site. This was done by adding the following line of code to the wp-config.php file:

define( 'DISALLOW_FILE_EDIT', true );

You can read more about disabling the plugin and theme editor here.

Assigning the User Role

Now I just needed to assign the user’s account to the new Manager role and give it a test to make sure I hadn’t forgotten or overlooked anything. To do that, I edited the user account in question, and assigned the role I just created.

Assigning the user role

Assigning the user role

To do the testing, I installed the handy User Switching plugin. With that in place, I easily switched over to the user’s account and confirmed that my new role was properly configured. Everything worked exactly the way I needed. And with that, I was done.

If you’d like to read up on the WordPress roles and capabilities, you can do so here. If you’ve handled similar situations with different solutions, please feel free to share those in the comments.

Alien doesn't want to hear the paint sniffers

Paint sniffers

A depiction of how I feel sometimes. Often. Depends on the moon phase I guess.

Working with Mike at Array, we sometimes joke about “paint sniffers”. You’d have to be there. Anyway, Mike turned 30 this year and wanted a new telescope. I donated to the cause. In return, Mike made good on his promise to deliver a hand-drawn celestial object. Well done, sir.

Nanu nanu.

Lemon on the beach