convey error response in userinfo

Issue #1301 new
Kosuke Koiwai created an issue

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)

  1. Kosuke Koiwai reporter

    Cases include:

    • RP wanted verified_claims of natural person, but the authenticated user was a legal entity.
    • The authenticated user has not completed id verification process with the IDP (and IDP wants to explicitly tell RP such status)

  2. Kosuke Koiwai 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>"
    }
    

  3. Mark Haine

    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

  4. Kosuke Koiwai 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 encrypt id_token if returned in the hybrid flow.

  5. Takahiko Kawasaki

    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 of verified_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?

    1. “/evidence/issuer does not match.”
    2. “/evidence/serial_number does not match.”
    3. “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.

  6. Takahiko Kawasaki

    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.

    1. evidence/type is not electronic_record
    2. evidence/check_details/*/organization is not TheCreditBureau
    3. evidence/check_details/*/txn is not unknown
    4. evidence/type is not document
    5. evidence/check_details/*/check_method is not unknown

    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.

  7. Daniel Fett

    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).

  8. Mark Haine

    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.

  9. Daniel Fett

    I wonder if proofing failed sufficiently describes what happened - it seems that there can be many actual reasons for this error code.

  10. Mark Haine

    Thinking about status codes for successful responses would be useful too and feel to me like something we could discuss

  11. Kosuke Koiwai reporter

    We discussed this issue in 22 Sept call and found that this concept can be used to convey pending status with partial results.

  12. Log in to comment