Skip to content

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

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

Add application password authorization flow to wp-login.php#551
obenland wants to merge 11 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.

@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.

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..

@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.

@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

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.

I'm not seeing any issues with this PR, code-wise, maybe a mu-plugin isn't ideal, we could just use a regular plugin that's activated on login.w.org, but I don't really have a big opinion on that :)

I think long-term this should probably be in core, as the wp-admin authorize endpoint is IMHO less ideal than it could be.

I guess the question stands on whether most WordPress users would expect that they could be prompted by an arbitrary application :)

Comment on lines 24 to 29
return array(
'c4c73a54-96d7-47b9-9bdc-1a66b9b04505' => array(
'name' => 'WordPress.org MCP',
'hosts' => array(),
),
);
Copy link
Member

Choose a reason for hiding this comment

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

We should probably wrap this in a filter I guess.

obenland and others added 11 commits February 17, 2026 13:50
…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.
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.
Co-authored-by: Dion Hulse <dd32@dd32.id.au>
…uthorization.

Encode values passed to add_query_arg() to match core's authorize-application.php,
use null-coalesce consistently, and remove redundant comment.
…ode.

- Replace hardcoded app list with `wporg_login_application_passwords_allowed_apps` filter
- Validate filter output with `_doing_it_wrong` for malformed entries
- Default `hosts` to empty array via `wp_parse_args`
- Add app hosts to `allowed_redirect_hosts` for `wp_safe_redirect`
- Remove `wporg_render_mcp_config` and MCP-specific CSS (moving to wporg-abilities)
- Improve escaping throughout
…iles.

Introduces `MCP_Authorization` in `clients/mcp/` to register the
WordPress.org MCP server via the new allowed-apps filter and render
the client configuration after password creation.

Moves inline CSS and JS into enqueued files:
- `css/authorize-application.css` for the base authorization form.
- `clients/mcp/style.css` for MCP config display styles.
- `clients/mcp/copy-config.js` for the copy-to-clipboard button.
@obenland obenland force-pushed the add/login-application-passwords branch from 78ccbc3 to e531df7 Compare February 17, 2026 19:58
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