convey error response in userinfo
There were discussions in OIDF-Japan that there is a need to return an error response in the userinfo endpoint.
An IDP provides social-login service and ID verification service. When an RP wants to authenticate user (with sub
) AND get verified_claims
when possible, the RP wants to know the reason why it didn't receive verified_claims
from userinfo response. Here the RP still wants to get sub
to authenticate user, so returning an error in authorization response is not sufficient.
Comments (13)
-
reporter -
reporter I will check PR56
-
reporter I’ve read the PR56. The goal is the same, but the suggested spec might be too difficult to implement for IDP (and to interpret for RP).
I’m expecting rather simpler spec such as:
"__response_metadata": { "error": "<machine-readable error code defined within the trust framework>", "error_description": "<optional human-readable string>", "error_uri": "<optional uri with error description>" }
-
Need to find te balance between useful error messages and leak of useful information to malicious actors
@Daniel Fett says - “yes this needs to be under the control of the IDP and we should make conservative assumptions about what the IDP wants to release”
Consider making the error response an optional feature
-
reporter I agree to make it OPTIONAL. I assume that eKYC claims should be exchanged between parties with mutual trust, so some degree of exposure is not that risky.
I also suggest that IDPs SHOULD NOT return an error in
id_token
in the hybrid flow and MUST encryptid_token
if returned in the hybrid flow. -
PR56 introduces
__response_metadata
, but the name is too generic (in other words, too invasive). Another different possible approach is to put error information under the namespace ofverified_claims
like below."verified_claims": { "error": "...", "error_description": "...", "error_uri": "..." }
Or, to define a less invasive top-level property like
verified_claims_error
."verified_claims_error": { "error": "...", "error_description": "...", "error_uri": "..." }
BTW, it is not always obviously easy to tell which claim has made the request fail when there exist multiple dataset candidates. I’m not sure that people discussing error information are aware of it.
Suppose that OP has the following two evidence:
type issuer serial_number electronic_signature ABC 456 electronic_signature DEF 123 and it receives the following request:
{ "userinfo": { "verified_claims": { "verification": { "trust_framework": null, "evidence": [ { "type": { "value": "electronic_signature" }, "issuer": { "value": "ABC" }, "serial_number": { "value": "123" }, "created_at": null } ] }, "claims": { "family_name": null } } } }
Neither of the two evidence matches the request. In this case, which error message among the following is appropriate?
- “/evidence/issuer does not match.”
- “/evidence/serial_number does not match.”
- “None of evidence meet the request.”
When there exist multiple dataset candidates, normal OP implementations will compare the request to dataset candidates one by one. For such implementations, it is natural to generate an error message like the third one. However, of course, OP implementations can choose to return the earliest or latest error information instead.
It is unrealistic to list error conditions like PR56, especially when there exist multiple dataset candidates. What RP can expect from an error message is “best effort” at best.
-
A realistic example. Suppose that OP holds the same dataset as “evidence_with_assurance_details.json” (203 lines in total at the time of this writing) holds.
If a request shown below is made:
{ "verified_claims": { "verification": { "trust_framework": null, "evidence": [ { "type": { "value": "electronic_record" }, "check_details": [ { "check_method": null, "organization": { "value": "TheCreditBureau" }, "txn": "unknown" } ] }, { "type": { "value": "document" }, "check_details": [ { "check_method": "unknown" } ] } ] }, "claims": { "given_name": null } } }
the response will not contain
verified_claims
because none of evidence elements in “evidence_with_assurance_details.json“ match any of evidence elements in the request.To reach the conclusion “none of evidence elements match the request”, the OP has to do comparison of evidence elements 12 times. “12” here is calculated by (6 evidence elements in “evidence_with_assurance_details.json”) x (2 evidence elements in the request). Remember that evidence elements in the request are treated by “logical OR” as the specification requires so.
In addition, places that cause “not match” are not always the same. OP encounters the following error conditions before reaching the conclusion.
evidence/type
is notelectronic_record
evidence/check_details/*/organization
is notTheCreditBureau
evidence/check_details/*/txn
is notunknown
evidence/type
is notdocument
evidence/check_details/*/check_method
is notunknown
In this case, what error message should OP report and what error message can help RP? I don’t think this is an easy question to answer. Reasons for unavailability of
verified_claims
do not always converge to one. -
Taka is raising a very good point here. It is likely that implementing a fine-grained description of the error is quite hard to implement. A relatively coarse error as proposed by Kosuke is likely to be sufficient at least for many use cases (in particular, debugging).
-
I have been looking at this for an implementation this week and I think what Kosuke is making sense to me with a couple of other additions.
Firstly - where there is a result code already defined that is a close enough fit it should be used. either from OAuth 2 section 4.1.2.1 or OIDC Core section 3.1.2.6
I have some examples based on scenarios provided by the implementation I am contributing to and my initial ideas about how to address them:
“Identity proofing failed”
"error": "access_denied", - standard from RFC6749 "error_description": "proofing failed",
“authentication failed”
"error": "login_required", - standard from OIDCC "error_description": "unable to authenticate end-user",
“cancelled”
"error": "access_denied", - standard from RFC6749 "error_description": "end-user cancelled the request",
There are also a couple of scenarios that I am less confiident about
“pending” - I am less sure about this one as I would much prefer to solve the pending case as a success rather tha an error
"error": "interaction_required", - standard from OIDCC "error_description": "pending further verification",
“fraud_refer“ - clearly an error but unfortunately the errors are returned via the front channel and so could warn a fraudster that their were under investigation which is a big NO as far as fraud specialists are concerned
"error": "interaction_required", - standard from OIDCC "error_description": "fraud_refer",
In the end we might be able to use the existing error codes - we will only know if we come up with as many real-world cases as we can and test them against the available error codes.
-
I wonder if
proofing failed
sufficiently describes what happened - it seems that there can be many actual reasons for this error code. -
Thinking about status codes for successful responses would be useful too and feel to me like something we could discuss
-
reporter We discussed this issue in 22 Sept call and found that this concept can be used to convey pending status with partial results.
-
I think that the current draft under the core WG is pertinent here too… https://openid.net/specs/openid-connect-unmet-authentication-requirements-1_0.html
It shows how additional error codes can be added to the registry
- Log in to comment
Cases include:
verified_claims
of natural person, but the authenticated user was a legal entity.