Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change client_id_scheme to a prefix #263

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

danielfett
Copy link
Contributor

@danielfett danielfett commented Sep 13, 2024

Solves #124 by removing client_id_scheme as a separate parameter and making it a prefix instead. entity_id was renamed to https in order to avoid breaking OpenID Federation.

Fixes #124
Fixes #29

Copy link
Collaborator

@Sakurann Sakurann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the cleanest approach that solves main security problem while not breaking other specifications like OpenID Federation and DIDs, while following OAuth 2.0 principle of client_id/aud uniquely identifying the client throughout the transaction

openid-4-verifiable-presentations-1_0.md Outdated Show resolved Hide resolved
openid-4-verifiable-presentations-1_0.md Outdated Show resolved Hide resolved
@jogu
Copy link
Collaborator

jogu commented Sep 13, 2024

Thanks Daniel!

One final thought: I am dubious about adding the prefix to pre-registered client ids. I don't think it actually really matters for VP, but I think it creates a clear gap as there's no way it could be accepted in normal OAuth, and if might be better if we chose something that could potentially eventually make it into an OAuth standard. Would removing the prefix for pre-registered clients and saying this work:

pre-registered client ids MUST NOT contain :

@@ -457,9 +471,9 @@ Location: https://client.example.org/universal-link?
8%22%5D%7D%7D%7D
```

* `entity_id`: This value indicates that the Client Identifier is an Entity Identifier defined in OpenID Federation [@!OpenID.Federation]. Processing rules given in [@!OpenID.Federation] MUST be followed. Automatic Registration as defined in [@!OpenID.Federation] MUST be used. The Authorization Request MAY also contain a `trust_chain` parameter. The final Verifier metadata is obtained from the Trust Chain after applying the policies, according to [@!OpenID.Federation]. The `client_metadata` parameter, if present in the Authorization Request, MUST be ignored when this Client Identifier scheme is used.
* `https`: This value indicates that the Client Identifier is an Entity Identifier defined in OpenID Federation [@!OpenID.Federation]. Since the Entity Identifier already is defined to start with `https:`, the `https` does not need to be prefixed additionally. Processing rules given in [@!OpenID.Federation] MUST be followed. Automatic Registration as defined in [@!OpenID.Federation] MUST be used. The Authorization Request MAY also contain a `trust_chain` parameter. The final Verifier metadata is obtained from the Trust Chain after applying the policies, according to [@!OpenID.Federation]. The `client_metadata` parameter, if present in the Authorization Request, MUST be ignored when this Client Identifier scheme is used. Example Client Identifier: `https://federation-verifier.example.com`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* `https`: This value indicates that the Client Identifier is an Entity Identifier defined in OpenID Federation [@!OpenID.Federation]. Since the Entity Identifier already is defined to start with `https:`, the `https` does not need to be prefixed additionally. Processing rules given in [@!OpenID.Federation] MUST be followed. Automatic Registration as defined in [@!OpenID.Federation] MUST be used. The Authorization Request MAY also contain a `trust_chain` parameter. The final Verifier metadata is obtained from the Trust Chain after applying the policies, according to [@!OpenID.Federation]. The `client_metadata` parameter, if present in the Authorization Request, MUST be ignored when this Client Identifier scheme is used. Example Client Identifier: `https://federation-verifier.example.com`.
* `https`: This value indicates that the Client Identifier is an Entity Identifier defined in OpenID Federation [@!OpenID.Federation]. Since the Entity Identifier already is defined to start with `https:`, the `https` is not prefixed additionally. Processing rules given in [@!OpenID.Federation] MUST be followed. Automatic Registration as defined in [@!OpenID.Federation] MUST be used. The Authorization Request MAY also contain a `trust_chain` parameter. The final Verifier metadata is obtained from the Trust Chain after applying the policies, according to [@!OpenID.Federation]. The `client_metadata` parameter, if present in the Authorization Request, MUST be ignored when this Client Identifier scheme is used. Example Client Identifier: `https://federation-verifier.example.com`.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to prescribe OpenID Federation as the only way metadata could be resolved from the client ID when it is an HTTPS url. There are multiple well-known metadata locations proposed for client metadata and a similar precedent exists within OAuth/OpenID for IDP / Authorisation Server metadata.

Copy link
Collaborator

@jogu jogu Sep 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention is that federation is the only thing that uses the https client id scheme, and this doesn't stop a well-known based client id scheme being created, it would just use a client_id like wellknown:https://rp.example.com/.

