The new WordPress 7.1 public flag makes exposure intent easier to share across clients, but it can encourage a dangerous shortcut: treating discoverability as authorization. REST, MCP, WP-CLI, and internal PHP can enumerate abilities differently while the execute callback still needs a strict capability and object-level decision.
Use this for abilities that read private data, export users, create content, update settings, manage products, change orders, or are callable by an AI agent or external automation.
Quick answer
Build a two-axis test: client channel by WordPress identity. Check whether the ability is discoverable, then separately attempt execution with anonymous, subscriber, editor, shop manager, administrator, expired credential, and wrong-object fixtures. Record response fields and side effects, not only status codes.
What to check first
- Create a matrix for REST, MCP, WP-CLI, internal PHP, and each identity that can reach production.
- Run discovery and execution as separate assertions because visibility does not grant authority.
- Test object ownership and scope, such as one order, one post, one site, or one permitted field set.
- Send malformed, missing, oversized, and cross-tenant inputs through the same public endpoint.
- Confirm logs record the actor, ability name, object ID, result, and request correlation ID without storing secrets.
Diagnostic table
Use this table to keep the work practical. It connects the symptom to evidence and a verification step.
| Action | Evidence to collect | How to verify |
| Map clients and identities | Create a matrix for REST, MCP, WP-CLI, internal PHP, and each identity that can reach production. | Every client exposes only the abilities intended for that channel. |
| Define object-level permissions | Run discovery and execution as separate assertions because visibility does not grant authority. | Permission callbacks deny the wrong role and wrong object even when discovery succeeds. |
| Create allowed and denied fixtures | Test object ownership and scope, such as one order, one post, one site, or one permitted field set. | Allowed responses contain only documented fields. |
| Test response minimization | Send malformed, missing, oversized, and cross-tenant inputs through the same public endpoint. | Audit records prove who invoked the ability without retaining credentials or payload secrets. |
Test scenarios to run
Run the same controlled fixture across these branches. Record the expected result before the test so a surprising response is visible immediately.
| Scenario | Fixture | Expected result |
| Anonymous discovery | No credentials against a public ability route | Only the documented public schema appears and execution remains denied |
| Allowed identity | Dedicated role with permission for fixture object 42 | One narrow response and one expected audit entry |
| Wrong object | Allowed role requests fixture object 99 outside its scope | Denied without revealing private object fields |
| Revoked credential | Previously valid application password after revocation | Discovery or execution fails according to the documented client contract |
Why this usually happens
- Client adapters can inherit public intent while implementing discovery differently.
- A broad role capability may pass even when object ownership should deny the action.
- Status-only tests miss excess fields or partial side effects.
Field notes
- Use synthetic records with no real customer details.
- Compare denied responses for data leakage in error messages.
- Revoke a credential during the test to prove cached authorization does not outlive it.
Useful command or data shape
Adapt paths, IDs, and privacy handling to the site before running commands or storing data on production.
permission_callback => function ( array $input ): bool {
$order_id = absint( $input['order_id'] ?? 0 );
return current_user_can( 'edit_shop_order', $order_id );
}
// Test discovery and execution separately for every client and role.
Safe fix order
Do the work in a sequence that makes each result easy to prove. Stop if a step produces new evidence that changes the incident scope.
- Map clients and identities
- Define object-level permissions
- Create allowed and denied fixtures
- Test response minimization
- Verify audit evidence
Decision rule
Hold release if any denied identity can trigger a side effect, enumerate private objects, infer sensitive fields from an error, or reuse a revoked credential.
What to tell the client or owner
Provide the ability name, channel, identity, credential type, object fixture, expected discoverability, expected permission result, observed response, side effect, and correlation ID.
Production verification checklist
- Every client exposes only the abilities intended for that channel.
- Permission callbacks deny the wrong role and wrong object even when discovery succeeds.
- Allowed responses contain only documented fields.
- Audit records prove who invoked the ability without retaining credentials or payload secrets.
Mistakes to avoid
- Do not equate a hidden ability with a protected ability.
- Do not test only happy-path administrators.
- Do not return full model objects when the client needs three fields.
- Do not log authorization headers, cookies, nonces, or full personal-data payloads.
Questions teams ask during testing
Why test WP-CLI if public controls external clients?
WP-CLI can list all abilities, so it is a useful reminder that exposure policies differ and execution permissions must stand alone.
Should denied users receive 404 or 403?
Choose a consistent contract that does not leak object existence, then test the exact documented behavior.
Can an AI agent use an administrator credential?
It can technically, but a dedicated least-privilege identity and narrow abilities reduce the impact of mistakes or prompt-driven misuse.
When HandL WP should help
HandL WP can threat-model an Abilities API integration, build the client and role matrix, test sensitive actions, and leave a repeatable security regression suite.
If this is active on a production site, audit a WordPress integration boundary.
Related HandL WP guides
Use these related guides when the same issue touches tracking, security, checkout, or crawler visibility.
Apply the permission boundary to Elementor MCP
Elementor 4.3 beta adds an official MCP connection for AI coding tools. The Elementor 4.3 MCP permission and staging safety test narrows the credential, page scope, change surface, data exposure, revision evidence, and revocation proof for a real Elementor workflow.
Helpful references