Skip to content
ThemesIonic — home
WordPress Tutorials

WordPress User Roles and Capabilities Explained

Roles are named bundles of capabilities, stored per user in the database. Understand the six defaults, then add or restrict capabilities without handing out administrator access.

1 min read intermediate

The short version: WordPress ships six roles. Give everyone the least powerful one that lets them do their job, and reserve administrator for people who genuinely administer the site. Most "we need an admin account" requests are actually editor-shaped.

The default roles

Role Can do Cannot do
Administrator Everything, including plugins, themes, users and settings Nothing (on multisite, network-level actions)
Editor Publish and edit anyone's posts and pages, moderate comments Install plugins, change settings, manage users
Author Publish and manage their own posts, upload media Touch other people's content
Contributor Write and edit their own drafts Publish, or upload media
Subscriber Manage their own profile Create content
Super Admin Multisite only: manage every site in the network

Two surprises worth knowing:

  • Contributors cannot upload images. This is the most common complaint about the role and the reason many sites promote writers to author.
  • Editors can edit other users' published posts. That is exactly the point, but it takes people by surprise on a shared blog.

How capabilities actually work

A capability is a single string permission — edit_posts, manage_options, install_plugins. Roles map names to sets of them.

Check capabilities, never roles, in code:

<?php
// Correct: works for custom roles and modified permissions.
if (current_user_can('edit_others_posts')) {
    // show the tool
}

// Fragile: breaks the moment someone creates a similar role.
if (in_array('editor', wp_get_current_user()->roles, true)) {
    // ...
}

Some capabilities are meta capabilities resolved per object. edit_post with a post ID maps to edit_posts, edit_others_posts or edit_published_posts depending on who owns the post and its status. That mapping is why passing the object ID matters:

<?php
if (current_user_can('edit_post', $post_id)) {
    // ...
}

Where roles are stored

Two places:

  • Definitions — a single serialised row in wp_options with the key wp_user_roles (prefixed to match your install). It holds every role and its capabilities.
  • Assignments — each user's wp_capabilities value in wp_usermeta, a serialised array such as a:1:{s:6:"editor";b:1;}.

Two practical consequences. Changing a role's capabilities in code writes to the options row permanently, so a snippet that runs on every page load is both wasteful and hard to undo. And a user whose wp_capabilities meta is missing has no permissions at all, even though the account exists — the fix is in adding an admin user via phpMyAdmin.

Modify permissions without a new role

To let editors manage a plugin's settings, or stop authors deleting published posts, add or remove single capabilities. Do it once, on activation, not on every request:

<?php
// In a small custom plugin, on activation.
register_activation_hook(__FILE__, function () {
    $editor = get_role('editor');
    $editor?->add_cap('edit_theme_options');   // access to menus and widgets
});

register_deactivation_hook(__FILE__, function () {
    get_role('editor')?->remove_cap('edit_theme_options');
});

Removing on deactivation matters. Because the change is stored in the database, a capability granted by a plugin outlives the plugin unless it is cleaned up.

Create a custom role

<?php
register_activation_hook(__FILE__, function () {
    add_role('shop_editor', 'Shop Editor', [
        'read'                   => true,
        'edit_posts'             => true,
        'edit_others_posts'      => true,
        'edit_published_posts'   => true,
        'publish_posts'          => true,
        'upload_files'           => true,
        'edit_products'          => true,
        'edit_others_products'   => true,
        'delete_posts'           => false,
    ]);
});

Start from an existing role's capability list rather than inventing one — get_role('editor')->capabilities gives you the array to copy and adjust. A role missing read cannot access the admin at all, which is a classic mistake.

If you would rather not write code, a role editor plugin does the same thing with a checkbox interface. It writes to the same options row, so the two approaches are interchangeable.

Assign roles safely

  • Give contributors and authors the minimum they need, and grant upload_files explicitly if contributors must add images.
  • Do not create second administrator accounts for convenience. Every administrator is a full compromise if their password leaks.
  • Audit Users periodically and remove accounts for people who have left.
  • Delete rather than demote unknown accounts, after checking whether they indicate a breach — see how to fix a hacked WordPress site.
  • When deleting a user, reassign their content instead of deleting it, unless you genuinely want the posts gone.

Roles added by plugins

WooCommerce adds Customer and Shop Manager; membership and LMS plugins add their own. Two things to expect:

  • These roles persist after the plugin is removed, because they live in the options row. Cleaning up is part of deleting a plugin completely.
  • Shop Manager is powerful — it can manage orders and customer data. Treat it with the same care as an editor account handling personal information.

Frequently asked

A capability is a single permission such as edit_posts. A role is a named set of capabilities. WordPress checks capabilities, not roles, which is why current_user_can() is the correct way to gate anything.
The definitions live in a single wp_options row called wp_user_roles, and each user's assigned role is in their wp_capabilities meta value.
Yes. add_role() on a WP_User object adds a second role, and the user gets the union of both capability sets. WooCommerce and membership plugins rely on this.
Tagged Security

Related guides