You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add an OAuth2 Dynamic Client Registration endpoint (RFC 7591) so clients can register themselves at /oauth2/register instead of requiring an admin to create an oauth2_client post by hand. This is the missing piece for MCP-style and other automated clients to onboard without manual setup, and pairs with #12 (discovery should advertise a registration_endpoint once this exists).
Clients are stored today as oauth2_client posts (inc/class-client.php): post_name is the client_id, post_status gates approval (draft → publish), and secret/type/redirect_uri live in post meta. DCR needs to register through that same model, so most of the work is a new endpoint plus filling in metadata fields the model doesn't capture yet.
Implementation plan:
Add Endpoints\Registration (inc/endpoints/class-registration.php), following the Endpoints\Token pattern, registering POST /oauth2/register in inc/endpoints/namespace.php.
Accept the RFC 7591 §2 metadata fields: redirect_uris, token_endpoint_auth_method, grant_types, response_types, client_name, client_uri, logo_uri, scope, contacts, tos_uri, policy_uri, jwks_uri. Extend Client::create() and add post meta keys for the ones not already stored (only type and redirect_uri exist today).
Validate per RFC 7591 §3.2.2: reject unknown grant_types/response_types, require redirect_uris (subject to Match redirect URIs exactly, not just scheme/host/port/path #7's exact-match rule), restrict token_endpoint_auth_method to none / client_secret_post / client_secret_basic.
Generate client_id the same way Client::create() does today; generate client_secret only when token_endpoint_auth_method isn't none (public client).
Return the RFC 7591 §3.2.1 response: client_id, client_secret (if issued), client_id_issued_at, client_secret_expires_at (0, matching that secrets don't expire elsewhere in this plugin), plus the metadata echoed back.
Decide the approval story and document it in the issue/PR: does a self-registered client land as post_status = draft like a manually-created one (blocking use until an admin approves it), or is it usable immediately? Open registration with immediate use is a spam/abuse vector worth deciding deliberately rather than defaulting into.
Add tests/test-registration-endpoint.php (pattern: tests/test-token-endpoint.php) covering a minimal valid registration, a missing/invalid redirect_uris, an unsupported grant_type, and the public-vs-confidential response shape.
Out of scope for this issue, filed separately once this lands: RFC 7592 (the client configuration management protocol — GET/PUT/DELETE on a client's own registration via a registration_access_token).
Related: #1 (PKCE — self-registered public clients should get the same "Require PKCE" treatment), #3 (confidential client authentication — a DCR-issued client_secret needs somewhere real to be checked), #7 (redirect_uri matching), #12 (discovery should list registration_endpoint).
Add an OAuth2 Dynamic Client Registration endpoint (RFC 7591) so clients can register themselves at
/oauth2/registerinstead of requiring an admin to create anoauth2_clientpost by hand. This is the missing piece for MCP-style and other automated clients to onboard without manual setup, and pairs with #12 (discovery should advertise aregistration_endpointonce this exists).Clients are stored today as
oauth2_clientposts (inc/class-client.php):post_nameis the client_id,post_statusgates approval (draft → publish), and secret/type/redirect_uri live in post meta. DCR needs to register through that same model, so most of the work is a new endpoint plus filling in metadata fields the model doesn't capture yet.Implementation plan:
Endpoints\Registration(inc/endpoints/class-registration.php), following theEndpoints\Tokenpattern, registeringPOST /oauth2/registerininc/endpoints/namespace.php.redirect_uris,token_endpoint_auth_method,grant_types,response_types,client_name,client_uri,logo_uri,scope,contacts,tos_uri,policy_uri,jwks_uri. ExtendClient::create()and add post meta keys for the ones not already stored (onlytypeandredirect_uriexist today).grant_types/response_types, requireredirect_uris(subject to Match redirect URIs exactly, not just scheme/host/port/path #7's exact-match rule), restricttoken_endpoint_auth_methodtonone/client_secret_post/client_secret_basic.client_idthe same wayClient::create()does today; generateclient_secretonly whentoken_endpoint_auth_methodisn'tnone(public client).client_id,client_secret(if issued),client_id_issued_at,client_secret_expires_at(0, matching that secrets don't expire elsewhere in this plugin), plus the metadata echoed back.post_status = draftlike a manually-created one (blocking use until an admin approves it), or is it usable immediately? Open registration with immediate use is a spam/abuse vector worth deciding deliberately rather than defaulting into.tests/test-registration-endpoint.php(pattern:tests/test-token-endpoint.php) covering a minimal valid registration, a missing/invalidredirect_uris, an unsupportedgrant_type, and the public-vs-confidential response shape.docs/spec.md, which currently only covers OAuth 1.0a (also relevant to Replace the OAuth 1.0a documentation #10).Out of scope for this issue, filed separately once this lands: RFC 7592 (the client configuration management protocol —
GET/PUT/DELETEon a client's own registration via aregistration_access_token).Related: #1 (PKCE — self-registered public clients should get the same "Require PKCE" treatment), #3 (confidential client authentication — a DCR-issued
client_secretneeds somewhere real to be checked), #7 (redirect_uri matching), #12 (discovery should listregistration_endpoint).RFC: https://www.rfc-editor.org/rfc/rfc7591