§ 04.28 — Pixy Puala · Security · Least privilege · 2026

WP Abilities Permission Auditor

PHP · WP-CLI · SECURITY AUDIT

As the WordPress Abilities API opens capabilities to automation, MCP and AI clients, a capability that was merely generous becomes an exposed surface. This auditor finds least-privilege violations and maps them to Abilities-style descriptors for review.

Maintainer
Pixy Puala
Vertical
Security · Least privilege
Year
2026
Role
Open source
Stack
PHP
Status
● Public repo
§ 04.28.B

Problem

What was broken

Role and capability grants accumulate quietly — a plugin adds one, a client asks for another, and nobody re-reads the matrix. When those capabilities become machine-callable, an over-granted editor role turns into a code-execution or account-control path. The gap is that nobody was looking.

§ 04.28.C

Constraints

Boundaries · published
01 Engagement Open source · authored and maintained
02 Stack PHP · WP-CLI · Composer
03 Scope Defensive audit · read-only
04 Audience Security reviewers · site admins · plugin devs
§ 04.28.D

Decisions

Three · defended
Decision · 01

Non-zero exit on findings

The CLI is designed to be a CI gate. A finding fails the build; a clean run is a recorded artefact. A pretty admin table alone changes nothing.

Decision · 02

Deterministic JSON export

Output is stable and diffable, so a capability change shows up in review as a diff instead of requiring someone to re-read a matrix by eye.

Decision · 03

Read-only by design

The tool reports; it never edits roles. An auditor that mutates the thing it audits is a new class of incident.

§ 04.28.E

Build

Stack · tooling · what it runs on

Stack

  • PHP · Composer
  • WP-CLI command · admin screen
  • Risk policy engine · capability → risk mapping
  • Deterministic JSON export
  • PHPUnit · PHPCS/WPCS clean
  • GitHub Actions · PHP 8.1 and 8.3

Tooling

  • ✓ kept Composer · WP-CLI · GitHub Actions
§ 04.28.F

Results · Measured

Countable facts · from the repository
Unit tests
24 passing
policy · export · command
Live finding
1 real
editor holds unfiltered_html
CI PHP matrix
2 versions
8.1 · 8.3

Verified against a live WordPress 7.0.2 + WooCommerce install, where it surfaced a genuine finding — WordPress grants unfiltered_html to the editor role — in both text and JSON output, recorded in docs/RUNTIME-VERIFICATION.md.

§ 04.28.G

Tradeoffs

What was not fixed

Broader Abilities API coverage waits for that API to stabilise; chasing a moving spec would ship churn. The admin screen is registered but has not been driven through a browser test, so the CLI is the surface with proof behind it.

Want this shape in your stack? The code is public. The judgement is the service.

Read the source → Start a project