Proposal for supporting "client discovery" in OIDC / OAuth2

Issue #1589 resolved
Tobias Looker created an issue

Background

The client_id parameter in OIDC and OAuth2 is used by the client to identify itself to the AS. The assumption is in most cases that this ID is allocated by the AS via a registration process supported by the AS, relevant extract from the RFC below

The authorization server issues the registered client a client
identifier -- a unique string representing the registration
information provided by the client.  The client identifier is not a
secret; it is exposed to the resource owner and MUST NOT be used
alone for client authentication.  The client identifier is unique to
the authorization server.

In industry the predominant pattern used is for the AS to assign client id’s to clients via an out of band registration process.

To support a more dynamic relationship between clients and AS’s, dynamic client registration was standardised first in OpenID then back ported to OAuth2 later. However this model has some challenges/downsides including

  1. How to appropriately limit registration requests
  2. Requires a pre-flight request by the client to AS to register before making an authorisation request
  3. Can require the client to manage state with various AS’s, e.g which the client is registered with and if so whats its client id

More recently via the OpenID federation specification, the concept of “automatic registration” has emerged where the client provides a resolvable identifier such as a URL that the AS can resolve to fetch the clients metadata but in a specific process designed primarily to serve its use cases.

Proposal

The intent of this issue is to discuss whether generalising the “automatic registration” mode or mechanism currently defined in the openid federation spec is worth considering for other usecases.

If so I believe its best framed as a new concept for clients and I’d offer the term “client discovery” as the way to describe it. The intent would be to describe a way that a client can make it self discoverable to an OP/AS in the same way an OP/AS makes it self discoverable to a client today with openid discovery.

The crux of the proposal would be for a new request parameter client_discovery to be supported on the authorise request that when processed by a supporting OP/AS would indicate that the client_id value supplied is infact a URL that should be resolved to obtain the clients metadata, instead of trying to make sense of the value amongst existing registered clients.

An example request might look like

  HTTP/1.1 302 Found
  Location: https://server.example.com/authorize?
    response_type=code
    &scope=openid%20profile%20email
    &client_id=https%3A%2F%2Fclient.example.org
    &client_discovery=true
    &state=af0ifjsldkj
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb

Where the AS/OP would execute the following request to obtain the clients metadata

GET /.well-known/client-metadata HTTP/1.1
  Host: client.example.org

Which would return a JSON based object containing the registration parameters described in OpenID Dynamic Client registration.

There would potentially also be caching considerations for the client metadata that could be added (e.g HTTP request caching) to limit how often an AS/OP needs to actually resolve the clients ID.

Why

There are several applications within the OIDC4SSI ecosystem that would benefit from an alternative mechanism to dynamic client registration being defined that does not suffer the same tradeoffs as listed above.

Note - SIOP does also reference the federation spec for this feature currently, so by separating this would perhaps help to clarify the generalised usage of the feature for other applications.

