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

remove c_nonce from the token endpoint response #381

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

Conversation

bc-pi
Copy link
Member

@bc-pi bc-pi commented Aug 27, 2024

remove c_nonce and c_nonce_expires_in from the token endpoint response to fix #39

again

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.

I suggest to add a dedicated nonce endpoint to the credential issuer as replacement for the c_nonce token response parameter. Just removing the c_nonce will force wallets to try the credential issuance request in order to get a nonce in order to be able to create a proper nonce-bound proof of possession. That's complicated.

@jogu
Copy link
Contributor

jogu commented Aug 27, 2024

I think this is the previous issue about a nonce endpoint for wallet attestation that people were asking about on today's call:

#71

@bc-pi
Copy link
Member Author

bc-pi commented Aug 29, 2024

There has been a lot of discussion about this (and roughly mostly in favor of it) in recent months in #39 and also #331 and maybe elsewhere too. [edit: like https://github.com//issues/357 ]

@peppelinux
Copy link
Member

peppelinux commented Sep 3, 2024

I suggest to add a dedicated nonce endpoint to the credential issuer as replacement for the c_nonce token response parameter.

@tlodderstedt that's exactly what I had in mind when I started writing this draft: https://github.com/peppelinux/draft-demarco-oauth-nonce-endpoint?tab=readme-ov-file

@jogu many of the conversations and points raised within the issue #71 was filtered and mentioned in the nonce endpoint draft

…ue without the overhead of a full Credential Request
@bc-pi
Copy link
Member Author

bc-pi commented Sep 4, 2024

as requested, 074065b adds a dedicated nonce endpoint to the credential issuer as replacement for the c_nonce token response parameter

Copy link
Contributor

@paulbastian paulbastian left a comment

Choose a reason for hiding this comment

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

I would like to mandate nonce endpoint if the issuer requires the use of c_nonce, i.e. the presence of the endpoint enforces its usage, therefore we could get rid of sending fake ugly Credential requests to fetch a c_nonce completely.

Having this endpoint optional and no other indication of the issuer whether he requires c_nonce for proofs seems inefficient.

@bc-pi
Copy link
Member Author

bc-pi commented Sep 6, 2024

I would like to mandate nonce endpoint if the issuer requires the use of c_nonce

48a3678 updates the proposed text to do that.

