Real Authentication

Generating and Rotating Application Passwords for AI Clients

⏱ 13 min

Now that you know Application Passwords are the real credential behind every remote MCP connection, treat generating one as an actual access-control decision, not a five-second setup step. This lesson covers creating them properly, naming them so a future audit makes sense, and rotating or revoking them on a real schedule.

What you'll learn in this lesson
Generating an Application Password in wp-admin
The real UI path, under your user profile.
A naming convention that survives an audit
Encoding agent, environment, and purpose into the name itself.
Doing it from WP-CLI instead
wp user application-password create, for scripted or CI setups.
A rotation policy you will actually follow
When to rotate on a schedule, and when to rotate immediately.
Prerequisites

Lesson 1 (how authentication actually works). Admin access to a WordPress site running on HTTPS or localhost, since the Application Passwords UI is hidden otherwise.

Step 1: Generate one in wp-admin

Application Passwords are created per-user, under that user’s own profile screen, not in a central admin settings page.

1
Go to Users > Profile
Or Users > All Users > (your user) if generating one for a different account.
2
Scroll to the Application Passwords section
This section only appears over HTTPS or on localhost. If it's missing, your site is likely on plain HTTP.
3
Enter a descriptive name, not "MCP"
Something specific enough to identify later, covered in Step 2.
4
Click Add New Application Password
WordPress displays the generated password exactly once.
5
Copy it into your AI client's connection config immediately
You cannot view it again after leaving this screen, only revoke and reissue.
The password is shown once, period

There’s no “view password” option later. If you lose it, the only fix is revoking that entry and generating a new one. Store it in a password manager or your AI client’s own secret storage, never in a plaintext config file committed to a repository.

Step 2: Name it so an audit makes sense later

A generic name like “MCP” or “AI” tells you nothing six months from now when you’re reviewing every credential with access to your site. Encode three things in the name: which client, which environment, and roughly when or why.

Claude Desktop - Production - 2026-07
Cursor - Staging - content-editing-agent
n8n workflow - Production - order-lookup-readonly
One Application Password per client, always
Never share a single password across two different AI tools or agents.
Name includes the client and the environment
So a staging credential is never mistaken for a production one during a review.
Name includes a date or purpose
Makes it obvious during rotation which ones are stale or which are tied to a project that's since ended.

Step 3: Generate one from WP-CLI instead

For scripted setups, CI environments, or provisioning many agent accounts at once, WP-CLI’s application-password commands avoid the UI entirely:

# File: provision-agent.sh
wp user application-password create ai-agent-readonly "n8n workflow - Production - 2026-07"

This prints the generated password to stdout once. List existing ones for a user, or delete a specific entry by its UUID:

wp user application-password list ai-agent-readonly --fields=uuid,name,created
wp user application-password delete ai-agent-readonly 6633824d-c1d7-4f79-9dd5-4586f734d69e
WP-CLI output can end up in shell history or logs

If you run wp user application-password create interactively, the generated password prints to your terminal and may land in your shell history file. In CI, make sure the job’s log output isn’t captured somewhere less secure than the secret itself would be. Pipe it directly into your secrets manager rather than printing it as a bare step output.

Step 4: Set a rotation policy, and follow it

An Application Password with no expiry and no review cadence is a permanent, unmonitored credential. Treat rotation the same way you’d treat any API key.

Rotate on a fixed schedule for production agents
Quarterly is a reasonable default for anything with write access.
Rotate immediately on staff or vendor offboarding
If a team member who provisioned an agent credential leaves, rotate anything they created, don't assume it was scoped to only them.
Rotate immediately on suspected leak
A credential pasted into a public repo, a shared screenshot, a support ticket, any of these mean rotate now, not at the next scheduled review.
Never reuse a name after rotation
Increment the date or add a suffix, so old audit log entries still map to a specific, identifiable credential.

Test it: confirm a rotated password actually stops working

After revoking an old Application Password (Users > Profile > Application Passwords > Revoke), try the AI client’s existing connection again. It should fail authentication immediately, since Basic Auth is checked on every single request, there’s no cached session to also expire separately.

curl -u "ai-agent-readonly:old-revoked-password" https://your-site.test/wp-json/

You should get a 401 Unauthorized response. If you still get a successful response, you likely revoked the wrong entry, application passwords are per-user and per-entry, not global to the account.

Recap

Generate one Application Password per client, name it so it’s identifiable in an audit months later, and prefer WP-CLI for scripted or bulk provisioning. Set an actual rotation policy rather than treating these credentials as set-and-forget, and rotate immediately on any offboarding or suspected leak rather than waiting for the next scheduled review. Lesson 9 in this course covers the revocation side in more depth, once you have live agent connections worth revoking.

Resources & further reading

← How Authentication Actually Works in the MCP Adapter Permission Inheritance: How WordPress Roles Map to Agent Access →