Remove c_nonce from the token response
The option to return c_nonce with token response should be dropped to simplify the spec and implementations. It’s a lot of complexity and optionality for the potential avoidance of just one HTTP request/response direct from wallet/client to credential issuer.
Comments (9)
-
-
The current spec provides implementers with two choices.
c_nonce from token endpoint round trip at credential endpoint server implementation wallet implementation 1 issue unnecessary cumbersome unburdensome 2 not issue necessary unburdensome cumbersome Removing the option to return
c_nonce
from the token endpoint will result in removing the first choice in the table above.Even if we can agree not to issue
c_nonce
from the token endpoint among us at this moment, there will always be people in the future who will complain about the extra round trip. Therefore, it would be wise to provide two choices without modifying the current specification. -
reporter The wallet implementation needs to be able to handle an
invalid_proof
(orinvalid_or_missing_proof
b/c the draft currently has both) error/challenge in any case so calling it cumbersome there is a misnomer. When a c_nonce from the token endpoint is an option, the wallet needs to deal with possibly getting the nonce value from two places. It's not making the wallet implementation less cumbersome. It's only optimizing around one http request / response.
-
- I agree that we are not simplifying the wallet by having the c_nonce on the token endpoint, namely because: 1) it is optional; 2) it may already be invalid when the wallet uses it, so the wallet needs to still correctly react to an error response and use the freshly provided c_nonce on a retry.
- OTOH, the c_nonce on the token endpoint is currently optional, so some AS may decide to not implement that support on the token endpoint, keeping its implementation simpler; while leaving the door open for other AS to implement it.
- So IMO, the question is: is the additional spec complexity (not necessarily AS complexity) worthwhile just to enable an optimization that some AS may decide to implement?
-
(or
invalid_or_missing_proof
b/c the draft currently has boththat’s editorial error. I will do a PR removing references to
invalid_or_missing_proof
-
Having read the arguments, I am increasingly in favor of removing the
c_nonce
from the token endpoint -
I would like to hear more feedback from implementers (both wallets and issuers) before we decide.
-
I tried writing a virtual wallet-side code for “c_nonce” handling. (Its error handling is not perfect, though.)
// Make a token request and receive a token response. token_response = make_token_request(); // The access token issued from the token endpoint. access_token = token_response.access_token; // The token response MAY contain "c_nonce". c_nonce = token_response.c_nonce; // Repeat credential requests until a credential or a transaction ID is issued. while (true) { // Make a credential request and receive a credential response. // It is assumed that the "make_credential_request" method here // internally generates a key proof with the given "c_nonce" and // includes the key proof in the credential request. credential_response = make_credential_request(access_token, c_nonce); // If either a credential or a transaction ID has been issued. if (credential_response.credential != null || credential_response.transaction_id != null) { // Stop repeating credential requests. break; } // If the reason of the error is "invalid_proof" and the value // of "c_nonce" in the credential response is different from // the one used in the credential request, it is worth trying // to make a credential request again with the new "c_nonce". if (credential_response.error == invalid_proof && credential_response.c_nonce != c_nonce) { // Make a credential request again with the new "c_nonce". c_nonce = credential_response.c_nonce; continue; } // Give up. break; }
The virtual code above indicates that whether the token response contains the
c_nonce
parameter or not is not a significant issue for wallet implementers. (Some people may not agree with this view, though.)My conclusion is that it is acceptable to allow authorization server implementations to issue
c_nonce
from their token endpoints if they wish to do so. However, others may reach different conclusions and prefer wallets to make credential requests at least twice (the first one to obtainc_nonce
and the second one to get a credential or a transaction ID).A credential issuer validates an access token that has been issued by an authorization server. Therefore, there exists a relationship between a credential issuer and an authorization server to some degree. If such a relationship is assumed for acess tokens, it should not be a major concern to allow a similar relationship to be established between a credential issuer and an authorization server for
c_nonce
s as well. If you implement an authorization server and a credential issuer, you will notice that ac_nonce
always appears with an access token. However, others may have different thoughts and want to prevent a credential issuer and an authorization server from establishing a relationship forc_nonce
s. -
- changed status to resolved
Migrated to GitHub
- Log in to comment
I was tempted to make a comment onto https://bitbucket.org/openid/connect/pull-requests/535/adding-security-considerations-on-the but this issue is probably a more appropriate place.
It’s interesting to note that, if we made the assumption that dpop is in use, and that the (optional) dpop nonces are being used, then an optimal solution would be removing c_nonce from the token response and instead use the dpop nonce as the nonce for the VCI key proof. Doing that is probably also kind of a layering violation though.
On the original point though, Torsten mentioned on today’s call that returning c_nonce from the token response is a nice optimisation that avoids a round trip at the resource server. I wanted to observe that when you’re using nonces with DPoP the first nonce for the resource server has to be obtained from the resource server, similarly causing an extra round trip, and I don’t remember anyone complaining much about the additional round trip for that. (I’m sure Brian will correct me if they have.)