@@ -710,6 +706,45 @@ Cache-Control: no-store
}
```

# Nonce Endpoint {#nonce-endpoint}

A Credential Issuer that requires `c_nonce` values to be incorporated into proofs in the Credential Request (see (#credential-request)) MUST offer a Nonce Endpoint. This endpoint allows a Client to acquire a fresh `c_nonce` value without the overhead of a full Credential Request.
Copy link
Collaborator

Choose a reason for hiding this comment

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

improve readability

Suggested change
A Credential Issuer that requires `c_nonce` values to be incorporated into proofs in the Credential Request (see (#credential-request)) MUST offer a Nonce Endpoint. This endpoint allows a Client to acquire a fresh `c_nonce` value without the overhead of a full Credential Request.
This endpoint allows a Client to acquire a fresh `c_nonce` value without the overhead of a full Credential Request. A Credential Issuer that requires `c_nonce` values to be incorporated into proofs in the Credential Request (see (#credential-request)) MUST offer a Nonce Endpoint.

but also do we really want to mandate nonce endpoint for all issuers that require c_nonce? than why keep an option to return c_nonce in credential response?

Copy link
Member Author

Choose a reason for hiding this comment

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

was trying to keep the scope of the changes to something that had been agreed on while also accommodating Paul's request for changes

Copy link
Member Author

Choose a reason for hiding this comment

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

while also keeping my own frustration in check about the fact that these are all things that were only hidden by the nonce from token endpoint but have existed all along so why do they always and only come up in the context of trying to make an improvement

Copy link
Member Author

Choose a reason for hiding this comment

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

Also removing the ability to have send a c_nonce in the credential response would probably be a breaking change by most measures and it's unclear if the WG has the appetite for that.

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.

overall looks good. I almost approved, but I think we should discuss if we really want to mandate nonce endpoint for all issuers that require c_nonce? than why keep an option to return c_nonce in credential response?

@bc-pi
Copy link
Member Author

bc-pi commented Sep 10, 2024

overall looks good. I almost approved, but I think we should discuss if we really want to mandate nonce endpoint for all issuers that require c_nonce? than why keep an option to return c_nonce in credential response?

fair questions that i guess should be discussed in the WG

Copy link
Contributor

@paulbastian paulbastian left a comment

Choose a reason for hiding this comment

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

I like the current direction.

If we keep things as-is, we can completely delete the chapter 7.3.2 as the nonce endpoint is doing the job and all other details are already covered in the main section of Credential Response

@jogu jogu added this to the Final 1.0 milestone Sep 16, 2024
@bc-pi
Copy link
Member Author

bc-pi commented Sep 16, 2024

overall looks good. I almost approved, but I think we should discuss if we really want to mandate nonce endpoint for all issuers that require c_nonce? than why keep an option to return c_nonce in credential response?

fair questions that i guess should be discussed in the WG

Noting that removing the ability to have send a c_nonce in the credential response would probably be a breaking change by most measures. Which, I think, would be okay by me. But should have some buy-in from the WG.

@Sakurann
Copy link
Collaborator

Discussed on the WG call, direction on removing section 7.3.2 and consolidating its content in Nonce Endpoint definition.
https://openid.github.io/OpenID4VCI/openid-4-verifiable-credential-issuance-wg-draft.html#section-7.3.2

also in this PR, add a little more explanation that issuer can invalidate c_nonce any time. please open an issue on removing c_nonce_expires_in parameter (@tplooker).

also agreed to open a separate issue on removing an option to return c_nonce from the credential error response, so that we can merge this PR as-is (@bc-pi).

@peppelinux
Copy link
Member

peppelinux commented Sep 19, 2024

on protecting the endpoint, discussed on the WG call, no strong reason to do it, agreed to proceed with unprotected endpoint, but open an issue to gather an implementation experience if anyone wants/needs a stateful c_nonce

interesting is the idea to use the AT released by the token endpoint, and for the purpose of the credential issuance, to the oauth nonce endpoint as a protected endpoint.

generally I assume that any endpoint might be protected with a token

Copy link
Member

@peppelinux peppelinux left a comment

Choose a reason for hiding this comment

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

I have requested some small changes about naming, you can consider this PR approved by me


The Credential Issuer provides a nonce value in the HTTP response with a 2xx status code and the following parameters included as top-level members in the message body of the HTTP response using the application/json media type:

* `c_nonce`: REQUIRED. String containing a nonce to be used when creating a proof of possession of the key proof (see (#credential-request)).
Copy link
Member

Choose a reason for hiding this comment

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

Okay, since this Nonce Endpoint is specifically tailored for credential issuance within the sole scope of the OpenID4VCI specs, it would make sense to rename the endpoint metadata parameter from nonce_endpoint to credential_nonce_endpoint.

In this way, other nonce endpoints created for other OpenID/IETF specs will not collide with this one.
The related section should therefore be renamed to "Credential Nonce Endpoint," adding "Credential" as a prefix to contextualize its scope.

@c2bo
Copy link
Member

c2bo commented Sep 20, 2024

overall looks good. I almost approved, but I think we should discuss if we really want to mandate nonce endpoint for all issuers that require c_nonce? than why keep an option to return c_nonce in credential response?

I was wondering about this as well. One reason why I think it would make sense to keep the option to return c_nonce in the Credential Response would be to allow the Issuer to invalidate an existing nonce because of some kind security concern (some kind of anomaly detection etc. that got triggered). That way the issuer could create a stateful nonce for a specific client via the credential response if necessary.

@bc-pi
Copy link
Member Author

bc-pi commented Sep 20, 2024

overall looks good. I almost approved, but I think we should discuss if we really want to mandate nonce endpoint for all issuers that require c_nonce? than why keep an option to return c_nonce in credential response?

I was wondering about this as well. One reason why I think it would make sense to keep the option to return c_nonce in the Credential Response would be to allow the Issuer to invalidate an existing nonce because of some kind security concern (some kind of anomaly detection etc. that got triggered). That way the issuer could create a stateful nonce for a specific client via the credential response if necessary.

I've created #393 to discuss/track "why keep an option to return c_nonce in credential response?"

Co-authored-by: Paul Bastian <[email protected]>
@paulbastian
Copy link
Contributor

Just to be sure, this PR creates two possible ways for the Issuer to provide the c_nonce, as both are described with MAY, this means the Wallet must implement both. Is this analysis correct?

@bc-pi
Copy link
Member Author

bc-pi commented Sep 20, 2024

Just to be sure, this PR creates two possible ways for the Issuer to provide the c_nonce, as both are described with MAY, this means the Wallet must implement both. Is this analysis correct?

I don't think so, no.

@paulbastian
Copy link
Contributor

Just to be sure, this PR creates two possible ways for the Issuer to provide the c_nonce, as both are described with MAY, this means the Wallet must implement both. Is this analysis correct?

I don't think so, no.

What do you think then?

@bc-pi
Copy link
Member Author

bc-pi commented Sep 20, 2024

Just to be sure, this PR creates two possible ways for the Issuer to provide the c_nonce, as both are described with MAY, this means the Wallet must implement both. Is this analysis correct?

I don't think so, no.

What do you think then?

@jogu's analysis from over in one of the 87 other communication channels seemed, as I said there, constructive:

It depends a little on the wallet's viewpoint. In some ways, it replaces a mechanism that may or may not happen (cnonce at token endpoint, cnonce error from credential endpoint) with a "if I list this endpoint in my metadata, you need to call it, and once you call it your credential endpoint call should succeed first time".

But also I think that this PR is a huge step in the right direction that is long overdue.

And further improvements should be considered seriously per #393 soon after this is merged. Which is hopefully soon.

@paulbastian
Copy link
Contributor

paulbastian commented Sep 22, 2024

Re-reading section 7.3.2 I think we should delete the following paragraph:

If the Client has not received a c_nonce and the Credential Issuer Metadata contains proof_types_supported indicating a key proof is required for the requested Credential, the Client MUST send a Credential Request that contains a proof or proofs parameter that is fully valid but does not include a c_nonce value. It is the Credential Issuer policy whether or not a c_nonce value is required in the key proofs.If the Client received a c_nonce, the c_nonce value MUST be incorporated in the respective parameter in the proof or proofs object.

I think leaving this paragraph in would lead to confusion, especially given that weird MUST that now contradicts the Nonce endpoint

@babisRoutis
Copy link
Contributor

FWIW,

I think that the removal of c_nonce from Token Endpoint is a big improvement. Now, it is only the credential issuer's responsibility to provide such a c_nonce.

I was hoping, though, to have a single way (for the caller/wallet) to obtain such a c_nonce. Introducing the nonce endpoint and keeping c_nonce in both success and/or error response, I have the feeling makes solution more complex that is needed.

For instance, in draft 13, it was clear - although not explicitly stated - that the main way to obtain c_nonce was via credential response. Token response was an optimization and in worst case, wallet could just "ignore" the token response in the expense of an additional credential request

With this PR, unless I am missing something, a wallet should be prepared to handle

  • Issuers that do provide nonce endpoint but don't provide c_nonce in the credential response
  • Issuers that do NOT provide nonce endpoint but provide c_nonce in the credential response
  • Issuers that support both nonce endpoint & c_nonce in the responses.

@bc-pi
Copy link
Member Author

bc-pi commented Sep 24, 2024

Re-reading section 7.3.2 I think we should delete the following paragraph:

If the Client has not received a c_nonce and the Credential Issuer Metadata contains proof_types_supported indicating a key proof is required for the requested Credential, the Client MUST send a Credential Request that contains a proof or proofs parameter that is fully valid but does not include a c_nonce value. It is the Credential Issuer policy whether or not a c_nonce value is required in the key proofs.If the Client received a c_nonce, the c_nonce value MUST be incorporated in the respective parameter in the proof or proofs object.

I think leaving this paragraph in would lead to confusion, especially given that weird MUST that now contradicts the Nonce endpoint

That that weird MUST needs to change but I'm reluctant to delete the whole paragraph.

@paulbastian
Copy link
Contributor

As I would read this PR, it recommends the wallet to use the nonce endpoint if it's present and the parameter in credential response is kind of an alternative/fallback. Therefore this paragraph does not fit any longer.

@bc-pi
Copy link
Member Author

bc-pi commented Sep 24, 2024

aadb2bb is what I was able to summon the appetite for

Co-authored-by: Giuseppe De Marco <[email protected]>
Below is a non-normative example of a Nonce Request:

```
GET /nonce HTTP/1.1
Copy link
Collaborator

