Differentiation between unknown information and incorrect assertion

Issue #1219 new
Kai Lehmann created an issue

This topic came up occasionally (e.g. when discussing age verification and aborting transactions). How can we let a RP understand the difference between an information an OP does not have and an assertion the RP made was not true?

Let’s consider the following use case:

The RP has the end user’s name and wants to verify that the information is correct. It creates the following request:

{
  "claims": {
    "given_name": { "value": "Max" },
    "family_name": { "value": "Mustermann" }    
  }
}

Let’s say the OP does not know (or could not verify) the given name of the end user and has a verified family name for the end user which does not match the value sent by the RP.

For unknown information (or information which the end user chose not to release) the claim will simply be omitted from the output. The OIDCC spec in chapter 5.5.1 states that it is up to the respective claim specification to define how the OP should respond to when a requested claim value does not match the stored value. Apart from the acr claim in chapter 5.5.1.1 there is no specific handling defined for any other claim in regards to the value (or values) attribute. So my assumption would be that the claim should also be just omitted from the Userinfo response in this case:

{
  "sub": "jkhsfStw34SDo36"
}

As was discussed, however, the RP will need the information if the data it has about the end user is valid or not. Also the OP may want to get paid for the verification/validation service even if this results in invalidating the given data.

With age verification the new attribute “result” was introduced. Is this attribute applicable to any other claim? It would certainly require to return a JSON object instead of the actual result value and combine the value with the result attribute. In our case we would be able to return information that family name value was invalid:

{
  "sub": "jkhsfStw34SDo36",
  "family_name": { "result": false }
}

Should we return the invalid claim value like so?

{
  "sub": "jkhsfStw34SDo36",
  "family_name": { "result": false, "value": "Mustermann" }
}

I suggest to not return the value in this case as we would prevent the RP from ignoring the result value and take the returned value as is.

Should we return the result value also when the validation was positive like it is currently intended in the age verification PR like so?

{
  "sub": "jkhsfStw34SDo36",
  "family_name": { "result": true, "value": "Mustermann" }
}

Complex types

How does this look for more complex value types like the address claim (how to request values for complex types is still an ongoing discussion in the age verification pull request. I just use single request value here for abbreviation reasons)?

Request

{
  "claims": {
    "address": {
      "value": {
        "street_address": "Musterstraße 14",
        "locality": "Musterstadt",
        "postal_code": 12345,
        "country": "Deutschland"
      }
    }
  }
}

Response if valid

{
  "sub": "jkhsfStw34SDo36",
  "address": {
    "street_address": "Musterstraße 14",
    "locality": "Musterstadt",
    "postal_code": 12345,
    "country": "Deutschland"
  }
}

Response if invalid:

{
  "sub": "jkhsfStw34SDo36",
  "address": { "result": false }
}

Or repeat the invalid data?

{
  "sub": "jkhsfStw34SDo36",
  "address": {
    "result": false,
    "value": {
      "street_address": "Musterstraße 14",
      "locality": "Musterstadt",
      "postal_code": 12345,
      "country": "Deutschland"
    }
  }
}

How about embedding the result value inside of the complex type as it is suggested in the age verification PR at this moment?

{
  "sub": "jkhsfStw34SDo36",
  "address": {
    "result": true/false,
    "street_address": "Musterstraße 14",
    "locality": "Musterstadt",
    "postal_code": 12345,
    "country": "Deutschland"
  }
}

The result attribute has a potential conflict with JSON objects already defining a “result” attribute with a different meaning. There are no claims in the OIDCC spec using this, but implementers could already have defined their own objects using a result attribute.

Are there maybe other options to represent invalid request data?

How about returning null or false instead?

{
  "sub": "jkhsfStw34SDo36",
  "family_name": false,
  "address": false
}

or

{
  "sub": "jkhsfStw34SDo36",
  "family_name": null,
  "address": null
}

The false value is conflicting with boolean claim types (e.g. email_verified).

The null value might get interpreted the same way as when omitting the claim itself in the response. Also OPs might already use this for telling the RP that they do not know this information. However, we have still the option to specify this accordingly to differentiate between unknown and invalid information. RPs who don’t care about the differentiation, can just interpret the null value as like as the attribute has been omitted entirely.

My suggestion

  1. If validation was successful or the stored data matches the requested data, just return the object as usual. Do not add any other attribute to indicate it was validated.
  2. If validation was unsuccessful, do not return the requested data. Instead return “null” as value for the claim.

Comments (6)

  1. David W Chadwick

    I agree with 1. (just return the correct values). I do not agree with 2. because it does not differentiate between false data and unknown. In the latter case, the data could be correct but the OP is not aware of this.

  2. David W Chadwick

    So you could return False meaning the OP knows the data is false, and null meaning unknown.

  3. Kai Lehmann reporter

    We may need for @Daniel Fett to address/incorporate Davids comments in the proposed PR.

  4. Log in to comment