---
title: Capabilities
---

Mantle defines its own capabilities rather than reusing `manage_options`, so a client administrator can be given a narrower slice of the plugin than a Linchpin engineer. Capabilities are grouped, assigned to roles by default, and synchronised into WordPress roles on demand.

Every label, description, group, and role list below was read from a running installation, not from the source definitions — see [How the list is assembled](#how-the-list-is-assembled) for why those can differ.

## The power_admin role

Mantle introduces a `power_admin` role that holds every Mantle capability. `administrator` receives a read-mostly subset, and a few cache-clearing capabilities extend to `editor` and `shop_manager`. The intent is that Linchpin staff hold `power_admin` while the client's own administrators keep `administrator`.

<!-- wp:docspress/callout {"tone":"note","title":"Capabilities are removed on uninstall, not deactivation","content":"<p><code>mantle_uninstall()</code> strips Mantle capabilities from all roles and deletes <code>mantle_capabilities_version</code> and <code>mantle_capabilities_last_synced</code>. Deactivating the plugin leaves the capabilities on the roles.</p>","collapsible":false} /-->

## Core capabilities

Defined in `Mantle\Model\Users\Capabilities::get_core_capabilities()` and not owned by any module.

<!-- wp:docspress/fields {"title":"Core capabilities","description":"Filterable via <code>mantle_core_capabilities</code>. The default column lists the roles granted the capability.","fields":[{"name":"mantle_manage_options","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Manage Mantle Options.</strong> Allows users to manage and edit Mantle plugin settings and options. Group: manage.","values":"power_admin","deprecated":false},{"name":"mantle_view_options","type":"string","required":false,"defaultValue":"power_admin, administrator","description":"<strong>View Mantle Options.</strong> Allows users to view Mantle plugin settings and options. Group: view.","values":"power_admin, administrator","deprecated":false},{"name":"mantle_manage_users","type":"string","required":false,"defaultValue":"power_admin, administrator","description":"<strong>Manage Mantle Users.</strong> Allows users to manage Mantle user capabilities and view capability sync status. Group: manage.","values":"power_admin, administrator","deprecated":false},{"name":"mantle_remote_register","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Remote Register.</strong> Core describes this as registering the plugin and authenticating during initial setup, but the <code>dashboard</code> module redefines the key and its description wins at runtime. Group: manage.","values":"power_admin","deprecated":false}],"searchable":true,"compact":false} /-->

## Module capabilities

Contributed by modules via `register_capabilities()`.

<!-- wp:docspress/fields {"title":"Dashboard module","description":"Owned by the <code>dashboard</code> module, which is type <code>core</code> and always enabled. The first two gate the built-in admin tabs through the <code>requiredCapability</code> property in <code>src/constants/routes.js</code>.","fields":[{"name":"mantle_edit_settings","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Manage Settings.</strong> Manage general Mantle settings. Group: manage. Gates the Settings tab.","values":"power_admin","deprecated":false},{"name":"mantle_view_dashboard","type":"string","required":false,"defaultValue":"power_admin, administrator","description":"<strong>View Dashboard.</strong> Access to the Mantle dashboard. Group: view. Gates the Dashboard tab.","values":"power_admin, administrator","deprecated":false},{"name":"mantle_remote_register","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Remote Register.</strong> Ability to remotely register mantle on behalf of the client. Group: manage. Redefines the core capability of the same name, and this definition is the one that takes effect.","values":"power_admin","deprecated":false}],"searchable":false,"compact":true} /-->

<!-- wp:docspress/fields {"title":"Cache","description":"Owned by the <code>convergence_cache</code> module.","fields":[{"name":"mantle_edit_cache","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Edit Cache Settings.</strong> Ability to edit cache settings and configuration. Group: manage.","values":"power_admin","deprecated":false},{"name":"mantle_view_cache","type":"string","required":false,"defaultValue":"power_admin, administrator","description":"<strong>View Cache.</strong> Access to cache management section. Group: view.","values":"power_admin, administrator","deprecated":false},{"name":"mantle_clear_cache_all","type":"string","required":false,"defaultValue":"power_admin, administrator, editor, shop_manager","description":"<strong>Clear Full Site Cache.</strong> Ability to clear the full site cache. Group: action.","values":"power_admin, administrator, editor, shop_manager","deprecated":false},{"name":"mantle_clear_cache_edge","type":"string","required":false,"defaultValue":"power_admin, administrator, editor, shop_manager","description":"<strong>Clear Edge Cache.</strong> Ability to clear the edge cache. Group: action.","values":"power_admin, administrator, editor, shop_manager","deprecated":false},{"name":"mantle_clear_cache_object","type":"string","required":false,"defaultValue":"power_admin, administrator, editor, shop_manager","description":"<strong>Clear Object Cache.</strong> Ability to clear the object cache. Group: action.","values":"power_admin, administrator, editor, shop_manager","deprecated":false},{"name":"mantle_clear_cache_page","type":"string","required":false,"defaultValue":"power_admin, administrator, editor, shop_manager","description":"<strong>Clear Single Page Cache.</strong> Ability to clear a single page cache. Group: action.","values":"power_admin, administrator, editor, shop_manager","deprecated":false}],"searchable":true,"compact":false} /-->

<!-- wp:docspress/fields {"title":"Monitoring","description":"Owned by the <code>monitoring</code> module. StatusCake is the backing service.","fields":[{"name":"mantle_view_monitoring","type":"string","required":false,"defaultValue":"power_admin, administrator","description":"<strong>View Monitoring.</strong> Access to monitoring/StatusCake section. Group: view.","values":"power_admin, administrator","deprecated":false},{"name":"mantle_view_monitoring_items","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Request StatusCake Items.</strong> Request items from StatusCake API. Group: monitoring.","values":"power_admin","deprecated":false},{"name":"mantle_edit_monitoring_items","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Edit StatusCake Items.</strong> Edit StatusCake monitoring items. Group: monitoring.","values":"power_admin","deprecated":false},{"name":"mantle_delete_monitoring_items","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Delete StatusCake Items.</strong> Delete StatusCake monitoring items. Group: monitoring.","values":"power_admin","deprecated":false}],"searchable":true,"compact":false} /-->

<!-- wp:docspress/fields {"title":"Communication and AI","description":"Owned by the <code>communication</code> and <code>ai_chatbot</code> modules.","fields":[{"name":"mantle_manage_communication","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Manage Communication.</strong> Manage communication details and information. Group: manage.","values":"power_admin","deprecated":false},{"name":"mantle_view_communication","type":"string","required":false,"defaultValue":"power_admin, administrator","description":"<strong>View Communication.</strong> View communication details and information. Group: view.","values":"power_admin, administrator","deprecated":false},{"name":"mantle_access_client_chat","type":"string","required":false,"defaultValue":"power_admin, administrator, editor","description":"<strong>Access Client Chat.</strong> Access the client chat widget for team communication. Group: view.","values":"power_admin, administrator, editor","deprecated":false},{"name":"mantle_access_slack_chat","type":"string","required":false,"defaultValue":"power_admin, administrator, editor","description":"<strong>Access Slack Chat.</strong> Access the Slack chat widget for team communication. Group: view.","values":"power_admin, administrator, editor","deprecated":false},{"name":"mantle_access_chatbot","type":"string","required":false,"defaultValue":"power_admin, administrator, editor","description":"<strong>Access Chatbot.</strong> Access to the AI chatbot feature. Group: feature.","values":"power_admin, administrator, editor","deprecated":false}],"searchable":true,"compact":false} /-->

<!-- wp:docspress/fields {"title":"Plugin sync and snippets","description":"Owned by the <code>plugin_sync</code> and <code>site_code_snippets</code> modules. The two highlighted below are the most privileged capabilities Mantle defines.","fields":[{"name":"mantle_execute_plugin_commands","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Execute Plugin Commands.</strong> Execute remote plugin management commands. Group: manage. Drives the <code>/plugins/command</code> routes.","values":"power_admin","deprecated":false},{"name":"mantle_manage_site_code_snippets","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Manage Site Code Snippets.</strong> Manage site code snippets. Group: manage. Permits arbitrary header, body, and footer script injection.","values":"power_admin","deprecated":false},{"name":"mantle_manage_plugin_sync","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Manage Plugin Sync.</strong> Manage plugin sync settings and view sync status. Group: manage.","values":"power_admin","deprecated":false},{"name":"mantle_view_plugin_action_log","type":"string","required":false,"defaultValue":"power_admin, administrator","description":"<strong>View Plugin Action Log.</strong> View audit log of plugin management actions. Group: view.","values":"power_admin, administrator","deprecated":false},{"name":"mantle_view_site_code_snippets","type":"string","required":false,"defaultValue":"power_admin, administrator","description":"<strong>View Site Code Snippets.</strong> View site code snippets. Group: view.","values":"power_admin, administrator","deprecated":false}],"searchable":true,"compact":false} /-->

<!-- wp:docspress/fields {"title":"Clients, security, optimizations, users","description":"Owned by the <code>client_info</code>, <code>security</code>, <code>optimizations</code>, and <code>user_management</code> modules.","fields":[{"name":"mantle_manage_clients","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Manage Clients.</strong> Manage client details and information. Group: manage.","values":"power_admin","deprecated":false},{"name":"mantle_manage_security","type":"string","required":false,"defaultValue":"power_admin, administrator","description":"<strong>Manage Security.</strong> Manage security. Group: manage.","values":"power_admin, administrator","deprecated":false},{"name":"mantle_manage_optimizations","type":"string","required":false,"defaultValue":"power_admin, administrator","description":"<strong>Manage Optimizations.</strong> Manage optimizations. Group: manage.","values":"power_admin, administrator","deprecated":false},{"name":"manage_mantle_users","type":"string","required":false,"defaultValue":"power_admin","description":"<strong>Manage Users.</strong> Manage user roles and permissions. Group: manage. Note the reversed word order compared with the core <code>mantle_manage_users</code>.","values":"power_admin","deprecated":false}],"searchable":true,"compact":false} /-->

<!-- wp:docspress/callout {"tone":"warning","title":"manage_mantle_users and mantle_manage_users are different capabilities","content":"<p>Both exist. <code>mantle_manage_users</code> is a core capability granted to <code>power_admin</code> and <code>administrator</code>; <code>manage_mantle_users</code> is contributed by a module and granted only to <code>power_admin</code>. They are not interchangeable, and a permission check written against the wrong one grants or denies more than intended. Confirm which one a route uses before relying on it.</p>","collapsible":false} /-->

## How the list is assembled

`get_all_capabilities()` merges core capabilities with module capabilities through two complementary paths.

<!-- wp:docspress/diagram {"title":"Capability collection","type":"flow","source":"get_all_capabilities -> core: get_core_capabilities\nget_all_capabilities -> enabled modules: loop adds their caps\nget_all_capabilities -> mantle_all_capabilities: apply filter\nmantle_all_capabilities -> disabled modules: filter adds their caps\nmantle_all_capabilities -> result: union across all modules","caption":"The loop covers enabled modules and the per-module filter covers disabled ones, so the result spans every module regardless of state."} /-->

The loop inside `get_all_capabilities()` skips modules where `is_enabled()` returns false. Separately, each module registers a `mantle_all_capabilities` filter whose callback returns early when the module *is* enabled and adds its capabilities when it is not. The two paths are complementary, so the returned list covers all sixteen modules either way — which is why a reference installation with twelve modules disabled still reports thirty capabilities.

Two consequences follow from the merge order:

<!-- wp:docspress/callout {"tone":"warning","title":"Module definitions overwrite core definitions of the same key","content":"<p>Core capabilities are added first, then module capabilities are assigned over them with <code>$all_capabilities[ $cap_key ] = $cap_data;</code>. Where a module defines a key that core also defines, the module wins. <code>mantle_remote_register</code> is a live example: it is declared in <code>get_core_capabilities()</code> and again by the <code>dashboard</code> module, and the dashboard definition is the one returned at runtime. Read the runtime list, not the core array, when you need the effective definition.</p>","collapsible":false} /-->

<!-- wp:docspress/callout {"tone":"warning","title":"Synchronisation grants capabilities for disabled modules too","content":"<p><code>sync_capabilities_to_roles()</code> operates on <code>get_all_capabilities()</code>. Because that list spans every module regardless of state, a sync grants capabilities such as <code>mantle_clear_cache_all</code> to roles even where <code>convergence_cache</code> is switched off. The capability is inert while the module is off — its routes do not exist — but it is present on the role and becomes live the moment the module is enabled. Audit roles after a sync if least privilege matters to you.</p>","collapsible":false} /-->

## Enumerate capabilities on your own site

<!-- wp:docspress/terminal-session {"title":"List every registered capability","shell":"bash","prompt":"$","command":"wp eval '$c = new \\Mantle\\Model\\Users\\Capabilities(); foreach ( $c->get_all_capabilities() as $k => $v ) { printf( \"%-38s %-11s %s\" . PHP_EOL, $k, $v[\"group\"] ?? \"-\", implode( \"|\", $v[\"roles\"] ?? [] ) ); }'","output":"manage_mantle_users                    manage      power_admin\nmantle_access_chatbot                  feature     power_admin|administrator|editor\nmantle_clear_cache_all                 action      power_admin|administrator|editor|shop_manager\nmantle_edit_settings                   manage      power_admin\n..."} /-->

## Synchronising and resetting

| Route | Methods | Effect |
|-------|---------|--------|
| `/mantle/v1/capabilities` | `GET` | Return capability metadata |
| `/mantle/v1/capabilities/check` | `GET` | Report sync status |
| `/mantle/v1/capabilities/sync` | `POST` | Write capabilities onto roles |
| `/mantle/v1/capabilities/reset` | `POST` | Remove and re-apply defaults |

Sync state is tracked in two options: `mantle_capabilities_last_synced` records the capability set last written, and `mantle_capabilities_version` records the plugin version that wrote it.

## Extending capabilities

<!-- wp:docspress/code-tabs {"tabs":[{"label":"Add a core capability","language":"php","filename":"functions.php","code":"add_filter(\n\t'mantle_core_capabilities',\n\tfunction ( array $capabilities ): array {\n\t\t$capabilities['mantle_view_reports'] = [\n\t\t\t'label'       => __( 'View Reports', 'my-plugin' ),\n\t\t\t'description' => __( 'Allows users to view the reports tab', 'my-plugin' ),\n\t\t\t'group'       => 'view',\n\t\t\t'roles'       => [ 'power_admin', 'administrator' ],\n\t\t];\n\n\t\treturn $capabilities;\n\t}\n);"},{"label":"Adjust one module's set","language":"php","filename":"functions.php","code":"// Runs for the module whose ID is 'monitoring'.\nadd_filter(\n\t'mantle_module_monitoring_capabilities',\n\tfunction ( array $capabilities, string $module_id ): array {\n\t\tunset( $capabilities['mantle_delete_monitoring_items'] );\n\n\t\treturn $capabilities;\n\t},\n\t10,\n\t2\n);"},{"label":"Adjust the whole set","language":"php","filename":"functions.php","code":"add_filter(\n\t'mantle_all_capabilities',\n\tfunction ( array $capabilities ): array {\n\t\t// Also grant single-page cache clearing to authors.\n\t\tif ( isset( $capabilities['mantle_clear_cache_page'] ) ) {\n\t\t\t$capabilities['mantle_clear_cache_page']['roles'][] = 'author';\n\t\t}\n\n\t\treturn $capabilities;\n\t}\n);"}],"showLineNumbers":true,"caption":"Each capability definition needs label, description, group, and roles."} /-->

A capability definition needs four keys: `label`, `description`, `group`, and `roles`. After changing definitions, POST to `/mantle/v1/capabilities/sync` so the new set is written onto roles.
