Repository navigation
Add support for Dynamic Client Registration (RFC 7591) #13
Description
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 theEndpoints\Tokenpattern, registeringPOST /oauth2/registerininc/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. ExtendClient::create()and add post meta keys for the ones not already stored (onlytypeandredirect_uriexist today). - Validate per RFC 7591 §3.2.2: reject unknown
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. - Generate
client_idthe same wayClient::create()does today; generateclient_secretonly whentoken_endpoint_auth_methodisn'tnone(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 = 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. - Add
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. - Document the endpoint in
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/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).
Activity