@tlodderstedt tlodderstedt Sep 26, 2024

Choose a reason for hiding this comment

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

Wouldn't a POST request be more appropriate? I mean the endpoint is supposed to provide a new/different value with every response and the result should not be cached (in my opinion).

Copy link
Contributor

Choose a reason for hiding this comment

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

+1, I tried to push in this direction as well: #381 (comment)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I didn't realize this was GET. my suggestion has been POST. In german wallet project we have been prototyping with POST and it works well https://bmi.usercontent.opencode.de/eudi-wallet/eidas-2.0-architekturkonzept/flows/PID-IssuerSigned-cloud/#issuer-session-endpoint-at-the-pid-provider

Copy link
Member Author

@bc-pi bc-pi Sep 26, 2024

Choose a reason for hiding this comment

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

Other than describing the media type of content that doesn't exist as JSON, which is semantically invalid and maybe syntactically wrong too, what value does the German wallet project get from using POST?

=== Screenshot of the previously cited german wallet project ===
Screenshot 2024-09-26 at 10 22 06 AM

Copy link
Member Author

@bc-pi bc-pi Sep 26, 2024

Choose a reason for hiding this comment

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

Wouldn't a POST request be more appropriate?

No.

I mean the endpoint is supposed to provide a new/different value with every response and the result should not be cached (in my opinion).