If you think the text isn't conveying this could you suggest alternative wording please?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* `https`: This value indicates that the Client Identifier is an Entity Identifier defined in OpenID Federation [@!OpenID.Federation]. Since the Entity Identifier already is defined to start with `https:`, the `https` does not need to be prefixed additionally. Processing rules given in [@!OpenID.Federation] MUST be followed. Automatic Registration as defined in [@!OpenID.Federation] MUST be used. The Authorization Request MAY also contain a `trust_chain` parameter. The final Verifier metadata is obtained from the Trust Chain after applying the policies, according to [@!OpenID.Federation]. The `client_metadata` parameter, if present in the Authorization Request, MUST be ignored when this Client Identifier scheme is used. Example Client Identifier: `https://federation-verifier.example.com`.
* `https`: This value indicates that the Clients metadata is available at a well-known location such as defined in [@!OpenID.Federation]. Processing rules for retrieving and validating the metadata for the well-known location being used, such as that given in [@!OpenID.Federation] MUST be followed. The `client_metadata` parameter, if present in the Authorization Request, MUST be ignored when this Client Identifier scheme is used. Example Client Identifier: `https://federation-verifier.example.com`.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't reflect the intention though. If people want to use https urls with a different resolution method, they use a client id scheme other than https, e.g. wellknown:https://rp.example.com/. The "https" client-id scheme is reserved for federation only.

Avoiding the vagueness of "I'm going to somehow authenticate with you using this url, you go figure out how you think I'm trying to authenticate with you" is very much the point. If you think of the browser API, using the https client id scheme to reflect multiple ways the wallet can authenticate, can result in lots of deadends as the sandboxed wallet matcher is now unable to know if it supports the method the wallet is using to authenticate, because it literally doesn't know how the wallet is trying to authenticate and has no way to find out because it can't access the network.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@selfissued I'll change this to a "MUST NOT be prefixed" to be very clear.

@tplooker @jogu I agree with Joseph here. This is an opportunity to have a clearly defined mechanism both from a security point of view and from an implementation perspective. Unless there is a good reason to not prefix other https-based client id schemes, we should avoid it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Federation is an overly complicated mechanism for a client to simply convey its metadata at a well-known location, I don't believe we should be promoting it as the preferred mechanism for clients that are choosing to identify via an HTTPS url which is what this proposal does. It relegates other HTTPS based url based client metadata discovery mechanism to requiring a double prefix style client id which I don't think is a clean solution.

If we would prefer to have less ambiguity then the text I suggested, I propose we have a seperate parameter to convey the metadata location for the client such as client_metadata_location=federation.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tplooker Is it going to be any different than client_id_scheme for https-based urls?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear, we are not promoting federation as a preferred mechanism. We are merely acknowledging that federation is already the long established way of client's using self-allocated client_ids beginning with https: and that there's not really any option open to us of changing that position.

The alternative (following in the vein of this PR) is that federation is also prefixed, but that introduces interoperability issues / confusion and still doesn't solve the 'clean solution' problem.

I think if we do want to do something that is a generic scheme based on https urls (and I think that could be a good idea), we need to do that with a prefix, otherwise we're going to overlap and/or conflict with at least two other different specifications. It's simply not sustainable or sensible to have multiple specs trying to define self-assert client ids that are pure https urls. Even federation probably shouldn't be doing it, but that ship has mostly sailed.

Copy link
Member

@selfissued selfissued left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved with requests for clarifying changes.

@jogu jogu added this to the Final 1.0 milestone Sep 13, 2024
Copy link
Member

@c2bo c2bo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are quite a few files in the diagrams folder that use client_id_scheme & client_id - should those be changed as well?


Important: Without the prefix, the `orig_client_id` is not sufficient to identify the Verifier, as different Verifiers (under control by different entities and using different cryptographic material) might have the same `orig_client_id` within different `client_id_scheme` namespaces. Therefore, `orig_client_id` MUST NOT be used independently within the context of the Wallet or its responses to identify the client. Only the full string `<client_id_scheme>:<orig_client_id>` is the Client Identifier of the Verifier, in particular in places where the Client Identifier is used in [@!RFC6749] and in the presentation returned to the Verifier.

Note that the Verifier needs to determine which Client Identifier schemes the Wallet supports prior to sending the Authorization Request in order to choose a supported scheme.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I've highlighted before this is a huge limitation of this approach and is the basis of discussion in #248 and #247. It essentially means that there needs be some form of out of band negotiation model in order for a verifier to pick the right scheme. I don't see how this is practically possible.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in #248 allow this to work and can be easily updated to work with the changes in this PR (i.e. putting everything in client_id instead of having a separate client_id_scheme in the unprotected header). I can't see any real practical issues with that approach.

we only have two proposals on how to fix this on the table and (as I said on the issue) I don't think the suggestion in #247 fully solves the problem.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I've left a comment on #248.