Comments (15)

  1. David W Chadwick

    This issue has many simularities to issue #1551 `administrative trust in the RP'. Both want to achieve the same objective i.e. allow the Authz server to dynamically establish communications with an unknown RP. Whilst the Federation approach works for ASs and RPs that support Federation it does not work for those that do not.

    Thus I would propose extending the syntax of this proposal to include the URI of the type of trust federation that the RP is a member of, coupled with the ID of the specific federation (as prescribed by that type of federation). In this way, the AS can first determine if they are using the same type of trust federation, and if they are, which specific trust federation they are both members of, and if they are, it can then go on to discover the metadata of this particular RP. It would be rather pointless fetching the metadata of an RP that the AS knows is not part of its federation and therefore cannot be trusted. (Note, we could specify a default of ‘no federation’ if that makes sense, for ASs and RPs that are not in any federation, but I am not sure that OpenID allows for this).

  2. Tobias Looker reporter

    David, I think it comes down to when and how the AS comes to know whether the client is in a federation or trusted by some external party that the AS also trusts. I would posit the easiest way to do this is for the client to list any external attestations about it, in its client metadata. Therefore the mechanism I describe above still applies its just the AS is looking for some specific metadata it can use to establish trust in the client.

  3. David W Chadwick

    Agreed, What I am proposing is indeed to list this information in the client metadata, as per my PR #255. But since you are also proposing to carry a pointer to the metadata in the initial request to the AS, then I am suggesting that this message also carries the trust information as well. In this way the metadata will never need to be retrieved if the AS knows it cannot trust the client.

  4. Thomas Bellebaum

    There are two messages in a dynamic client registration: First, the client candidate sends a request for particular metadata values to the AS (this is similar to providing the metadata at a URI), but then the AS also gets to have a say in the final values and informs the client of its actual metadata at the AS.

    Consider this from a usability perspective: The not-yet-registered client has no insurance that its request will be accepted by the AS. If the server decides that the client is unacceptable (which it may do for whatever reason), it will not register the client, will not accept the redirect_uri and the user agent ends up at an error page at the AS. For traditional deployments, this is not a problem. While performing dynamic client registration, the user agent is still with the client, so if anything goes wrong, it can handle the error in a way that makes sense for the client’s processes.

  5. Tobias Looker reporter

    Good points, however could we not establish the same behaviour in the model I outlined, e.g if the AS was un-willing to accept the clients metadata it could just error in the authorisation request?

  6. Tobias Looker reporter

    Something worth highlighting that I didn’t originally which is if the establishing a level of trust in the client is important to the AS, then I believe this “client discovery” model provides something unique over dynamic client registration. For instance a malicious client trying to impersonate as https://client.example.org by setting their client_id to this in their request would be unable to receive the response because their redirect URI (assuming the redirect url is say HTTPS based) must be registered under the JSON document returned from the /.well-known/client-metadata endpoint. When in the most basic dynamic client registration model, the client metadata is effectively self attested by the client instance so it can be harder to establish trust in the client.

  7. Vladimir Dzhuvinov

    In traditional dynamic client registration the URL that identifies the client is the redirect_uri. This is the location where the authorisation responses will go, and if it doesn't belong to the client it won't get the responses. This means that the redirect URL can also play the role of a client_id. In this regard the redirect_uri trust in dynamic client registration is not lesser than with a /.well-known/client-metadata that publishes the redirect_uri.

    Do you envision confidential clients with this client discovery mechanism and if so what kind of methods for them to authenticate at the token endpoint?

  8. Tobias Looker reporter

    In traditional dynamic client registration the URL that identifies the client is the redirect_uri. This is the location where the authorisation responses will go, and if it doesn't belong to the client it won't get the responses. This means that the redirect URL can also play the role of a client_id. In this regard the redirect_uri trust in dynamic client registration is not lesser than with a /.well-known/client-metadata that publishes the redirect_uri.

    Yes totally agree with this perspective.

    Do you envision confidential clients with this client discovery mechanism and if so what kind of methods for them to authenticate at the token endpoint?

    Yes and this is where I think discoverable clients becomes even more powerful. A confidential client for example could publish its public key in its metadata and then sign the authorise or token requests it sends to the AS, which the AS can then verify against the client without any pre-registration step (dynamic or otherwise).

    I think there is also new options around client authentication for what we would traditionally have referred to as public clients too. For instance a native application that is able to generate a key pair that has an attestation from the OS provider could use this to sign authorise and token requests it sends to the AS, of course the resolved client metadata in this case would need to include new elements that relate to how to validate such a key attestation.

  9. Kristina Yasuda

    I want to make sure we keep an option to use DIDs as a client_id and as a mechanism to discover `client_metadata` file

  10. Michael Jones

    As discussed during the 3-Oct-22 working group call, OpenID Connect Federation already defines the Automatic Client Registration mechanism to accomplish this. It’s applicable beyond the scope of Connect Federations, as evidenced by its use by SIOPv2.

    It would be my suggestion that if an OAuth draft is written to enable use of clients without pre-registration, that it be 100% compatible with this OpenID Connect functionality, just OAuth Dynamic Client Registration, OAuth Authorization Server Metadata, and OAuth JWS Authorization Request (JAR) were compatible with the original OpenID Connect specifications of their functionality.

  11. David W Chadwick

    We need to think at a higher level in order to resolve this issue as it is not just a technical protocol problem but also an administrative trust problem. We need to consider what GAIN is doing in this area, as it envisages that trust in different federations needs to support different trust methods at the administrative level. So before we assume that OIDC Federation is being used, we should appreciate that GAIN does not assume that. GAIN recognises that several different adminisitrative trust methods exist. Issue #1551 `administrative trust in the RP' is in line with this thinking. It allows the RP to say which administrative trust method(s) its federation uses. If the AS sees that they both support the same trust method (which could be OIDC Federation), then it knows that it can establish administrative trust in the RP. (If there is no common trust method then communication will cease with an appropriate error message.) Once the AS knows that it can establish administrative trust it can use use the technical protocols of that method to establish trust in the RP. And this is when OIDC Federation will start to be used.

  12. Tobias Looker reporter

    client_id_scheme is client discovery just by a different name, agree this has been addressed

  13. Log in to comment