Documentation
What AI can do to your sites
Exactly what you approved, on exactly the sites you approved it on.
- Nothing is on by default Connecting offers two read-only actions, pre-ticked — you confirm or decline them. Every other read, diagnostic and write is off until a human turns it on, per site.
- Two independent gates The action must be on the site's approved list and the agent account must hold the WordPress permission it needs. Either one refuses on its own.
- A WordPress admin always wins Unticking an action on the plugin's page revokes it immediately and authoritatively — before our side has even heard about it.
Where to change what a site allows
Two places, either of which works:
- In the Portcullis dashboard — open the site, tick or untick actions. Needs an admin role and a second factor proved in the last five minutes.
- On the site itself — the Portcullis page in WordPress admin has the same list. Needs a WordPress administrator.
Changes made on the site apply there instantly, then sync back to your dashboard. Changes made in the dashboard are pushed to the site so they apply without a re-enrol.
Why a WordPress admin can edit this at all
Because they already fully control that site. Someone who can install plugins and edit users can do anything the approval list could grant them, so letting them govern it gives them nothing they didn't have — and it means the person standing closest to the site can always cut access without waiting for anyone.
The site's own copy is what each request is checked against, which is why switching something off there beats our record rather than racing it.
The two gates
Gate 1 — the approved list
Every request from Portcullis carries a signed pass naming the one action it wants. That action must appear in both the pass and the list stored on the site. Portcullis also checks its own record before it will sign anything, so a revoke that hasn't finished syncing still refuses at both ends.
Gate 2 — WordPress's own permissions
Connecting creates a dedicated agent account, granted only the permissions its approved actions actually need. Admin-equivalent permissions — managing options, editing users, installing plugins, editing themes — are stripped; the account can never hold them. Writes map to the narrowest real WordPress permission, or to a purpose-built one that names a single operation.
The account is also identity-bound: it carries an ownership marker only the plugin writes, so a login already held by a human is refused rather than adopted.
The AI cannot widen its own limits
This is structural, not "we didn't build that tool":
- A management pass carries a permissions marker and zero actions.
- An action pass carries actions and never the marker.
- The permissions endpoint requires exactly the marker and nothing else.
- The action gate requires a real action.
So a pass minted to run something can't touch permissions, and a pass minted to manage permissions can't run anything. Every pass the AI path mints is the second kind.
What's in the catalogue
35 actions, all off until approved. The honest scope: report on your sites thoroughly, keep them updated, manage settings and users within guardrails, and draft content without publishing it.
| Group | What it covers |
|---|---|
| Fleet-audit reads | Pending updates, installed plugins and themes, the user roster. |
| Diagnostics | Cron health, debug and file-editing config, autoloaded option bloat, site settings, content and comment counts, database size, last publish date. |
| Writes | Update plugins, themes, core and translations; activate, deactivate and switch; maintenance mode; flush caches; run a stuck cron event; set a site setting from a curated list; create, delete or password-reset a non-administrator user. |
| SEO reads | Search-engine visibility, permalink and homepage setup, an on-page content audit, and which SEO plugin is running. |
| Content | List and read posts; create and edit drafts; publish as a separate action with its own permission; set SEO metadata. |
Four sentences somebody would type
- Which sites are still on an old WordPress?
- How many of these can actually run that action?
- Run it on everything tagged retail, then check it took.
- What ran on the Acme sites this month, and who approved it?
The guardrails inside the write actions
- No credential ever comes back. Creating a user or resetting a password emails a link to that person; no password appears in any result, log or audit entry.
- Setting changes are limited to a curated list — title, tagline, timezone, formats, posts-per-page, comment defaults, search visibility. Site URL, admin email and registration settings are excluded.
- Deleting a user refuses administrators and the agent account itself, and requires somewhere to reassign their content, so nothing is orphaned.
- Creating a user refuses any administrator-equivalent role.
- Content is draft-first. Creates and edits land as drafts, a published post can't be edited by the draft action, and publishing is governed separately.
Seeing what happened, and stopping it
- Every action Portcullis dispatches is recorded — what ran, on which site, who or what authorized it, and whether it succeeded. Admins can filter and export it as CSV or JSON. Kept 12 months.
- Disconnect a site from the dashboard (admin, plus a freshly proved factor) and Portcullis stops signing for it — it fails closed on the very next call, for every client at once.
- Or disconnect from the site, on the plugin's page. That removes the connection, the agent account, its role and stored settings. Your posts, pages and other content aren't touched.
One thing the audit log doesn't capture
The plugin keeps no log of its own, so if a WordPress admin switches an action off in the moment between Portcullis dispatching a request and the site checking it, the site's refusal isn't recorded on our side. Everything we dispatch, and every permissions edit, is.
This is deferred on purpose. The plugin holds no signing key, so it cannot prove anything it sends us is genuine — and an unauthenticated feed into an audit trail is worse than no feed. If we build it, we have to pull the log over our own trusted pass.
Limits & requirements
Every figure here is what the code enforces.
What you need
- WordPress 6.8 or newer, on a host that lets you install plugins
- WordPress's Abilities API — in core from WordPress 7.0, or the free Abilities API plugin on 6.8+. Every action runs through it, and we check for it before you connect.
- PHP 8.0 or newer
- One companion plugin per site — nothing added to your front end, no database tables created
- An MCP client, or nothing at all if you use the built-in assistant
Limits
- Up to 1,000 sites in a single fan-out job
- Up to 6 steps in one chained sequence
- Audit history kept 12 months, then pruned automatically
Protocols
- OAuth 2.1 + PKCE S256 (RFC 7636) — your AI client to Portcullis
- ES256, DPoP-bound (RFC 9449), ~60-second lifetime, scoped to one action — Portcullis to your site
- Model Context Protocol for any client you bring
- WordPress Abilities API (
wp-abilities/v1) on the site itself
Back to Getting started, or Connect your AI client. For the full threat model, see the security whitepaper.
Questions about the governance model? Email hello@portculliswp.com.