Br resource policy
Skill Lonsdale201/wp-agent-skills/better-route/br-resource-policy
Configure better-route 1.1 Resource action and field authorization. Use for ResourcePolicy::publicReadPrivateWrite, adminOnly, capabilities, callbacks, Resource::policy, permissionCallback, per-action rules, wildcard rules, fieldPolicy, public Resource OpenAPI security, ownership policies, or reviewing CPT/table CRUD permissions. In 1.1 denied fields are rejected rather than silently stripped.From its SKILL.md
npx -y skills add Lonsdale201/wp-agent-skills --skill br-resource-policyAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
4.9 KB, 968 tokens by cl100k_base, as published. Nobody here has run it
better-route: Resource authorization
Use a Resource policy to decide who may call each generated action. Use fieldPolicy separately to authorize individual incoming fields.
Presets
use BetterRoute\Resource\ResourcePolicy;
->policy(ResourcePolicy::publicReadPrivateWrite('edit_posts'))
->policy(ResourcePolicy::adminOnly('manage_options'))
->policy(ResourcePolicy::capabilities([
'list' => 'read_private_reports',
'get' => 'read_private_reports',
'create' => ['edit_posts', 'manage_woocommerce'], // any-of
'update' => 'edit_posts',
'delete' => 'delete_posts',
]))
->policy(ResourcePolicy::callbacks([
'update' => static fn ($request, string $action): bool =>
current_user_can('edit_post', (int) $request->get_param('id')),
]))
Supported action keys are list, get, create, update, delete, and fallback *. update covers PUT and PATCH.
Rule values:
- boolean: allow/deny;
- non-empty capability string:
current_user_can($capability); - capability list: any capability may pass;
- callable: invoked with as many of
($request, $action, $resource)as its signature accepts.
A top-level permissionCallback callable overrides per-action resolution for the Resource. A top-level public => true opens every registered action, including writes; use it only with a deliberately read-only allow(['list', 'get']) Resource.
Defaults
Without a policy:
- table resources deny every action;
- CPT writes deny;
- CPT list/get allow only when the post type is publicly viewable, followed by item-level status/public/password visibility checks.
Prefer explicit policy even where the CPT default is safe, so intent and OpenAPI are clear.
Field policy in 1.1
->fieldPolicy([
'featured' => ['write' => 'manage_options'],
'author' => ['write' => ['edit_others_posts', 'manage_options']],
'external_id' => ['write' => false],
'tenant_id' => ['write' => static function (
$request,
string $field,
string $action,
?int $id
): bool {
return can_write_tenant($request, $id);
}],
])
Denied fields are not silently stripped in 1.1:
- boolean
falsereturns400 validation_failedwith a field error; - a failed capability/list/callback returns
403 forbiddenwith field error details; - allowed fields continue into coercion/sanitization.
A field-policy callable can accept ($request, $field, $action, $id, $resource). Declare only the prefix needed. The action is create or update; PATCH also resolves as update.
Only payload fields in the Resource's writable fields() set reach field policy. Unknown/read-only fields fail earlier.
OpenAPI
An action whose resolved static policy is explicitly public (true or top-level public) gets operation security: []. Callable policy source is never serialized into metadata; it is represented only as a safe callback marker where applicable.
Do not assume a callable's runtime result can be inferred into OpenAPI. Document the security scheme explicitly when middleware/auth is required.
Ownership
Use OwnedResourcePolicy::currentUserOwns() for get/update/delete ownership checks. It resolves resource ID from the request, compares the owner to native current WP user, and optionally permits an admin bypass capability. List access still needs query-level row filtering; a permission callback alone cannot remove other users' rows from a collection.
Review checklist
- Declare which actions exist with
allow()before reviewing permissions. - Never use top-level
public => trueon a write-capable Resource unintentionally. - Treat capability arrays as any-of, not all-of.
- Add object/row-level checks for get/update/delete and query-level filters for lists.
- Test denied fields and assert 400/403; do not expect silent removal.
- Keep policy callback work cheap because WordPress evaluates permission before the handler.
- Verify explicitly public actions emit
security: []in OpenAPI.
Related skills
- Use
br-resource-cptorbr-resource-tablefor source behavior. - Use
br-owned-resource-guardsfor ownership patterns. - Use
br-write-schemafor validation after field authorization.
References
- Verified source paths:
src/Resource/ResourcePolicy.phpsrc/Resource/Resource.phpsrc/Resource/OwnedResourcePolicy.php
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.