@Sakurann Sakurann requested review from jogu and c2bo September 19, 2024 13:13

```
GET /authorize?
client_id=client.example.org
&client_id_scheme=x509_san_dns
client_id=x509_san_dns:client.example.org
Copy link
Member

@peppelinux peppelinux Sep 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that this doesn't really scale

My name is "Giuseppe De Marco", not "trust-evaluation-mechanism:Giuseppe De Marco"

who verifies the trust with me uses the mechanisms it supports and that we might have in common, for this reason it is important to have a way to hint these mechanisms.

Since a subject might be part of multiple networks and using more than a single trust framework, it would be better to hint a list of supported trust evaluation mechanisms, instead of embedding only one of them within the entity identifier, such as the client_id

I believe that this aspect is crucial for the grow of the ecosystem beyond the bounduaries if a single trust framework or network

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @peppelinux. IMO, adding a prefix seems to introduce mandatory extra semantics to a field which are limiting.

I've also had this idea of something similar to login_hint found in other specifications that hint how client can be authenticated.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as an organization, I want to use a single deployment enabling multiple trust frameworks and evaluation mechanisms. Otherwise I would be forced to replicate the same application, using a similar configuration but with the difference in the trust-framework:name identifier value.

This doesn't scale, it shows impacts in real world deployments. We need more freedom in join and exit from and to several networks without forking our deployments.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very strong suggestion to discuss a single deployment enabling multiple trust frameworks and evaluation mechanisms topic into a separate issue #248.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@peppelinux If one of the trust frameworks uses federation and one uses x509_san_dns, then you cannot have the same name in both, regardless of whether client_id_scheme is a separate parameter, a prefix, or doesn't exist at all. Therefore what you're describing is a separate problem that we should discuss in #248.

Copy link
Member

@peppelinux peppelinux Sep 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically, using X.509 certificates and SAN

X509v3 extensions:
    X509v3 Subject Alternative Name:
        URI:https://example.com/rp/entity1

note: X.509 SAN allows multivalued entries

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@peppelinux

In the technical specification, we should enable this kind of flexibility.

As I think I mentioned in another comment somewhere, we're not preventing people defining new client id schemes that have behaviour like this (whether it is a good idea for people to do so or not is a separate matter and likely depends on many details that haven't yet been talked about). If anything this PR is enabling that extensions like that in a way that doesn't result in security issues and confusion. If someone manages to come up with a single client id scheme that works for every single ecosystem/trust framework, then that's an even better outcome!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@peppelinux the proposed mechanism is just a different syntax for the data conveyed n the client_id_scheme parameter. Why do you think this scales less then the client_id_scheme parameter?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the client_id using HTTPS URL doesn't make any conflicts with any other trust establishment mechanisms that might come or be hinted in the future, I can approve this PR thinking that fixed namespaces will not scale, while https url would be more flexible.

I'm not very happy about this, but happiness doesn't necessarily have to be found in github reviews :-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tlodderstedt client_id_scheme as single valued array didnt scale as well, it would have been an array to scale.
More specifically about your question: It was not a comparison between the two but a vision about improve the specification with something more flexible.

approved, let's try to move forward lightly.

Copy link
Collaborator

@tlodderstedt tlodderstedt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left one editorial comment


```
GET /authorize?
client_id=client.example.org
&client_id_scheme=x509_san_dns
client_id=x509_san_dns:client.example.org
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@peppelinux the proposed mechanism is just a different syntax for the data conveyed n the client_id_scheme parameter. Why do you think this scales less then the client_id_scheme parameter?

The following is a non-normative example of a request when `client_id` equals `redirect_uri`.
For example, an Authorization Request might contain `client_id=verifier_attestation:example-client` to indicate that the `verifier_attestation` Client Identifier Scheme is to be used and that within this scheme, the Verifier can be identified by the string `example-client`. The presentation would contain the full `verifier_attestation:example-client` string as the audience (intended receiver) and the same full string would be used as the Client Identifier anywhere in the OAuth flow.

Without the prefix, `example-client` in the example above would be interpreted as referring to a pre-registered client, as defined below. Therefore, Wallets MUST always use the full Client Identifier, including the prefix if provided, within the context of the Wallet or its responses to identify the client. This refers in particular to places where the Client Identifier is used in [@!RFC6749] and in the presentation returned to the Verifier.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this paragraph should be split, as the 1st sentence talks about a different aspect then the rest. The rest is of outmost importance to the security of the overall flow. I think this should be pointed out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely restructured the section, please re-review.

Copy link
Member

@c2bo c2bo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do believe that this is the best/cleanest path forward to guarantee security / prevent downgrading attacks.

