Controlling WordPress Admin Page Visibility by Role is not simply a matter of hiding menu items from users who should not see them. A reliable WordPress admin access strategy must distinguish between interface visibility and actual authorization.
That distinction matters because these two situations are fundamentally different:
User cannot see an admin menu item
≠
User cannot access the underlying admin functionality
Removing a page from the WordPress admin menu can make the dashboard cleaner.
It does not automatically make the page inaccessible.
A user may still reach functionality through:
- a direct
wp-adminURL; - another admin page;
- a bookmarked URL;
- an AJAX request;
- a REST API endpoint;
- a form submission;
- custom plugin code.
The correct model is therefore:
Admin visibility
+
Capability checks
+
Server-side authorization
=
Controlled WordPress admin access
This guide explains how WordPress determines access to administrative pages, how roles and capabilities interact, how to hide pages safely, how to protect custom admin pages and how to build different backend experiences for administrators, editors, authors, clients and other users.
WordPress roles and capabilities are not the same thing
Before controlling admin pages, it is important to understand the distinction between roles and capabilities.
A role is a named collection of permissions.
Default WordPress roles include:
- Administrator;
- Editor;
- Author;
- Contributor;
- Subscriber.
A capability represents a specific permission.
Examples include:
edit_posts
publish_posts
edit_pages
manage_options
install_plugins
edit_users
A useful mental model is:
Role
↓
contains capabilities
↓
capabilities determine what the user can do
For a deeper explanation of the underlying permission model, see WordPress User Roles and Capabilities Explained.
Prefer capabilities over checking role names directly
When controlling access programmatically, WordPress generally expects developers to ask whether a user has the required capability rather than whether the user has a particular role name.
For example:
if ( current_user_can( 'manage_options' ) ) {
// Allow the administrative action.
}
is generally more flexible than:
$user = wp_get_current_user();
if ( in_array( 'administrator', $user->roles, true ) ) {
// Allow the administrative action.
}
The official WordPress documentation for current_user_can() specifically recommends capability checks rather than checking roles directly.
Why capability checks are more flexible
Suppose a custom administration page requires the ability to manage a specific workflow.
If access is hard-coded to:
administrator
then only users carrying that exact role qualify.
But later you may create:
Site Manager
SEO Manager
Content Manager
and want one of those roles to access the same page.
A capability-based architecture lets you grant the required permission without pretending every privileged user must be an Administrator.
This is particularly useful when building custom roles. See Creating a Custom WordPress Role Safely for the wider process.
Role-based visibility still has a place
Roles remain useful when designing user experiences.
You may reasonably decide that:
Administrators
→ full administrative interface
Editors
→ editorial tools
Authors
→ personal content tools
Clients
→ selected reports and settings
The important distinction is that role-based interface design should eventually resolve to appropriate capabilities when authorization is enforced.
Visibility and authorization solve different problems
Consider an Editor who does not need to see the Plugins menu.
There are two separate questions:
Should the Plugins menu appear?
Can the user perform plugin administration?
The first is an interface question.
The second is an authorization question.
WordPress capabilities should answer the second question.
Hiding an admin menu item is not access control
This is one of the most important principles in WordPress admin customization.
Suppose you remove an item:
Dashboard
Posts
Media
Pages
Comments
Appearance
Plugins
Users
Tools
Settings
so that a particular user sees:
Dashboard
Posts
Media
Pages
The simplified menu may be useful.
But removing:
Tools
from the sidebar does not automatically prove that every Tools-related endpoint is inaccessible.
The underlying authorization still needs to be correct.
This distinction is covered more broadly in How to Hide WordPress Admin Menu Items by Role.
Why CSS hiding is even weaker
A CSS rule such as:
#menu-tools {
display: none;
}
only changes presentation.
The menu element can still:
- exist in the HTML;
- be revealed through browser developer tools;
- be ignored by direct navigation;
- have no effect on the underlying permissions.
CSS can be useful for visual customization.
It should not be treated as an authorization mechanism.
How WordPress protects registered admin pages
When a plugin registers an admin page using functions such as:
add_menu_page()
add_submenu_page()
it supplies a required capability.
A basic custom page might look like:
add_action( 'admin_menu', 'example_register_admin_page' );
function example_register_admin_page() {
add_menu_page(
'Company Reports',
'Reports',
'manage_options',
'company-reports',
'example_render_reports_page'
);
}
The manage_options argument is significant.
It tells WordPress which capability is required for the menu page.
The official add_menu_page() documentation explains that the supplied capability determines whether the page is included in the menu for the current user.
Protect the page callback as well
The page callback should also be written defensively.
function example_render_reports_page() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_die(
esc_html__( 'You are not allowed to access this page.', 'example' )
);
}
echo '<div class="wrap">';
echo '<h1>Company Reports</h1>';
echo '</div>';
}
The official documentation for wp_die() describes the WordPress function used when execution should stop and an error response should be displayed.
Why repeat the capability check?
Authorization should remain close to the sensitive operation.
This makes the security requirement explicit:
Page registration
→ capability requirement
Page callback
→ capability verification
Sensitive action
→ capability verification
The interface becomes one layer of the permission system rather than the only layer.
Custom admin pages should declare their permissions deliberately
If you create custom administrative interfaces, decide which capability each page genuinely requires.
For example:
Editorial overview
→ edit_posts
Page management tool
→ edit_pages
Site-wide configuration
→ manage_options
A custom business workflow may justify a dedicated capability instead of reusing a broad Core capability.
For the page-building process itself, see How to Add a Custom Admin Page in WordPress.
Do not use manage_options for everything
manage_options is commonly associated with high-level site configuration.
It is convenient, but convenience is not always the correct permission model.
If a custom page only manages editorial notes, requiring broad administrative privileges may be unnecessary.
Conversely, lowering a sensitive settings page to edit_posts merely so Editors can see it can expose functionality too broadly.
The required capability should match the operation being performed.
Create dedicated capabilities for specialized admin pages
For custom applications, a dedicated capability can make the access model clearer.
For example:
view_company_reports
manage_company_reports
export_company_reports
You can then assign those permissions to whichever roles require them.
This creates a model such as:
Administrator
→ view
→ manage
→ export
Manager
→ view
→ export
Editor
→ no access
rather than forcing unrelated WordPress capabilities to represent application-specific responsibilities.
Role Manager can support custom permission structures
TheOneWP’s Role Manager can help manage WordPress roles and capabilities when the default role structure does not match the site’s operational requirements.
This is particularly useful when custom administrative pages should be available to specific staff groups without granting them unnecessary Administrator-level permissions.
The principle of least privilege
A useful permissions model follows a simple rule:
Give users the permissions they need
to perform their responsibilities
but not unrelated permissions
they do not need.
For example, somebody responsible for publishing articles may need:
- content editing;
- media access;
- publishing;
- editorial tools.
They may not need:
- plugin installation;
- theme editing;
- site-wide configuration;
- user administration;
- database tools.
For the broader architecture, see Restricting WordPress Features by User Role.
Design the WordPress admin around responsibilities
Instead of asking:
What can we hide from Editors?
start with:
What does an Editor actually need
to complete their work?
This changes admin customization from subtraction to intentional interface design.
For example:
EDITOR WORKSPACE
Dashboard
Posts
Media
Pages
Editorial Notes
CLIENT WORKSPACE
Dashboard
Reports
Profile
ADMINISTRATOR WORKSPACE
Full administration
The result is easier to reason about and easier to audit.
Use admin_menu for menu customization
WordPress administrative menu registration and modification normally takes place through the admin_menu hook.
For example:
add_action( 'admin_menu', 'example_customize_admin_menu', 999 );
function example_customize_admin_menu() {
if ( ! current_user_can( 'manage_options' ) ) {
remove_menu_page( 'tools.php' );
}
}
The menu modification changes what appears in the interface.
The user’s capabilities remain responsible for what the user can actually do.
Removing a menu page
WordPress provides remove_menu_page() for removing top-level admin menu entries.
For example:
add_action( 'admin_menu', 'example_remove_tools_menu', 999 );
function example_remove_tools_menu() {
if ( ! current_user_can( 'manage_options' ) ) {
remove_menu_page( 'tools.php' );
}
}
The official remove_menu_page() documentation covers the function used to remove top-level menu pages.
Removing submenu pages
WordPress also provides remove_submenu_page().
A simplified example is:
add_action( 'admin_menu', 'example_customize_settings_menu', 999 );
function example_customize_settings_menu() {
if ( ! current_user_can( 'manage_options' ) ) {
remove_submenu_page(
'options-general.php',
'options-writing.php'
);
}
}
Again, menu removal is primarily interface customization.
It should not replace authorization.
Menu visibility can improve usability
There is still significant value in hiding unnecessary administrative pages.
A smaller menu can:
- reduce navigation complexity;
- make common actions easier to find;
- reduce accidental interaction with irrelevant settings;
- make client dashboards easier to understand;
- create clearer role-specific workflows.
TheOneWP’s Admin Menu Organizer can help reorganize the WordPress administration menu as part of a more deliberate backend structure.
Admin Menu Organizer and permissions solve different problems
Menu organization answers:
Where should this item appear?
What should it be called?
Does the interface need this item?
Permissions answer:
Is this user authorized
to perform the underlying action?
Those systems complement each other.
They should not be confused.
How to handle plugin admin pages
Third-party plugins may register their own:
- top-level menus;
- Settings pages;
- Tools pages;
- custom post type interfaces;
- dashboard pages.
If the plugin has implemented capabilities correctly, WordPress should already restrict sensitive functionality according to those capabilities.
You may still want to remove unnecessary menu entries for specific users to simplify the interface.
Do not assume a plugin menu slug from its visible label
A menu labelled:
Analytics
might internally use a slug such as:
vendor-dashboard
plugin-reports
analytics-settings
custom-admin-page
When customizing third-party admin menus, inspect the actual registered menu structure rather than guessing the slug from the label.
Direct URL access must still be considered
Suppose a user cannot see:
Settings
→ Custom Plugin
but knows that the page exists at:
/wp-admin/admin.php?page=custom-plugin
If the page has been registered with an appropriate capability, WordPress can reject unauthorized access.
If a custom implementation relies only on hiding its menu link, direct navigation can bypass the visual restriction.
WordPress has an internal admin-page access system
WordPress tracks registered administrative pages and their required permissions.
The Core function user_can_access_admin_page() determines whether the current user can access the current administrative page.
Plugin and application code should still use explicit capability checks around sensitive operations rather than depending on interface state.
Protect form handlers separately
An admin page may contain a form:
<form method="post">
...
</form>
The fact that the form appeared only on an administrator page does not mean its submission handler can skip authorization.
The handler should check the required capability again.
if ( ! current_user_can( 'manage_options' ) ) {
wp_die(
esc_html__( 'You are not allowed to perform this action.', 'example' )
);
}
Use nonces as a separate security layer
Capability checks answer:
Is this user authorized?
Nonces help answer:
Is this request associated with
the intended interaction?
A typical administrative action may therefore require both:
Capability check
+
Nonce verification
The official WordPress nonce documentation explains how nonces help protect requests against certain forms of request forgery.
A secure admin form example
function example_render_settings_page() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_die(
esc_html__( 'You are not allowed to access this page.', 'example' )
);
}
?>
<div class="wrap">
<h1>Example Settings</h1>
<form method="post" action="">
<?php
wp_nonce_field(
'example_save_settings',
'example_settings_nonce'
);
?>
<input
type="text"
name="example_value"
value=""
>
<button type="submit">
Save
</button>
</form>
</div>
<?php
}
The submission handler should then verify both authorization and request validity.
Protect AJAX endpoints independently
An admin interface may use JavaScript to trigger an AJAX action.
Hiding the page from a role does not prevent that role from attempting the AJAX request directly.
An AJAX callback should therefore contain its own authorization logic.
function example_ajax_action() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error(
array(
'message' => 'Permission denied.',
),
403
);
}
check_ajax_referer(
'example_action',
'nonce'
);
// Perform authorized action.
wp_send_json_success();
}
For WordPress AJAX fundamentals, see the official WordPress AJAX documentation.
Protect REST API endpoints too
A custom admin page may communicate with the WordPress REST API.
The page being hidden has no security effect on the API endpoint.
A custom REST route should use a proper permission_callback.
register_rest_route(
'example/v1',
'/reports',
array(
'methods' => 'GET',
'callback' => 'example_get_reports',
'permission_callback' => function () {
return current_user_can( 'view_company_reports' );
},
)
);
The official WordPress documentation for custom REST endpoints explains route registration and permission callbacks.
Visibility rules should not exist only in JavaScript
Code such as:
if ( userRole !== 'administrator' ) {
document.querySelector( '.settings-page' ).remove();
}
can alter the interface.
It cannot secure the server-side operation.
Browser-side checks can be manipulated by the user.
Authorization decisions belong on the server.
Do not rely on disabled buttons either
This:
<button disabled>Delete everything</button>
is not access control.
Neither is:
opacity: 0;
pointer-events: none;
Interface restrictions can communicate permissions to users, but the backend must independently enforce them.
Custom capabilities are useful for granular admin pages
Imagine a reporting system with three levels of access:
view_reports
export_reports
manage_report_settings
You could assign:
Administrator
→ all three
Manager
→ view_reports
→ export_reports
Editor
→ view_reports
Author
→ none
This produces more precise control than asking whether every user is an Administrator.
Custom roles can simplify recurring permission patterns
If multiple users need the same capability set, creating a dedicated role may make the model easier to manage.
For example:
Content Manager
edit_posts
edit_pages
publish_posts
upload_files
view_editorial_reports
See Custom WordPress Roles vs. Combining Existing Ones before deciding whether a new role is necessary.
Multi-role users require capability-based thinking
A WordPress user can potentially receive permissions from more than one role or through additional capability assignments.
This is another reason code such as:
if ( $role === 'editor' )
can become fragile.
The question should usually be:
Can this user perform this action?
rather than:
What label is attached to this user?
TheOneWP’s Multi Role Assignment can support users who need permission sets from multiple roles.
Role Manager and Multi Role Assignment serve different purposes
Role Manager helps define and maintain the permissions associated with roles.
Multi Role Assignment can assign multiple existing role structures to the same user.
Both can contribute to a more flexible administrative access model.
Build admin pages around custom capabilities
A scalable architecture can look like:
Custom page:
Reports
Required capability:
view_company_reports
Custom page:
Report Settings
Required capability:
manage_company_reports
Custom action:
Export CSV
Required capability:
export_company_reports
This makes the permission model explicit and auditable.
Separate viewing from modification
A common mistake is using one capability for every action on an admin page.
Consider separating:
view
edit
delete
export
configure
where the application genuinely needs those distinctions.
A manager may need to view a report without being allowed to change the reporting configuration.
Page visibility can be broader than action permission
Sometimes a page should be visible to several user groups while individual actions inside it remain restricted.
For example:
Reports page
→ visible to Editors and Administrators
Export button
→ Managers and Administrators
Configuration panel
→ Administrators only
The page can perform capability checks around individual components.
if ( current_user_can( 'export_company_reports' ) ) {
// Render export controls.
}
Do not reveal unusable controls unnecessarily
If a user cannot perform an action, hiding the corresponding control can improve usability.
The secure sequence is:
Backend permission exists
↓
Backend enforces permission
↓
Interface reflects permission
not:
Button is hidden
↓
therefore permission exists
WordPress admin page visibility for Editors
An Editor commonly needs broad content-management capabilities but not infrastructure administration.
A focused Editor interface might include:
- Dashboard;
- Posts;
- Media;
- Pages;
- Comments;
- relevant custom post types;
- editorial workflow pages.
It may omit unrelated plugin configuration and infrastructure tools.
WordPress admin page visibility for Authors
An Author typically needs a smaller interface.
A role-specific workspace might emphasize:
- their posts;
- Media Library access appropriate to the site;
- profile;
- relevant editorial tools.
Again, actual permissions should remain the source of truth.
WordPress admin page visibility for clients
Client WordPress installations often benefit from particularly deliberate administration design.
A client may need:
- content editing;
- media;
- orders;
- forms;
- reports;
- selected business settings.
They may not need to see dozens of technical plugin pages.
For a broader team-oriented approach, see Standardizing the WordPress Admin for Teams.
A focused dashboard reduces unnecessary choices
The same principle applies to dashboard widgets.
A role-specific WordPress administration experience can prioritize information relevant to each user’s responsibilities.
See Building a Focused WordPress Dashboard for Teams for the dashboard side of the problem.
Custom admin pages can provide purpose-built workspaces
Sometimes hiding existing WordPress pages is not enough.
A business workflow may be easier to operate through a custom page containing only the information and actions relevant to that workflow.
For example:
Client Dashboard
Active orders
Recent enquiries
Monthly statistics
Documentation
Support links
For implementation fundamentals, see How to Add a Custom Admin Page in WordPress.
Add custom menu entries deliberately
When building a custom admin architecture, custom menu entries can connect users directly to the pages they actually need.
See How to Add Custom Admin Menu Items in WordPress for the menu-registration side of that process.
Reorganize rather than only hide
A confusing admin interface is not always solved by removing things.
Sometimes the better solution is:
- rename menu items;
- move them;
- group related functionality;
- prioritize frequent workflows;
- reduce unnecessary hierarchy.
For the wider menu architecture, see How to Reorganize the WordPress Admin Menu.
Access Manager can support broader access policies
TheOneWP’s Access Manager can support broader WordPress access-control workflows where access needs to be managed according to the site’s user and permission architecture.
It should be considered alongside WordPress’s native capability system rather than as a substitute for secure capability checks inside custom code.
Admin Bar visibility is a separate layer
The WordPress Admin Bar is another interface that can expose administrative shortcuts.
Customizing the sidebar menu does not automatically customize the toolbar.
If users should have a simplified toolbar too, review Customizing the WordPress Toolbar for Different Roles.
The Admin Bar can contain shortcuts to hidden pages
This creates an important usability issue.
You may remove an admin sidebar item while leaving a toolbar shortcut pointing to the same page.
The authorization model may still be secure, but the interface becomes inconsistent.
A complete role-specific admin design should therefore review:
Sidebar menu
+
Admin Bar
+
Dashboard widgets
+
Custom pages
+
Direct links
Use Admin Bar controls consistently
TheOneWP’s Disable Admin Bar Items can help remove unnecessary toolbar items where a simplified user experience requires it.
If the toolbar itself is unnecessary for particular users, Hide Admin Bar provides another interface-level option.
Neither replaces server-side authorization.
Do not redirect unauthorized users instead of checking permissions
A common pattern is:
if user should not see page
→ redirect to dashboard
Redirects can improve the user experience in some situations.
But they should not replace the underlying capability check.
The correct sequence is:
Determine authorization
↓
Reject unauthorized operation
↓
Optionally provide appropriate navigation
Login redirects are a different concern
You may also want users to land on different pages immediately after authentication.
For example:
Administrator
→ Dashboard
Editor
→ Posts
Client
→ Reports
TheOneWP’s Redirect After Login can support role-specific post-login destinations.
For the underlying workflow, see Redirecting Users by Role in WordPress.
Landing page and authorization are still different
Sending an Editor directly to:
/wp-admin/edit.php
does not mean the Editor cannot access another page.
It only changes the first page shown after login.
Access must still be controlled through capabilities.
Custom post type visibility can depend on capabilities
Custom post types add another layer to admin visibility.
Registration can control:
- whether the post type appears in the admin;
- where it appears;
- which capabilities control its actions;
- whether it appears under another menu.
For the broader content model, see WordPress Post Types vs. Custom Post Types.
Do not rely only on show_in_menu
A custom post type’s show_in_menu configuration affects its administrative presentation.
Its capability configuration determines who can perform actions on its content.
These are related but distinct settings.
A secure custom post type should define its access model deliberately rather than using menu visibility as the permission boundary.
Object-level permissions can be more precise than page-level permissions
Sometimes access depends on the specific object being edited.
For example:
Can user edit posts generally?
vs.
Can user edit this specific post?
WordPress meta capabilities support this kind of contextual check.
if ( ! current_user_can( 'edit_post', $post_id ) ) {
wp_die(
esc_html__( 'You cannot edit this content.', 'example' )
);
}
The official current_user_can() documentation describes passing an object ID when checking meta capabilities such as edit_post.
Use capability checks for user administration too
User-management pages can expose particularly sensitive operations.
Before building custom user administration interfaces, distinguish between actions such as:
- viewing users;
- editing users;
- creating users;
- deleting users;
- promoting users.
Do not assume one broad visual rule adequately represents every operation.
Audit existing roles before designing page visibility
Before implementing a large set of role-specific admin rules, understand what the site’s roles currently contain.
Sites that have existed for years may include:
- plugin-created roles;
- old custom roles;
- unexpected capabilities;
- roles left behind by removed plugins;
- users with additional permissions.
Use How to Audit User Roles on a WordPress Site before assuming the permission structure matches the role names visible in the interface.
Test with real role accounts
Do not validate role-based admin visibility only while logged in as Administrator.
Create or use representative test accounts for:
- Editor;
- Author;
- Contributor;
- Subscriber;
- custom roles.
For each role, test:
Visible menu
Direct URLs
Form submissions
AJAX
REST endpoints
Content editing
User actions
Plugin pages
Test direct URLs explicitly
If a page should be unavailable to an Editor, test the actual URL while logged in as an Editor.
For example:
/wp-admin/admin.php?page=company-settings
Do not stop after confirming that the menu item is absent.
Test requests without using the interface
Security testing should assume the user can construct requests manually.
Therefore test:
- direct GET requests;
- direct POST requests;
- AJAX requests;
- REST requests.
The browser interface is not a security boundary.
Test users with multiple roles
If the site allows multi-role assignment, test combinations rather than assuming each role behaves independently.
A user receiving capabilities from another role may legitimately gain access to pages hidden from ordinary members of their primary role.
That is another reason capability-based testing is more reliable than checking labels.
Test after plugin changes
Plugins can:
- add new admin pages;
- register new capabilities;
- create new roles;
- modify existing permissions;
- add toolbar items;
- add custom post types.
Role-specific administration should therefore be reviewed when significant plugins are added, removed or replaced.
Test after WordPress updates
Custom menu modifications should also be checked after significant WordPress changes.
Code that relies on undocumented markup or CSS selectors is generally more fragile than code using documented WordPress APIs and capabilities.
Avoid permission logic based on menu position
Do not build authorization rules around assumptions such as:
menu item number 7
=
Settings
Plugins and customization can alter the menu structure.
Permissions should refer to capabilities and known application behavior rather than visual position.
Avoid permission logic based on translated labels
Similarly, visible labels can change with:
- language;
- plugins;
- white-label customization;
- menu renaming.
Do not use a displayed label such as:
"Settings"
as the foundation of authorization logic.
Custom admin design should remain maintainable
A role-specific backend can become difficult to maintain if dozens of unrelated snippets independently modify the menu.
A better architecture centralizes:
- role definitions;
- capabilities;
- menu customization;
- custom admin pages;
- toolbar customization;
- access rules.
TheOneWP’s Admin Menu Organizer, Role Manager and Access Manager can support different layers of that administrative architecture.
Do not remove emergency administrative access
When customizing capabilities, ensure that the site’s legitimate administrators retain the permissions necessary to maintain and recover the installation.
Test capability changes on staging where possible before applying extensive role modifications to production.
Be careful when editing the Administrator role
The Administrator role is central to ordinary single-site WordPress management.
Removing capabilities without understanding their dependencies can create unexpected administrative restrictions.
Custom roles are often easier to reason about than heavily modifying the Administrator role to accommodate a narrow workflow.
Multisite requires additional consideration
WordPress Multisite introduces network-level administration and Super Admin behavior.
A permission architecture designed for a normal single-site installation should not automatically be assumed to behave identically across a network.
The official WordPress Roles and Capabilities documentation provides the broader Core capability model, including capabilities relevant to Multisite environments.
Role-specific notices should follow the same principle
Admin notices can also be targeted according to user responsibilities.
An Editor does not necessarily need infrastructure warnings intended for site administrators.
TheOneWP’s Disable Admin Notifications by Role can help reduce irrelevant administrative notices for selected roles.
For the underlying notice system, see WordPress Admin Notices Explained.
Visibility rules should improve clarity, not conceal security problems
A well-designed role-specific admin can feel dramatically simpler than the default backend.
But visual simplicity should be the final layer:
Correct permissions
↓
Secure handlers
↓
Secure endpoints
↓
Appropriate page access
↓
Clean interface
Reversing that sequence creates an interface that looks restricted without necessarily being restricted.
Example: building an Editor-specific WordPress admin
Suppose Editors should manage content but not technical configuration.
The intended interface might be:
Dashboard
Posts
Media
Pages
Comments
Editorial Tools
First, confirm that the Editor role has the required content capabilities and lacks inappropriate infrastructure capabilities.
Then remove irrelevant menu entries where necessary.
Finally, test direct access to sensitive pages and actions.
The sequence is:
1. Audit capabilities
2. Correct permissions
3. Register custom pages with appropriate capabilities
4. Remove irrelevant menu entries
5. Customize dashboard and toolbar
6. Test direct access
7. Test actions and endpoints
Example: client-only reporting page
Suppose a client should access a reporting page but not normal WordPress administration.
Create a dedicated capability:
view_client_reports
Register the page against that capability:
add_action( 'admin_menu', 'example_register_client_reports' );
function example_register_client_reports() {
add_menu_page(
'Client Reports',
'Reports',
'view_client_reports',
'client-reports',
'example_render_client_reports',
'dashicons-chart-area'
);
}
Then verify the same capability in the callback:
function example_render_client_reports() {
if ( ! current_user_can( 'view_client_reports' ) ) {
wp_die(
esc_html__( 'You are not allowed to access this page.', 'example' )
);
}
echo '<div class="wrap">';
echo '<h1>Client Reports</h1>';
echo '</div>';
}
The capability can then be assigned to the appropriate custom role.
Example: different actions on the same page
A reporting page may be visible to several roles while advanced actions remain restricted.
if ( current_user_can( 'view_company_reports' ) ) {
// Render report.
}
if ( current_user_can( 'export_company_reports' ) ) {
// Render export button.
}
if ( current_user_can( 'manage_company_reports' ) ) {
// Render configuration controls.
}
The corresponding handlers must repeat the appropriate capability checks.
Example: hiding a menu entry without changing access
add_action( 'admin_menu', 'example_simplify_editor_menu', 999 );
function example_simplify_editor_menu() {
if ( current_user_can( 'edit_others_posts' )
&& ! current_user_can( 'manage_options' ) ) {
remove_menu_page( 'tools.php' );
}
}
This can simplify the interface for users who fit that capability pattern.
It should be understood as menu customization, not a replacement for the capabilities protecting individual Tools pages.
Example: denying a custom admin action
function example_process_admin_action() {
if ( ! current_user_can( 'manage_company_reports' ) ) {
wp_die(
esc_html__( 'Permission denied.', 'example' ),
'',
array(
'response' => 403,
)
);
}
check_admin_referer( 'example_admin_action' );
// Perform the protected operation.
}
This places authorization directly next to the operation being protected.
Use HTTP 403 appropriately for forbidden operations
When an authenticated user attempts an operation they are not authorized to perform, an HTTP 403 response can accurately communicate that the request is forbidden.
The important point is not merely the error page shown to the user.
The important point is that the sensitive operation never executes.
Audit custom admin pages periodically
As a WordPress site evolves, administrative pages accumulate.
Periodically inventory:
- Core admin pages;
- plugin pages;
- custom pages;
- custom post type screens;
- settings pages;
- Tools pages;
- dashboard pages.
For each one, ask:
Who should see this?
Who should access this?
Which capability protects it?
What actions does it expose?
Audit user roles periodically too
Admin page visibility depends on the underlying permission model.
If roles have accumulated unnecessary capabilities, the interface can become inconsistent with the site’s actual security requirements.
Use How to Audit User Roles on a WordPress Site as part of periodic access reviews.
Document custom capabilities
If your site introduces capabilities such as:
view_client_reports
manage_inventory
approve_editorial_content
export_orders
document:
- what each capability allows;
- which pages use it;
- which actions use it;
- which roles receive it;
- why the permission exists.
This becomes particularly important when multiple developers or administrators maintain the site.
Use a permissions matrix
A simple matrix can make role-specific admin design much easier to reason about.
PAGE / ACTION ADMIN EDITOR AUTHOR CLIENT
Posts Yes Yes Yes No
Pages Yes Yes No No
Media Yes Yes Yes No
Reports Yes Yes No Yes
Export Reports Yes No No Yes
Report Settings Yes No No No
Plugins Yes No No No
Users Yes No No No
Then translate that business model into WordPress capabilities.
Do not make the role name the permissions matrix
A statement such as:
Editors can access this
is less precise than:
This page requires view_company_reports.
The Editor role currently receives
view_company_reports.
The second model makes future permission changes easier.
Test after changing capabilities
Whenever role capabilities change, test:
- admin menu visibility;
- direct page access;
- content editing;
- custom actions;
- AJAX endpoints;
- REST endpoints;
- toolbar shortcuts;
- login redirects.
A capability can affect more functionality than the one page you originally intended to modify.
Do not grant broad capabilities just to reveal one menu page
Suppose an Editor needs access to one plugin report, but that report requires:
manage_options
Granting manage_options to Editors simply to reveal that report can expose many unrelated administrative settings.
A better solution may require:
- a plugin-specific capability;
- a custom reporting page;
- a dedicated custom capability;
- a plugin configuration option for access control.
The permission should be as narrow as the required responsibility.
Do not remove capabilities just to hide one page either
The opposite problem also occurs.
A capability may control several legitimate actions.
Removing it solely to hide one menu entry can unintentionally break unrelated workflows.
Separate:
Interface customization
from
authorization design
and choose the appropriate mechanism for each.
Admin menu customization is part of UX
Once permissions are correct, the administrative menu becomes a user-experience problem.
Good role-specific navigation should prioritize:
- frequent tasks;
- clear terminology;
- predictable grouping;
- relevant functionality;
- minimal distraction.
TheOneWP’s Admin Menu Organizer can support this organizational layer.
Admin visibility is not only about security
Not every hidden page is sensitive.
Sometimes a page is hidden simply because it is irrelevant to a particular user.
For example:
SEO configuration
→ relevant to SEO team
Editorial workflow
→ relevant to editors
Server diagnostics
→ relevant to technical administrators
A clean admin interface can reduce cognitive overhead even where security is not the primary concern.
Security still needs to survive a visible URL
A useful test is:
If the user knows the exact URL,
does the authorization model still work?
If the answer is no, the implementation relies too heavily on obscurity.
Security needs to survive a custom request too
The stronger version of the same test is:
If the user knows:
the URL
the request parameters
the AJAX action
the REST route
can they perform the operation
without the required capability?
Every sensitive path should enforce authorization independently.
Role-based WordPress admin visibility checklist
- Inventory the site’s roles.
- Inventory important capabilities.
- Audit custom roles.
- Audit plugin-created roles.
- Inventory Core admin pages.
- Inventory plugin admin pages.
- Inventory custom admin pages.
- Identify the capability required by each sensitive page.
- Prefer capability checks over direct role-name checks.
- Use dedicated capabilities for specialized workflows where appropriate.
- Register custom admin pages with appropriate capabilities.
- Verify capabilities inside sensitive callbacks.
- Protect form handlers independently.
- Protect AJAX callbacks independently.
- Protect REST endpoints independently.
- Use nonces for state-changing administrative requests.
- Do not treat CSS hiding as security.
- Do not treat JavaScript hiding as security.
- Do not treat disabled buttons as security.
- Remove irrelevant menu entries for usability.
- Review submenu visibility.
- Review Admin Bar shortcuts.
- Review dashboard widgets.
- Review custom post type screens.
- Review plugin settings pages.
- Test direct admin URLs.
- Test GET requests.
- Test POST requests.
- Test AJAX requests.
- Test REST requests.
- Test every important role.
- Test users with multiple roles where applicable.
- Test custom capabilities.
- Document the permission model.
- Repeat the audit after major plugin or role changes.
A practical implementation sequence
For a site with several user groups, use a process such as:
1. List user responsibilities
2. Map responsibilities to capabilities
3. Audit existing roles
4. Create custom capabilities where necessary
5. Assign capabilities to appropriate roles
6. Register admin pages with those capabilities
7. Protect page callbacks
8. Protect form handlers
9. Protect AJAX and REST endpoints
10. Remove irrelevant menu entries
11. Organize remaining navigation
12. Customize toolbar and dashboard
13. Test each role
14. Test direct access
15. Document the final permission model
How TheOneWP can support role-specific WordPress administration
Different TheOneWP modules can support different layers of the admin-access model.
Role Manager
Role Manager can help manage the roles and capabilities that form the foundation of WordPress authorization.
Use it when the default WordPress roles do not accurately represent the responsibilities of the site’s users.
Access Manager
Access Manager can support broader access-control workflows when user access needs to be managed more deliberately.
Admin Menu Organizer
Admin Menu Organizer addresses the interface layer by helping organize the administration menu around actual workflows.
Multi Role Assignment
Multi Role Assignment can support users whose responsibilities span multiple existing role structures.
Disable Admin Notifications by Role
Disable Admin Notifications by Role can reduce irrelevant notices for users who do not need infrastructure-level administrative messages.
Redirect After Login
Redirect After Login can direct different users toward the most appropriate starting point after authentication.
Admin Bar controls
Disable Admin Bar Items and Hide Admin Bar can simplify the toolbar where role-specific interface design requires it.
The ideal WordPress admin permission model
A maintainable WordPress administration architecture separates several concerns:
Roles
↓
represent responsibilities
Capabilities
↓
represent permissions
Server-side checks
↓
enforce authorization
Admin pages
↓
expose appropriate workflows
Menus and toolbar
↓
present those workflows clearly
When those layers agree, the backend becomes easier to use and easier to secure.
Related guides
- Restricting WordPress Features by User Role
- How to Hide WordPress Admin Menu Items by Role
- WordPress User Roles and Capabilities Explained
- How to Add a Custom Admin Page in WordPress
- How to Audit User Roles on a WordPress Site
Final recommendation
Control WordPress admin page visibility as part of a complete authorization architecture rather than treating hidden menu items as permissions.
Start with the site’s roles and capabilities. Use WordPress User Roles and Capabilities Explained to understand the underlying model, then audit the actual site with How to Audit User Roles on a WordPress Site.
When the default permission structure does not match real responsibilities, Role Manager can help maintain custom role and capability structures. Use dedicated capabilities for specialized workflows instead of granting broad administrative permissions simply to make one page accessible.
Register custom admin pages with the capability they genuinely require, then verify that capability again around sensitive operations. Apply the same principle to form handlers, AJAX callbacks and REST API endpoints. A user should remain unauthorized even if they know the exact URL or construct the request manually.
Once authorization is correct, simplify the interface. Admin Menu Organizer can help structure the administration menu around the work each user actually performs, while Disable Admin Bar Items can reduce unnecessary toolbar shortcuts.
Finally, test with representative accounts rather than only with an Administrator. Verify visible menus, direct URLs, forms, AJAX requests, REST endpoints and individual actions for every important role.
The distinction to preserve is simple:
Hiding an admin page
controls what the user sees.
Capabilities
control what the user can do.

