Docs Advanced Custom Policy Rules (JSON)

Custom Policy Rules (JSON)

Write advanced policy rules with conditional logic, role targeting, and capability overrides.

Advanced reference 5 min read

Overview

Custom policies let you go beyond the built-in templates. Write JSON rules that precisely control menu access, page blocking, and capability stripping for specific WordPress roles. This is the most flexible way to configure AdminLocks and is ideal for agencies managing complex multi-role environments.

Every policy in AdminLocks ultimately resolves to a JSON rule object. The visual policy builder generates these rules for you, but you can also write them by hand in the AdminLocks → Policies → Custom JSON editor for full control.

Rule Structure

A policy rule is a JSON object with three optional arrays. Each array controls a different aspect of the WordPress admin experience. You can include any combination of the three -- all are optional, and omitted arrays have no effect.

{
  "deny_menus": ["plugins.php", "themes.php"],
  "deny_pages": ["plugins.php", "theme-install.php"],
  "deny_capabilities": ["install_plugins", "switch_themes"]
}

All three arrays work together. If you deny a menu item but do not deny the corresponding page or capability, the user may still access the functionality through direct URL navigation or API calls. For complete lockdowns, use all three arrays in combination.

deny_menus

An array of WordPress menu slugs to hide from the admin sidebar. These are the filenames used in add_menu_page() and correspond to top-level admin menu items. When a menu slug is denied, the sidebar item is removed entirely.

Common menu slugs:

SlugMenu Item
plugins.phpPlugins
themes.phpAppearance
users.phpUsers
tools.phpTools
options-general.phpSettings
edit-comments.phpComments
upload.phpMedia
edit.phpPosts

The user will not see the menu item in the sidebar, but they could still navigate to the page directly by entering the URL. Always pair deny_menus with deny_pages for complete enforcement.

deny_pages

An array of admin page filenames to block. AdminLocks matches these values against the WordPress $pagenow global variable on every admin page load. When a user navigates directly to a denied page, they receive a 403 "Access Denied" response with a message explaining that their access has been restricted by a policy.

This is the enforcement layer. While deny_menus hides the navigation, deny_pages actually blocks access. Common page filenames:

deny_capabilities

An array of WordPress capabilities to strip from targeted users. When a capability is stripped, the user cannot perform any action that requires it. WordPress checks capabilities throughout the admin via current_user_can(), so this is the deepest level of enforcement -- it affects UI elements, REST API calls, AJAX requests, and all programmatic capability checks.

CapabilityWhat it controls
install_pluginsInstalling new plugins
activate_pluginsActivating and deactivating plugins
delete_pluginsDeleting plugins from the server
install_themesInstalling new themes
switch_themesChanging the active theme
delete_themesDeleting themes from the server
edit_theme_optionsCustomizer and widget access
create_usersCreating new user accounts
delete_usersDeleting user accounts
promote_usersChanging user roles
edit_usersEditing other users' profiles
manage_optionsAccessing the Settings screens
moderate_commentsModerating and managing comments

Targeting Roles

Policies can target specific WordPress roles via a comma-separated list in the policy's Roles field. When roles are specified, the policy only applies to users who hold one of those roles.

If the roles field is left empty, the policy applies to all non-administrator users by default. Administrators with the manage_options capability are always exempt unless they lack the adminlocks_bypass capability and a policy explicitly targets the administrator role.

// Target editors and authors only
Roles: "editor,author"

// Target all non-admin users (leave empty)
Roles: ""

Be careful when targeting the administrator role. Locking yourself out of the Settings screen will require WP-CLI or direct database access to recover. Always keep at least one account with the adminlocks_bypass capability.

Examples

Lock out editors from plugins and themes

{
  "deny_menus": ["plugins.php", "themes.php"],
  "deny_pages": ["plugins.php", "plugin-install.php", "themes.php", "theme-install.php"],
  "deny_capabilities": ["install_plugins", "activate_plugins", "delete_plugins",
                         "install_themes", "switch_themes", "delete_themes"]
}
Roles: "editor"

Content-only mode for authors

{
  "deny_menus": ["plugins.php", "themes.php", "users.php", "tools.php",
                  "options-general.php"],
  "deny_pages": ["plugins.php", "themes.php", "users.php", "tools.php",
                  "options-general.php", "import.php", "export.php"],
  "deny_capabilities": ["install_plugins", "activate_plugins", "switch_themes",
                         "manage_options", "create_users", "edit_users"]
}
Roles: "author"

Block settings for all non-admins

{
  "deny_menus": ["options-general.php"],
  "deny_pages": ["options-general.php", "options-writing.php", "options-reading.php",
                  "options-discussion.php", "options-media.php", "options-permalink.php"],
  "deny_capabilities": ["manage_options"]
}
Roles: ""

Validation

All policy rules are validated when you save them. AdminLocks checks that the rule is valid JSON, that the top-level value is an object, and that each key maps to an array of strings.

You can test your custom policy rules without affecting live users by setting the policy to inactive. Activate it only after you have verified the JSON structure and tested with a staging account.