That's why it was made not cacheable in the example https://github.com/openid/OpenID4VCI/pull/381/files#diff-1f424614b35a9899813079f1b1f6218631a2aedd993368ccb89bb81a9eda0289R741 and text https://github.com/openid/OpenID4VCI/pull/381/files#diff-1f424614b35a9899813079f1b1f6218631a2aedd993368ccb89bb81a9eda0289R734 using the Cache-Control construct that HTTP gives for control of caching.

Copy link
Member Author

@bc-pi bc-pi Sep 26, 2024

Choose a reason for hiding this comment

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

+1, I tried to push in this direction as well: #381 (comment)

My naive feeling that using a GET to get some data is the most straightforward way to get some data remained unchanged by that discussion over the course of the last two weeks.

Copy link
Contributor

@nemqe nemqe Sep 27, 2024

Choose a reason for hiding this comment

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

My 2 cents for what they are worth,

If we asked the question "is this call safe (i.e. is it read-only)" I think the answer would be "maybe". Safe calls shouldn't alter the state of the server in any way but without knowing how the server implements the nonce endpoint we would not know the answer to the question.

If we asked the question "is this call idempotent" I think we would also get a "maybe". Client could do this call just to "fetch a value" which might not assume any intention of a side-effect, and from the perspective of the server it would depend on the implementation.

I do see the point in making it a GET because it is technically just fetching a random value, so semantically if fits, but there might be an embedded assumption here that this random value is a prerequisite for some other steps, and that getting a nonce can be viewed as setting up a state that needs to be validated by the server.

One could argue that it might be safer to make this a POST because this would communicate that the call might not be safe or idempotent and that subsequent calls could cause load, burden, and side-effects for the server.

But this is just philosophizing, I personally do not have a clear preference, I see arguments for both GET and POST.

@@ -1044,7 +1081,7 @@ Cache-Control: no-store

The Credential Issuer MAY provide the Client with a `c_nonce` as defined in (#credential-response) in a Credential Error Response using `invalid_proof` error code defined in (#credential-error-response) if the Credential Issuer Metadata contains `proof_types_supported` indicating a key proof is required for the requested Credential. Depending on the Credential Issuer policy, this occurs if they receive a Credential Request without a `c_nonce` or with an invalid `c_nonce` value included in the proof(s) in the `proof` or `proofs` parameter.

If the Client has not received a `c_nonce` and the Credential Issuer Metadata contains `proof_types_supported` indicating a key proof is required for the requested Credential, the Client MUST send a Credential Request that contains a `proof` or `proofs` parameter that is fully valid but does not include a `c_nonce` value. It is the Credential Issuer policy whether or not a `c_nonce` value is required in the key proofs.
If the Client has not received a `c_nonce` and the Credential Issuer Metadata contains `proof_types_supported` indicating a key proof is required for the requested Credential, the Client can send a Credential Request that contains a `proof` or `proofs` parameter that is fully valid but does not include a `c_nonce` value. It is the Credential Issuer policy whether or not a `c_nonce` value is required in the key proofs.
Copy link
Collaborator

Choose a reason for hiding this comment

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

When is this paragraph apply? I'm asking since the client can always obtain a c_nonce from the nonce endpoint.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1, I was trying to push in this direction as well: #381 (comment)

Copy link
Member Author

@bc-pi bc-pi Sep 26, 2024

Choose a reason for hiding this comment

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

As I've tried to convey in comments on this PR and in calls over the course of the last month, I attempted to keep the scope of this change narrow so as to hopefully make it acceptable to the wide range of opinions and oftentimes irregular participation of the WG members. I have clearly failed in my efforts. I believe the text in question here was written recently by @awoie and because it is still true that "Credential Issuer policy whether or not a c_nonce value is required in the key proofs" and a "Client can send a Credential Request that contains a proof or proofs parameter that is fully valid but does not include a c_nonce value" it seemed like it applied enough to not delete it.

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 did not realize this was GET, approved assuming this was POST, sorry about that...

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.

Remove c_nonce from the token response