Index Logo

Handling Permissions in your WordPress REST routes

In our previous walkthroughs on register_rest_route we added this line of code to our registration function:

'permission_callback' => '__return_true'

This was to prevent permissions issues for our sandbox code, but in a production environment you would only use this for fully public API endpoints, and never for endpoints related to a user.

Note: if you are building a public API then the above is what you should use.

Handling permissions in your routes

Just like validating user input for your route, the permissions callback is a function where you return either true, false, or a WP_Error instance:

register_rest_route(
	'ndx/v1',
	'my-endpoint/(?P<id>[a-zA-Z0-9_-]+)',
	array(
		array(
			// ... other arguments stripped for readability
			'permission_callback' => function($request) {
				// ... permissions check goes here
			},
		)
	)
);

The permissions callback is run after the current user is set, which would be either the matching user in the dashboard or an authenticated user you passed in your request. As this is WordPress, our permissions checks will use functions provided by WordPress, mainly current_user_can.

The callback also receives the entire request so you can perform conditional logic depending on the data passed in.

How to check user capabilities in WordPress

WordPress uses a roles and capabilities system to handle what a user is allowed to do. A role is basically a set of capabilities that you can quickly assign to users. Examples of built-in roles are administrator, author, editor, and subscriber.

A capability is a singular action a user is either allowed or not allowed to do. The system is additive, so if the user has the capability it means they can do the specified action (ie: don’t create capabilities like cannot_do_action.

The quickest way to verify a user can do something is by using the current_user_can function. This function takes a string that matches a capability and returns true or false:

return current_user_can('edit_posts'); // true or false

There are a lot of different capabilities built-in to WordPress, and you can add custom ones as well. We won’t go through the list, but you can view the list here https://wordpress.org/support/article/roles-and-capabilities/#capabilities

Performing a permissions check

Let’s go back to our rest route and add a permissions check. Let’s say theoretically that our route was to update global settings for the WordPress installation. We’ll use the built-in manage_options capability, which allows users to access and update all of the settings in the dashboard:

register_rest_route(
	'ndx/v1',
	'my-endpoint/(?P<id>[a-zA-Z0-9_-]+)',
	array(
		array(
			'permission_callback' => function($request) {
				return current_user_can('manage_options');
			},
		)
	)
);

Wrap Up

This was a short walkthrough, but that’s because creating permissions is pretty simple! It really just depends on how you design your user system and security levels (fortunately WordPress provides a lot of this up front for whats included out of the box). I would recommend looking closely at the capabilities provided. We’ll also go through creating capabilities and recommended plugins for more advanced patters like policies in the future.

Get started for free

Try Index free for 14 days and see for yourself why it's the best interface for managing your WordPress content — no credit card required.

Start your free trial