Proposal for supporting "client discovery" in OIDC / OAuth2
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
- How to appropriately limit registration requests
- Requires a pre-flight request by the client to AS to register before making an authorisation request
- 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)
-
-
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.
-
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.
-
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. -
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?
-
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. -
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?
-
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.
-
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
-
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.
-
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.
-
has this been addressed by the introduction of the
client_id_scheme
parameter? -
and potentially obsoleted by the client attestation IETF draft adoption?
-
reporter client_id_scheme is client discovery just by a different name, agree this has been addressed
-
- changed status to resolved
- Log in to comment
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).