workers-oauth-provider icon indicating copy to clipboard operation
workers-oauth-provider copied to clipboard

[Feature request] `/register` endpoint should support access token

Open pcan opened this issue 7 months ago • 4 comments

Currently the OAuthProviderImpl.handleClientRegistration method does not provide any kind of authentication, thus letting any client to register. In some cases, this may be a security issue if malicious clients present themselves as legit services to the end user. E.g. a malicious actor may convince a user to navigate to a fake ChatGPT-like website, which register itself through the /register endpoint, and then it's able to access user data, once the user gives permission. As recommended here there should be support for an initial access token exchange between parties, in order to only allow trusted client applications to invoke the /register endpoint. In some cases this is not strictly necessary, but there should be an option to support it. The current workaround is to wrap the OAuthProvider.fetch() method to check for /register authentication. An optional callback parameter could be added to OAuthProviderOptions to better support this use case.

pcan avatar May 19 '25 09:05 pcan

Hmm, I don't quite understand. Where does this access token come from, if the client is not registered yet? Don't you need a client_id to get an access token in the first place?

More abstractly, what is the purpose of supporting dynamic client registration, but then locking it down to only "trusted" clients? If you only trust certain clients, shouldn't they be registered upfront?

The library does allow you to disable dynamic registration, and instead implement your own custom registration flow, if you so desire -- the env.OAUTH_PROVIDER API has methods to create and modify registrations, which you could use behind your own custom registration endpoint, while disabling the standard one.

But my understanding is that MCP clients today expect to be able to register dynamically, and they expect there to be no access control on the registration endpoint. So introducing access control or a custom registration process would seemingly make you incompatible with most MCP clients, I think? Or do they implement some standard for this that I missed?

kentonv avatar May 19 '25 18:05 kentonv

I'm quoting the standard:

The OpenID Provider MAY require an Initial Access Token that is provisioned out-of-band (in a manner that is out of scope for this specification) to restrict registration requests to only authorized Clients or developers.

There are some scenarios that benefit the exchange of an initial access token (which may not be supported by all clients), but it's definitely part of the standard. I understand that the maintainers may have no interest in implementing this part of the standard. As long as there are workarounds, this is not an issue, other than having some friction in the DX.

EDIT: I quoted the OIDC spec, but the same is present in the DCR RFC itself.

pcan avatar May 19 '25 19:05 pcan

OK so basically the RFC says:

   (A)   Optionally, the client or developer is issued an initial access
         token giving access to the client registration endpoint.  The
         method by which the initial access token is issued to the
         client or developer is out of scope for this specification.

So the standard says you can do it but doesn't say anything at all about where the token comes from or how it should be authenticated. This implies that for a client and server to actually use such a mechanism, there has to be some additional agreement between them about how the token is issued and checked. There's not enough information here to actually build a server that any existing client can actually connect to -- you have to know, separately, what convention those existing clients are following.

Can you point me at any such documented convention? Examples of who uses this today? Are there any well-known MCP clients that can use this, for example? It'd be great to understand in particular what the benefit would be of issuing an access token for this purpose as opposed to just doing the client registration non-dynamically.

Otherwise it's pretty hard to design an implementation without understanding how it would be used in practice.

kentonv avatar May 19 '25 19:05 kentonv

there has to be some additional agreement between them about how the token is issued and checked.

This is correct. I'll make an example of real use case to expand on this part, and where in the business this is helpful (and sometimes required). Let's assume there is a multi-tenant service named MyDocumentCloud (resource server), that contains user/customer data. This may be sensitive data (legal, financial, health, etc), that is, access is regulated or subject to some verification process to comply with the law. Users can autonomously create an account and pay for the services the MyDocumentCloud offers. The company that owns MyDocumentCloud wants to provide additional functionalities through partners (or vendors), and want to leverage a standard to let them onboard in a self-service manner. However, before enabling the technical process that allows partners to onboard, MyDocumentCloud must perform some verification to comply with regulations, for each partner. These verifications are not technical, but mostly bureaucratic (e.g. compliance). Once MyDocumentCloud validates the compliance level of each individual partner, they provide an access token (valid for a short time) in order to allow the partner to onboard in a self-service manner, through DCR. The way this token is exchanged can be through a shared password vault, a secrets manager or other similar means, this is not relevant. What is important is the the trust that is established before allowing the partner to self-register. If MyDocumentCloud cannot guarantee to their customers that only trusted and compliant partners can potentially have access to their data, it's going to lose its compliance. This is even more applicable when the customer is not a user, but another company, which requires the entire compliance chain (that is, the service and all the vendors it relies on) to be verified before they can sign their contract for the service. The implication, of course, is that MyDocumentCloud will not be able to integrate with many services out there that assume the registration is open, but this is actually desirable in this scenario.

Are there any well-known MCP clients that can use this, for example?

This is not trivial, unfortunately. There may be vendors out there supporting both cases (with/without initial auth token), but when they need to sign an agreement, I'm quite sure there's no much technical effort to support the initial auth, on the client side.

P.S. Regarding the implementation, my suggestion is it could be as simple as adding an optional callback invocation (provided as an optional config parameter) before this line. The callback may receive request headers (or the entire Request object) and return a boolean, for example.

pcan avatar May 20 '25 06:05 pcan