How to Restrict Admin Access by Role (Without Plugins)

December 22, 2025
How to Restrict Admin Access by Role (Without Plugins)

In many WordPress projects, not every logged-in user should have full access to the admin area.
Editors may only need content screens, authors should not see settings,
and clients should never access sensitive admin pages.

This article explains how to restrict WordPress admin access by role
using code only—no plugins—while following WordPress best practices.

Understand the Difference: Roles vs Capabilities

WordPress access control is capability-based, not role-based.
Roles are simply collections of capabilities.

That means:

  • You should restrict access by capability
  • Roles are just a convenient abstraction

This approach is more flexible and future-proof.

Common Admin Restriction Use Cases

  • Editors should not access Settings
  • Authors should not access the admin dashboard
  • Clients should only edit specific post types
  • Subscribers should never access /wp-admin/

Restrict Access to the Entire Admin Area

The simplest and safest method is to block /wp-admin/
for users without a required capability.

Block Admin Access for Non-Admins

<?php
add_action( 'admin_init', function () {
  if ( wp_doing_ajax() ) {
    return;
  }

  if ( ! current_user_can( 'manage_options' ) ) {
    wp_safe_redirect( home_url() );
    exit;
  }
} );

What this does:

  • Allows admins full access
  • Redirects all other roles away from the admin
  • Preserves AJAX functionality

Allow Access Only to Specific Admin Pages

More commonly, you want to allow limited admin access.
For example: editors can manage content but not site settings.

Restrict Settings Pages Only

<?php
add_action( 'admin_init', function () {
  if ( current_user_can( 'manage_options' ) ) {
    return;
  }

  $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
  if ( ! $screen ) {
    return;
  }

  // Block Settings pages
  if ( strpos( $screen->base, 'options' ) === 0 ) {
    wp_die(
      esc_html__( 'You do not have permission to access this page.', 'default' ),
      esc_html__( 'Access Denied', 'default' ),
      array( 'response' => 403 )
    );
  }
} );

This prevents unauthorized users from accessing:

  • Settings → General
  • Settings → Writing
  • Settings → Permalinks

Hide Admin Menu Items by Role

Restricting access is not enough.
You should also hide irrelevant menu items to avoid confusion.

Hide Menus for Editors

<?php
add_action( 'admin_menu', function () {
  if ( current_user_can( 'manage_options' ) ) {
    return;
  }

  remove_menu_page( 'options-general.php' ); // Settings
  remove_menu_page( 'tools.php' );            // Tools
  remove_menu_page( 'plugins.php' );          // Plugins
  remove_menu_page( 'themes.php' );           // Appearance
} );

Important:

  • This is UI control only
  • Always combine with capability checks

Restrict Access to Specific Post Types

If a user should only manage certain post types,
remove capabilities instead of blocking admin access.

Remove Page Editing from Editors

<?php
add_action( 'init', function () {
  $role = get_role( 'editor' );
  if ( ! $role ) {
    return;
  }

  $role->remove_cap( 'edit_pages' );
  $role->remove_cap( 'delete_pages' );
} );

This ensures:

  • Editors cannot edit or delete pages
  • Access control works everywhere (UI + API)

Prevent Direct URL Access to Admin Pages

Hiding menus is not enough.
Users can still access admin pages directly via URL.

Block Access by Screen ID

<?php
add_action( 'current_screen', function ( $screen ) {
  if ( current_user_can( 'manage_options' ) ) {
    return;
  }

  $blocked_screens = array(
    'options-general',
    'options-permalink',
    'plugins',
    'themes',
  );

  if ( in_array( $screen->id, $blocked_screens, true ) ) {
    wp_die(
      esc_html__( 'You do not have permission to access this page.', 'default' ),
      esc_html__( 'Access Denied', 'default' ),
      array( 'response' => 403 )
    );
  }
} );

Redirect Non-Admins After Login

Another common requirement is redirecting users
to a specific admin page (or front-end page) after login.

<?php
add_filter( 'login_redirect', function ( $redirect_to, $requested, $user ) {
  if ( isset( $user->roles ) && is_array( $user->roles ) ) {
    if ( in_array( 'editor', $user->roles, true ) ) {
      return admin_url( 'edit.php' );
    }

    if ( in_array( 'subscriber', $user->roles, true ) ) {
      return home_url();
    }
  }

  return $redirect_to;
}, 10, 3 );

Common Mistakes to Avoid

  • Checking roles instead of capabilities everywhere
  • Only hiding menus without blocking access
  • Blocking admin access without allowing AJAX
  • Redirect loops caused by unconditional redirects

Security & Maintenance Considerations

Best practices:

  • Restrict by capability whenever possible
  • Keep logic centralized (functions.php or mu-plugin)
  • Test with multiple roles and direct URLs

Avoid hardcoding role names in many places.
Capabilities are more stable and expressive.

Summary

  • WordPress access control is capability-based
  • Use admin_init and current_screen to restrict access
  • Hide menus with remove_menu_page for better UX
  • Always protect against direct URL access
  • No plugins required

With these patterns, you can safely restrict admin access
while keeping WordPress secure, usable, and maintainable.

Avatar

Written by

satoshi

I’ve been building and customizing WordPress themes for over 10 years. In my free time, you’ll probably find me enjoying a good football match.