I let an AI agent publish directly to this site, and the access I grant it is narrower than most people assume. It authenticates with a WordPress application password tied to a limited-role account, not my admin login. Every mutation — a new post, an edited meta field, a status change — passes through a recorded approval step first. The credential lives in a local file outside version control, and I can revoke it in one click without touching anything else. That is the actual model: gated authority and revocable credentials, not blind trust.
The access tiers I actually use
Before I gave an agent any access to this site, I split the possible actions into four tiers. I did this on paper first, then matched each tier to a real WordPress capability, because “the agent can help with SEO” is not a permission — it is a marketing phrase. A permission is something you can name, log, and revoke.
- Read-only audit. Pulling Search Console data, crawling live pages, checking status codes, comparing what is indexed against what is published. No write access anywhere. This is the largest share of what the agent actually does day to day.
- Content draft. Writing a post or editing a meta field, saved as a draft. Nothing goes live from this tier alone.
- Publish-with-approval. The agent can request a status change from draft to published, but the request is logged and requires a recorded decision before WordPress executes it.
- Never-grant. Site settings, user management, plugin installation, database access, billing. The agent has no path to any of these, by account role, not by instruction.
That last tier matters more than the first three combined. An instruction like “don’t touch billing” is a suggestion I could forget to include in a prompt. An account role that was never granted `manage_options` capabilities is a wall the agent cannot talk its way past, regardless of what any prompt says.
How this site scopes it
WordPress application passwords, a core feature since version 5.6, let you generate a unique password for a specific integration without exposing your main account password. That password authenticates API requests — it cannot be used to log into wp-admin through the normal login screen. Each one can be reviewed by name and revoked individually, without disturbing any other credential on the account.
Here is the part most people miss: WordPress does not scope an application password to specific endpoints or actions. The password inherits the full role and capability set of the user account it belongs to. There is no native setting that says “this password can publish posts but not delete pages.” The scoping has to happen one layer up, at the account itself.
So the agent on this site runs under a dedicated account with the Editor role, not Administrator. An Editor can create, edit, and publish posts and manage their own meta fields, but cannot install plugins, change site settings, add users, or touch anything requiring `manage_options` — the capability WordPress checks before administrative actions. I confirmed this the concrete way: the account’s password returned a 403 `rest_forbidden` error when a task tried to purge a sitemap cache, because that action needs `manage_options` and the account does not have it. That failure is a feature, not a bug I patched around.
The password itself lives in a local environment file, outside this repository. It is never written into a prompt, a log line, or a committed file. And the agent does not phone home with usage data beyond what WordPress itself logs against the account — no separate telemetry channel reporting what it read or drafted.
If you are setting this up yourself: create a new WordPress user, assign it Editor (or a role with even fewer capabilities if your workflow allows it), generate an application password on that account under Users → Profile → Application Passwords, and hand that credential to your agent. Never generate an application password on your own administrator account for this purpose. The password will carry every capability you have, and there is no dial to turn that down after the fact.
The approval gate is the real boundary
Role-based access answers “what could the agent technically do.” It does not answer “what did the agent actually do, and did a human agree to it.” That second question needs a separate mechanism, and on this site it is an approval gate that sits in front of every content mutation, not just the risky ones.
The pattern is consistent: a proposed change — a new brief, a draft ready to publish, a meta field edit — gets written to a record with a `status: proposed` field. Nothing executes from that state alone. A decision has to arrive through an approval channel and get recorded with who decided, when, and through what channel, before the record’s status can legally change to `approved`. Only then does the corresponding WordPress action run. If that decision record is missing any of those fields, the downstream publish step refuses to proceed rather than guessing at intent.
What makes this a security boundary and not just a workflow nicety is that it is enforced by the code path, not by convention. An agent that skipped the approval check and called the publish endpoint directly would still not be blocked at the WordPress layer — the Editor-role account has publish capability regardless. The gate is a rule this system’s own logic enforces before reaching the WordPress API, and it produces a persistent, append-only decision log as evidence: exactly which human approved which change, and when. Nothing in it gets edited after the fact — corrections are appended as new entries, never rewritten into old ones.
This brief and article are themselves an instance of the pattern: a proposal was written, a human approved it in a recorded session, and only that recorded approval unlocked drafting and publishing. You are reading the output of a gate, not a bypass of one.
Revocation and rotation
The value of scoping access this way shows up when something goes wrong, or looks like it might. Because the agent’s credential is a standalone application password on a limited-role account, the response to “something feels off” is one action: open Users → Profile → Application Passwords in wp-admin, find that password by name, and revoke it. Revocation is immediate and does not require changing the account’s main password or touching any other integration.
That is a meaningfully different recovery path than an agent running under a shared admin login, where revoking access means resetting a password used everywhere else too, then re-authenticating every legitimate integration that also relied on it. Narrow credentials are not just safer day to day. They are cheaper to cut off when you need to.
I do not treat “nothing has gone wrong yet” as a reason to leave a credential untouched indefinitely. Rotating the password on a schedule, and re-checking that the account role still matches only the tiers I want granted, costs a few minutes and closes the gap between “correct when I set it up” and “still correct now.” If you already monitor drift on your published content, extend that habit to the credential and role that produced it.
None of this makes an AI agent risk-free. It makes the risk boundaries explicit, narrow, and something you can point to. That is the standard I would want from any integration touching a production site, agent or not.
For more on what an AI SEO agent actually does day to day, see what is an AI SEO agent. For the difference between an agent like this and a rules-based automation tool, see AI SEO agent vs. SEO automation tool. If you want the mechanics of how this site’s agent actually publishes to WordPress, see WordPress SEO autopilot. And for how ongoing changes get caught after publish, see SEO drift monitoring.
What is a WordPress application password?
It is a unique, per-integration password, a core WordPress feature since version 5.6, that authenticates API requests without exposing your main account password. It cannot be used to log into wp-admin through the normal login form, and it can be individually reviewed and revoked without affecting any other credential on the account.
Can you limit exactly what an AI agent’s WordPress password can do?
Not directly. WordPress does not scope an application password to specific endpoints or actions — it inherits the full role and capabilities of the user account it belongs to. The way to limit it is to put the password on a dedicated, reduced-privilege account, such as Editor instead of Administrator, rather than trying to restrict the password itself.
Should an AI agent be able to publish content without human approval?
On this site, no. Every status change from draft to published passes through a recorded approval step with a named decision, actor, channel, and timestamp before it executes. The publish capability exists at the account-role level, but the approval gate is a separate, enforced check in front of it.
What should you never grant an AI SEO agent access to?
Site settings, user management, plugin installation, database access, and billing. These sit outside what a content-focused Editor role can touch, so the boundary is enforced by account role rather than by instruction alone.

Leave a Reply