That being said, I do understand the concerns that have been brought up, but do believe we should be dealing with that and especially the optimization for re-using the same key for different trust mechanisms in a different issue/PR.

@danielfett
Copy link
Contributor Author

FYI, I restructured the section on client id schemes to tighten the exp... improve readability.

* `response_type`
* `response_mode`
* `nonce`
* `presentation_definition`
* `client_metadata`
* `request`

The `client_id` and `client_id_scheme` MUST be omitted in unsigned requests defined in (#unsigned_request). The Wallet determines the Client Identifier from the origin as asserted by the Web Platform and/or app platform. The transport of the request and origin from the Web Platform and/or app platform to the Wallet is platform-specific and is out of scope of this profile.
The `client_id` MUST be omitted in unsigned requests defined in (#unsigned_request). The Wallet determines the Client Identifier from the origin as asserted by the Web Platform and/or app platform. The transport of the request and origin from the Web Platform and/or app platform to the Wallet is platform-specific and is out of scope of this profile.
Copy link
Member

@bc-pi bc-pi Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per my (possibly flawed) understanding, this effectively means that an unsigned request will have a Client Identifier determined to be something like "https://verifiers.domain.com" which is a value that "indicates that the Client Identifier is an Entity Identifier defined in OpenID Federation" per https://github.com/openid/OpenID4VP/pull/263/files#diff-3118c9756a1d7b361bb53af8bd9d65666476a27cfeeced56c47a5dccc38eac55R494

It is not that.

This bit of text was arguably a bit unspecified before this PR.

But now it's wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed on the call, an option would be that the wallet adds a prefix indicating that it derived the client id from the web platform, e.g., api-orign:.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This option was more or less the agreed to path forward in the call (as I remember it anyway).

Copy link
Member

@bc-pi bc-pi Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still object to special treatment of DIDs and Federation. And do not buy the argument about DIDs not being special. But in the interest of moving forward, I've conceded on that point and agreed on fixing things here. And also came to realize that #213 "What is effective client_id in unsigned browser requests" is related.

Copy link
Member

@bc-pi bc-pi Sep 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is an attempt at some suggested text, which I half promised to do during the call.

Suggested change
The `client_id` MUST be omitted in unsigned requests defined in (#unsigned_request). The Wallet determines the Client Identifier from the origin as asserted by the Web Platform and/or app platform. The transport of the request and origin from the Web Platform and/or app platform to the Wallet is platform-specific and is out of scope of this profile.
The `client_id` parameter MUST be omitted in unsigned requests defined in (#unsigned_request). The Wallet determines the effective Client Identifier from the origin as asserted by the Web Platform and/or app platform. The effective Client Identifier is composed of a synthetic Client Identifier Scheme of `web-origin` and the origin itself. For example, an origin of `https://verifier.example.com` would result in an effective Client Identifier of `web-origin:https://verifier.example.com` The transport of the request and origin from the Web Platform and/or app platform to the Wallet is platform-specific and is out of scope of this profile.

The text in the {#unsigned_request} section likely needs a bit of an update too. But that content is too far out of scope from the changes in the PR to make a suggestion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WRT the text in {#unsigned_request} perhaps,

The Verifier MAY send all the OpenID4VP request parameters as members in the request member passed to the API. In this case, the Wallet will use the Verifier's origin as asserted by the user agent as the Verifer's Client Identifier.

to

The Verifier MAY send all the OpenID4VP request parameters as members in the request member passed to the API. In this case, the Wallet will use the Verifier's origin as asserted by the user agent to determine the Verifier's effective Client Identifier.

or something

Copy link
Member

@bc-pi bc-pi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am philosophically opposed to special treatment of DIDs and Federation.

If we're gonna prefix, prefix all the new stuff equally. And ":" needn't be the prefix indicator.

Also it causes breakage in the Appendix A. OpenID4VP profile for the W3C Digital Credentials API #263 (comment)

@Sakurann
Copy link
Collaborator

Sakurann commented Sep 24, 2024

discussed on the WG call. need to clarify the behavior of client id in an unsigned request in the browser API since that is where client id is an https: just like in openid federation. please make suggestions.

there were multiple opinions that DIDs are not a special treatment. did: is defined as an URI scheme.

@Sakurann
Copy link
Collaborator

I think this PR also resolves #29?

@jogu
Copy link
Collaborator

jogu commented Sep 26, 2024

I think this PR also resolves #29?

I don't think so. I'll comment on the issue.

@danielfett
Copy link
Contributor Author

It indeed resolves #29 as it changes the title of the section that @jogu identified as confusing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

client_id_scheme security considerations Unclear what happens if client_id_scheme appears twice