Skip to content

Add application password authorization flow to wp-login.php#551

Open
obenland wants to merge 7 commits intoWordPress:trunkfrom
obenland:add/login-application-passwords
Open

Add application password authorization flow to wp-login.php#551
obenland wants to merge 7 commits intoWordPress:trunkfrom
obenland:add/login-application-passwords

Conversation

@obenland
Copy link
Member

@obenland obenland commented Feb 11, 2026

Summary

Adds an authorize_application action to wp-login.php that lets users create application passwords through the login flow. Requests are validated against a UUID-based allowlist. After approval, the MCP client configuration is rendered with a copy button for easy setup.

Not sure if this UUID-gating is strictly needed but I thought I'd be a bit conservative to start out with.
I suppose at some point we'd want an application password management UI in profiles.wordpress.org.

Login prompt

When visiting the authorization URL while logged out, a contextual message is shown:

Screenshot 2026-02-11 at 2 04 26 PM

Authorization form

After logging in, the user can approve or reject the connection:

Screenshot 2026-02-11 at 2 04 48 PM

MCP configuration

On approval, the ready-to-use MCP client config is displayed with per-client setup instructions:

Screenshot 2026-02-11 at 2 04 55 PM

TODO

  • Gate to login.wordpress.org.
  • Only show MCP config when creating app password for the MCP app.

Test plan

  • Visit wp-login.php?action=authorize_application&app_id=c4c73a54-96d7-47b9-9bdc-1a66b9b04505 while logged out and verify redirect to login form with contextual message.
  • Log in and verify the authorization form renders correctly.
  • Approve and verify the MCP configuration is displayed with the correct credentials.
  • Copy the config and verify it works with an MCP client.
  • Reject and verify redirect to wp-admin.
  • Verify that an invalid or missing app_id is rejected.
  • Verify that providing success_url or reject_url for the MCP app (which has empty hosts) is rejected.
  • Re-approve and verify the previous application password is revoked before creating a new one.

…n.php.

Provides a login-based authorization flow for creating application
passwords, gated by a UUID-based app allowlist. After approval,
renders the MCP client configuration for easy copy-paste setup.
@github-actions
Copy link

github-actions bot commented Feb 11, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props obenland, dd32.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@obenland
Copy link
Member Author

@dd32 When you get a chance, I'd appreciate any feedback you have on this. Naming, file location, stuff I missed, anything. Thank you!

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an application-password authorization flow to wp-login.php?action=authorize_application for a UUID-allowlisted set of apps, enabling users to approve/reject and (for the MCP app) obtain a ready-to-copy MCP client configuration.

Changes:

  • Introduces a new login_form_authorize_application handler that validates requests, renders an approval form, and creates/revokes application passwords.
  • Adds login-page contextual messaging and custom styling for the new action.
  • Renders an MCP client configuration (with copy button + client notes) after approval for the allowlisted MCP app.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Guard wporg_render_mcp_config with an app_id check so it only
renders for the WordPress.org MCP application, not for any other
app that may be added to the allowlist in the future.
…ison.

Remove redundant urlencode() calls in add_query_arg() which already
handles encoding internally. Normalize hostnames to lowercase before
comparing against the allowlist since DNS is case-insensitive.
…ress.org.

Only load the mu-plugin on blog ID 350 (login.wordpress.org) so the
authorization flow is not available on other sites in the multisite.
Copy link
Member

@dd32 dd32 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for code location.. I don't really mind where this lives. This seems like something that could be upstreamed to WordPress core perhaps, as a front-end UI for the existing wp-admin authorize application flow. It seems this has a few things in it that are very WordPress.org specific, and that's OK.

wporg-sso plugin has a bunch of logic related to login in it. I don't really like that.
wporg-login theme has a bunch of logic in it. I also don't really like that.

I assume this is intentionally open to accepting literally any redirect location at present, and that we might look at changing it to a more strict host set before deploy? Otherwise, what's the point of an application allow list.. the UUIDs would be public knowledge..

Co-authored-by: Dion Hulse <dd32@dd32.id.au>
@obenland
Copy link
Member Author

I assume this is intentionally open to accepting literally any redirect location at present

Each app in the allowlist has a hosts array that controls which domains success_url/reject_url may point to. The MCP app has an empty hosts array, which means no callback URLs are accepted at all (the validation rejects any URL when hosts is empty). A future app that needs redirects would specify its allowed domains there. Knowing the UUID shouldn't let you redirect anywhere.

…uthorization.

Encode values passed to add_query_arg() to match core's authorize-application.php,
use null-coalesce consistently, and remove redundant comment.
@dd32
Copy link
Member

dd32 commented Feb 13, 2026

The MCP app has an empty hosts array, which means no callback URLs are accepted at all (the validation rejects any URL when hosts is empty).

@obenland OH! I didn't realise it just then prompted, I was thinking it just allowed an open-redirect with no hosts 🙃 which as you can imagine... concerned me :)

@obenland
Copy link
Member Author

Yeah, I think that's how the current Core version works. The form shows the URL that it'll redirect to, but it mostly seems to rely on users knowing what they're doing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants