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

Add Age Verification to KnowYourCustomer SP's Scope in README #81

Open
ToshiWakayama-KDDI opened this issue May 7, 2024 · 54 comments
Open
Labels
subproject management Indicating issues with subproject repository or release management process

Comments

@ToshiWakayama-KDDI
Copy link
Collaborator

Problem description

  • Current KnowYourCustomer Sub project's Scope in README does not include Age Verification API.

Expected action

  • This issue is to propose content for Age Verification scope (fulfilling AI 12.01);
    It provides the API customer with the ability to: check if the owner/user of the line is older than a provided age, in order to provide API customer's age-restricted services, access to its age-restricted website etc.
@ToshiWakayama-KDDI ToshiWakayama-KDDI added the subproject management Indicating issues with subproject repository or release management process label May 7, 2024
@GillesInnov35
Copy link
Collaborator

hi @ToshiWakayama-KDDI, how could we link this issue with the interesting discussion started in issue #46 and the code proposition in #50 ?

thanks a lot
BR
Gilles

@GillesInnov35
Copy link
Collaborator

Concerning Age verification API, reading discussion in issue #46, I understand that if we complete the enum (true/false/unverified/not_available/insufficient input data provided) we could validate a first proposal defined in PR in #50.
Is it right ?

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Hi @GillesInnov35 ,

hi @ToshiWakayama-KDDI, how could we link this issue with the interesting discussion started in issue #46 and the code proposition in #50 ?

I do not know how to do that, but we could modify the text, so that it can be aligned with Issue #46/ PR #50. Why don' t we leave this issue for a while?

BR

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Hi @GillesInnov35 ,

Thanks.

Concerning Age verification API, reading discussion in issue #46, I understand that if we complete the enum (true/false/unverified/not_available/insufficient input data provided) we could validate a first proposal defined in PR in #50. Is it right ?

Generally yes, but I have commented to Issue #46, as:

As we have had very long discussions, could you summerise the conclusion before moving on to PR? It is difficult to see what proposals are remaining, I feel.

A basic question, please. We have started Match Scoring discussion. As Age Verification has scoring feature, should it be aligned with Match Scoring?

Many thanks,

@GillesInnov35
Copy link
Collaborator

GillesInnov35 commented Jun 18, 2024

hi @ToshiWakayama-KDDI and all, I've tried to summarized the current discussion with all contributors in PR #50 and issue #46

  • as the MNO hold only information of contract owner or contact, the identity of the user might be verified before the age verification
  • Main rule: MNO will be able to return a result only if the user is the owner/contact of the contract known by the MNO
  • MNO will return in the response a string result and a score level which is the aggregation of all match score result of the provided attributes
  • Regarding the score result, MNO will decide what should be the age verification result (true/false/unverified/not_available)
  • insufficient_data has been removed of the initial proposition of enum
  • by also returning the aggregated score it allows consumer application to decide how to understand the response.

The request contains

  • age value to be verified
  • attributes of the user's identity to be verified
  • all additional attributes of identity are optional (seems to be the decision?)
  • if not provided in the request, no identity verification will be performed (seems to be the decision?)

The response

  • a string result (enum array) true/false/unverified/not_available
  • insufficient_data has been removed
  • aggregated score match result of additional user's identity attributes if they are provided

What might be the next steps

What do you think about that ?

BR
Gilles

@HuubAppelboom
Copy link
Collaborator

@GillesInnov35 @ToshiWakayama-KDDI Sounds like a good summary to me. Note that the score with age verification should indeed be the aggregate score, because you don't want to disclose the match on the individual attributes (for that we have the KYC Match api).

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Hi @GillesInnov35 , @HuubAppelboom , all,

Let me confirm the understanding of 'ageVerified' values, please.

My understanding is:

  • true: if the subscriber's age is equal to or more than the 'age' value sent by the request (the subscriber's age >= the 'age' value sent by the request)

  • false: if the subscriber's age is less than the 'age' value sent by the request (the subscriber's age < the 'age' value sent by the request)

  • unverified: I am not sure what this means. Would appreciate it if someone could advise me.

  • not_available: if the operator/API provider does not have age-related information.

Many thanks,

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Hi @GillesInnov35 , @HuubAppelboom , all,

In addition to the above, I feel the parameter name 'age' is a bit vague. It may be better to change it to something like 'specifiedAge', 'checkedAge', 'verifiedAge', 'ageThreshold'.

What do you think?

Best regards,
Toshi

@HuubAppelboom
Copy link
Collaborator

Hi @ToshiWakayama-KDDI @GillesInnov35 @KevScarr , all,

The "unverified" response was originally proposed for those cases where users may have recorded their date of birth in the telco CRM system (prepaid was mentionned as an example), but the telco never has verified whether this is valid or not.

@HuubAppelboom
Copy link
Collaborator

@ToshiWakayama-KDDI @GillesInnov35 @KevScarr , all,

In the list of possible answers we may be overlooking the scenario where there is a clear mismatch between the optional pararmeters provided (for example in givenName, familyName). This means the end user is not the contract owner.

For this case, I see 2 options

  • we could provide a separate answer for this (like identity_mismatch), so the developer knows this as well
  • or simply give "not_available" (because we don't have the right end user data)

What do you prefer ? The 2nd option may be a better choice in terms of privacy,

@HuubAppelboom
Copy link
Collaborator

@ToshiWakayama-KDDI @GillesInnov35 @KevScarr , all,

We have been discussing Age Verification with quite a few customers recently in the Netherlands, and we see demand for 2 versions of the API, depending on what data the developer has collected

One is a very simple one, in which the developer simply wants to check the DoB a customer has entered (without checking any additional info). This is a simple dressed down version of the KYC Match api, where only Date of Birth is verified. If the DoB can not be verified, these customers typically use a different verification method (with more friction). The assurance level here is typically not that relevant, and for cases where there is a mismatch between end user and contract owner they simply switch to the 2nd verification method. The reason we need a separate API here (next to KYC Match) is primarily a commercial one, for just age verification we typically see a need for a much lower price point as compared to a full scale identy product, at a different positioning.

The other API is the one we have been discussing so far, where the input is usually the phone number (and optionally additional personal data to see whether end users are contract owners), and where you provide the result as discussed above. For these cases, customers typically did not acquire the date of birth.

@HuubAppelboom
Copy link
Collaborator

Hi @ToshiWakayama-KDDI @GillesInnov35 @KevScarr , all,

Regarding the aggregated score we have been discussing so far, I think we should be providing it slightly different than with KYC Match.

What I would propose is to let the aggregated score by an estimate in how many cases the Age Verification is correct.

For example, if the developer does not provide any additional data to see whether the contract owner is the end user, you simply return an estimate of for example 82%, in case you know from KYC match statistics that on average, in 82% of cases the end user and the contract owner is the same. And if the developer provides more data (like first name, last name etc), you adjust the estimate accordingly (tkaing into account also the scores that these individual attributes have).

Since this is a different method than with KYC Match (you give an estimate how reliable the Age Verification is), it may be better to give this indicator a different name than "score". Perhaps "reliability_indicator" would be a beter word for it.

@KevScarr
Copy link
Collaborator

KevScarr commented Oct 4, 2024

@HuubAppelboom You may need to be careful using statistics built on KYC match success rates; when we first launched in UK we had a Bank that would do a KYC check using the current details on the account and the new details being printed onto the account. In this scenario we saw our match rate degrade quickly. At most, we'd be reporting a success 50% of the time :( as at least one lookup will always be wrong.
Could that kind of stat be provided via a portal or where you host your APIs & developer docs? We hadn't considered publishing match rates (due to the different use-cases it's serving) but it's an interesting idea that you propose.

@HuubAppelboom
Copy link
Collaborator

@KevScarr Hi Kevin, it's not the idea that you provide match rates for any use cases, I don't think this a good idea. In stead, you use an as good as possible estimate what the percentage of users is where the contract owner is the end user, as an idication how reliable the age verification is. This percentage will climb ofcourse when the developer provides more details about the end user.
And when one of the attributes has for example 97% match with fuzzy logic, you can also take this into account.

This will only work when you have sufficient statistics on your base. When the target group is not your average base (for example students) it will not be very precise, and will deviate. But at least you have some indication how reliable the age verification is. And if you provide all the necessary detail (like first name and last name), it can still be very reliable.

@GillesInnov35
Copy link
Collaborator

the Thanks @HuubAppelboom , @KevScarr , very interesting comments on how to see Age verification.

My comments on:

  • The identity doesn't match

In the list of possible answers we may be overlooking the scenario where there is a clear mismatch between the optional pararmeters provided (for example in givenName, familyName). This means the end user is not the contract owner.

The simplier way would be to use an unique string result not_available but in this case we do not distinguish the result of identity control with the age verification.
The question is: is it useful for the developer to differentiate the case the identity atributes do not match and the case the age data are not available.

  • 2 versions of the API

One is a very simple one, in which the developer simply wants to check the DoB a customer has entered (without checking any additional info).

it is very close to kyc-match offer (used with only 1 attribute), isn't it ? coudl it be confusing ?

  • Db stats on age verification
    The fact that not all MNO will manage a Db Stats on Age Verification reliability could be seen as lower quality solutions.

BR
Gilles

@HuubAppelboom
Copy link
Collaborator

@KevScarr @GillesInnov35 In any case, we should somehow find a way to communicate towards developers that providing extra identification data to distinguish contract owners from end users results in a more reliable age verification. That is omething we should at least include in the documentation , otherwise you run the risk that an unspecting developer (who is not familiar with the issue contract-owner vs end user) may be submitting just a phone number, and expect that this always very reliable. The more personal data you provide, the more reliable the result will be.

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Hi @HuubAppelboom , @KevScarr , @GillesInnov35 ,
Thanks, but the discussions seemed complicated.

So, is it OK for us to continue the currently proposed Age Verification API proposal and to complete the initial version of it? This is my (KDDI's) preference, and, if the supbroject/any of you need another version or feature, let's discuss it separately.

Just to review the Gilles' summary, below is 'What might be the next steps':

I think it is better for us to close the issue #46, if you guys agree.

Best regards,
Toshi

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Hi @HuubAppelboom , @KevScarr , @GillesInnov35 ,

In addition, regarding extra identification data to distinguish contract owners from end users, I could agree to include something in the documentation. However, actually for KDDI, it seems a bit different from your situation, but our customrs want to just do age-verify without scoring feature, and we KDDI do not have any need of scoring. So, as we have proposed before, we would like to keep identification information input optional as well as keep implementation of scoring feature optional (same as KYC Match Scoring feature).

Best regards,
Toshi

@HuubAppelboom
Copy link
Collaborator

Hi @ToshiWakayama-KDDI @KevScarr @GillesInnov35 ,

As far as I am concerned, we can keep both the additional information optional, as well as the scoring and the scoring method used. We can always make local alignment how to do this in the various markets.

@GillesInnov35
Copy link
Collaborator

hi, yes I agree with your proposal @ToshiWakayama-KDDI and HuubAppelboom. Aditional identification must be optional, I think that's what we proposed.
In case only the ageThreshold has been provided, the response should be below
{ "ageThreshold": 18, "ageVerified": "true" }

otherwise if information of user's identity are part of the request body identityMatchScore should be returned
{
"ageThreshold": 18,
"ageVerified": "true",
"identityMatchScore": 90
}
``

I propose to update the draft design in PR #50 with API swagger corrections and updates.

BR
Gilles

@HuubAppelboom
Copy link
Collaborator

HuubAppelboom commented Oct 9, 2024

@GillesInnov35 @ToshiWakayama-KDDI @KevScarr
Yes, good idea to update the draft design.

One addition I would like to add, and that is that you can also add the Date of Birth to the list of identifiable information.
It may sound a bit strange, but in practice we see that an exact match on this field is a very good check (better that First Name and Last Name etc) whether it is the same person or not. If the API Consumer gives the wrong DoB, you can respond with not_available. And if we do it this way, we will not need a separate API for just a DoB check, as I previously suggested.

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Hi @GillesInnov35 , @HuubAppelboom , @KevScarr ,

Thanks, and sorry for the late response.

May I reiterate my (KDDI's) proposal that MNO's/API provider's implementation of the identityMatchScore feature is kept optional, because, for some MNOs/API providers including KDDI, it may not be needed as their services, and it is better to have some flexibility for providing this API/service, e.g. at the beginning, they won't provide Age Verificaiton API/service without scoring feature, and then after some time, some months or some years, they will add scoring feature to their Age Verification API/service.

I hope this proposal is acceptable.

Assuming it is acceptable, for API specification, if information of user's identity is included in the request body but the scoring feature is not available with the MNO/API provider, there could be quick two options:

Option 1: nothing will be returned, and response could be;
{
"ageThreshold": 18,
"ageVerified": "true",
}
(API Description should say something like : if you include information of user's identity in the request body but you do not receive "identityMatchScore" attribute in the response body, it means the API provider does not provide the "identiyMatchScore" feature.)

Or Option 2: something showing unavailability of the scoring feature will be returned, and response could be:
{
"ageThreshold": 18,
"ageVerified": "true",
"identityMatchScore": "not_available" (or an impossible value e.g. 999)
}

What do you think?

Best regards,
Toshi

@HuubAppelboom
Copy link
Collaborator

@ToshiWakayama-KDDI @KevScarr @GillesInnov35

Hi Toshi, all,

Perhaps the best is to do the same as with KYC Match, where the Score returned is also optional, and if it is not calculated, it is not returned.

At least we are then consistent within the API family ;-)

Regards
Huub

@GillesInnov35
Copy link
Collaborator

hi @ToshiWakayama-KDDI @HuubAppelboom , as IdentityMatchScore is an integer we should not be able to return a not-available. I'd also prefer not to return any match score if scoring is not available on MNO side.
Rules must be clearly defined and specified in that way.
Thanks,
BR
Gilles

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Thank you, @GillesInnov35 , @HuubAppelboom , @KevScarr ,

I think it has been incorporated into the proposed YAML, but I would like to write down what have been agreed as below, if my uderstanding is correct:

Input/Output (R:required, O:optional)

  • Request Body
  1. phoneNumber [O]
  2. ageThreshold [R]
  3. idDocument [O]
  4. name [O]
  5. givenName [O]
  6. familyName [O]
  7. middieNames [O]
  8. familyNameAtBirth [O]
  9. birthdate [O]
  10. email [O]
  • Response
  1. ageThreshold [R]
  2. ageVerified [R] True/ false/ unverified/ not_available *1
  3. identityMatchScore [O] *2

ageVerified value (*1)

  • true: if the subscriber's age is equal to or more than the 'ageThreshold' value sent by the request (i.e. the subscriber's age >= the 'ageThreshold' value sent by the request)
  • false: if the subscriber's age is less than the 'ageThreshold' value sent by the request (i.e. the subscriber's age < the 'ageThreshold' value sent by the request)
  • unverified: if MNO has not verified the validity of the information it holds.
  • not_available: if age information is not available

Opitional identityMatchScore (*2)
In addition to the identifiable information attributes being optional, the identityMatchScore returned is also optional. So, if identityMatchScore is not calculated, identityMatchScore is not returned. (This is consistent with KYC Match Scoring feature.)

Thank you.

@KevScarr
Copy link
Collaborator

Captured from todays call; a proposal to split the response object to include:-

  1. ageVerified: True | False | not_available (mandatory)
  2. verifiedStatus: True | False (optional) (feel free to tweak the field name); Used to indicate if the information provided was checked against another form of official identification.

@GillesInnov35
Copy link
Collaborator

GillesInnov35 commented Oct 15, 2024

Thanks @KevScarr, also proposed to remove ageThreshold from the response body to be compliant with the other API.
I wonder if we should not propose an other name than verifiedStatus, it is very similar to ageVerified.
Gilles

@KevScarr
Copy link
Collaborator

@GillesInnov35 Good shout.... I think ageVerified would be a better name to state if it was verified by the MNO and then use ageCheck to give the true/false/not_available. Do you have a view on what would be a better name to use?
Kev.

@GillesInnov35
Copy link
Collaborator

hi Kevin, I also like your proposition for ageVerified according to discussions we had and the meaning of this returned attribute.
ageCheck may be also a goog name as the value is not a boolean.
Thanks
BR
Gilles

@HuubAppelboom
Copy link
Collaborator

As discussed in last weeks meeting, there was a request to discuss how to calculate the identityMatchScore.

Here is a proposal on how to do it. This is just one proposal, there may be other alternatives, very much depending on the quality of the data that is available or local market conditions

The main issue that you'll need to think about is how to work with identifiers for which users may have multiple valid data points, and how to deal with that. For example, in the Netherlands we accept ID Cards, Passports, Driver Licenses (and a couple more) as proof of identity. These all have different document numbers.

Also, one party may have a document number of a passport which has expired, and the other party may have the document number of the new document, which would result in a mismatch.

The same issue may occur with email addresses, where users may have more than one address. WHen there is a mismatch, it does not mean that the end user and the contract owner are different persons.

However, you can still use this information in calculating the identityMatchScore, and below is one proposal how to do it.

For KPN, I would propose the following steps to calculate identiyMatchScore

  1. In case the API Consumer provided Date of Birth, and there is a mismatch with API Provider Date of Birth always return "not_available", and do not provide an identiyMatchScore
  2. calculate subscores for
    • an aggregated name score x% based by multiplying scores on all available name fields
    • ID document match -> this will be either 0% or 100%
    • email match - this will be either 0% or 100%
  3. Depending on the available subscores, calculate the identityMatchScore as follows:
    a) Only name input : return x% name score
    b) Only ID Document input : return 100% or 0%
    c) Only email input : return 100% or 0%
    d) Only name input and ID Document input :
    - if ID Document matches return average of 100% and x% name score
    - If ID Document does not match return x% name score
    e) Only name input and email input :
    - if email matches return average of 100% and x% name score
    - If email does not match return x% name score
    f). Only ID Document and email input :
    - if email matches or ID Document matches return 100% score
    - If both do not match, return 0% score
    g). Name input, ID Document and email input :
    - if ID Document and email matches return average of (100%, 100% and x% name score)
    - If only ID Document matches (and not email) or only email matches (and not ID Document) return average of 100% and x% name score
    - If ID Document does not match and email does not match, return x% name score
    h). No inputs:
    Don’t provide a score (or provide a static score based on statistics, like abc% of users are also contract owners)

So, for each possible combination of provided inputs, you decide what to do with it.
A positive ID Document match or email match is used only to increase the name score to indicate the result is more reliable.

Depending on local market conditions, you may choose a diferrent approach (for example when the ID Document number is always the same), or you decide that the email must always match before giving any result back etc.

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Hi @GillesInnov35 , @KevScarr , @HuubAppelboom , all,

As we have had some updates, let me write down Request and Response attributes as below for common understanding.

Request body

  • phoneNumber [Optional] -> Is 'Optional' OK?

  • ageThreshold [Required]

  • extra identification information - any of idDocument, name, givenName, familyName, middieNames, familyNameAtBirth, birthdate, email [Optional]

Response

  • ageCheck: true | false | not_available [Required]

    -true: if Contract Owner's age derived from the contract information is larger than (>=) ageThreshold
    -false: if Contract Owner's age derived from the contract information is smaller than (<) ageThreshold
    -not_available: other than above, eg. if Contract owner's age related information is not available in the contract information

  • verifiedStatus: true | false [Optional]

    -true: to indicate that the ageCheck response provided was checked against another form of official identification
    -false: to indicate that the ageCheck response provided was not checked against another form of official identification
    [Note] optionality: if a MNO/API provider wants to indicate

  • identityMatchScore: an integer score [Optional]

    -0-100? integer score: calculated by identification information provieded by the request body
    [Note] How to caluclate score -> under discussion (Thanks, Huub)
    [Note] optionality: In addition to extra identification information being optional in Request body, identityMatchScore returned is also optional. If identityMatchScore is not calculated by a MNO/API provider, identityMatchScore is not returned. (This is consistent with KYC Match Scoring feature.)

Please let us know anything wrong.

BR
Toshi

@HuubAppelboom
Copy link
Collaborator

HuubAppelboom commented Oct 26, 2024

@ToshiWakayama-KDDI
PhoneNumber in the Request body: I would not describe as optional. This will lead to a combination of Number Verification and Age Verification. Because of privacy reasons (knowledge of a phone number is not required in case of Authorization Code flow) and commercial/billing reasons we don't want provide this combination with a 3 legged fow. If customers want to verify the phone number as wel, this should be done in a separate flow, for which consent may be required. If you want to provide a combination of API's at a reduced rate (or Number Verification at no extra costs), this should be solved in the billing system, if you ask me.

I would describe the PhoneNumber in the request body as "Only required in case a 2 legged flow has been agreed between API Provider and API Consumer."

The not_available answer should also be returned in case birthdate provided with the optional extra identification info does not match (you can not provide a solid true / false answer in this case).

IdentityMatchSCore should indeed be an integer, as with KYC Match.

@GillesInnov35
Copy link
Collaborator

thanks @ToshiWakayama-KDDI , @HuubAppelboom. PhoneNumber as an optional parameter is also a requirement in others CAMARA APIs. Do you mean this rule (2-Legged mode) should be also specified for the others to be consistent ?
BR
Gilles

@GillesInnov35
Copy link
Collaborator

For ageCheck response parameter

  • ageCheck: true | false | not_available [Required]
    - true: if Contract Owner's age derived from the contract information is larger than (>=) ageThreshold
    - false: if Contract Owner's age derived from the contract information is smaller than (<) ageThreshold
    - not_available: other than above, eg. if Contract owner's age related information is not available in the contract information

We should also specify that not_available should also be returned when the user phone number (from token) doesn't match with the contract owner number.

@HuubAppelboom
Copy link
Collaborator

@GillesInnov35 We don't agree with this approach, because of privacy and commercial reasons. The only thing that needs to be verified is the age of the user; by integrating Number Verification into the API for the authorization code flow, you provide a mechanism for API Consumers to check the phone number as well (and perhaps they have no business in knowing the phone number of the user). Also, this would force us to charge extra for the authorization code flow, or accept a revenue leak, which is another complicating factor. That is why we think combining API's is a very bad idea. When the user phone number is present in the body request with the authorization code flow, we should always return an error code.

@rartych
Copy link
Collaborator

rartych commented Oct 29, 2024

Please check and review the proposed guidelines related to API misuse in camaraproject/Commonalities#324

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Hi @GillesInnov35 , @HuubAppelboom , @KevScarr , @rartych

Sorry for the late response.

As discussed at 2024/10/29 Meeting, I have discussed internally and for this API, Age is only the focused information, so it is OK to remove phoneNumber from request body and the phone number associated with a 3-legged Access Token is used for identity of the targeted contract.

I understand this is what others want.

@ToshiWakayama-KDDI
Copy link
Collaborator Author

ToshiWakayama-KDDI commented Nov 8, 2024

So, I updated Summary; Italic parts have been modified:

=====

Request body

  • phoneNumber [Required; Only required in case a 2-legged flow has been agreed between API Provider and API Consumer; otherwise, none]
  • ageThreshold [Required]
  • extra identification information - any of idDocument, name, givenName, familyName, middieNames, familyNameAtBirth, birthdate, email [Optional]

Response

ageCheck: true | false | not_available [Required]

-true: if Contract Owner's age derived from the contract information is larger than (>=) ageThreshold
-false: if Contract Owner's age derived from the contract information is smaller than (<) ageThreshold
-not_available: other than above, e.g. if Contract owner's age-related information is not available in the contract information, if the provided birthdate does not match the one that an MNO/API Provider has (but this is optional as part of optional identityMatchScore calculation feature)

verifiedStatus: true | false [Optional]

-true: to indicate that the ageCheck response provided was checked against another form of official identification
-false: to indicate that the ageCheck response provided was not checked against another form of official identification
[Note] optionality: if an MNO/API provider wants to indicate

identityMatchScore: an integer score [Optional]

-0-100 integer score: calculated by identification information provided by the request body
[Note] How to calculate score -> under discussion
[Note] optionality: In addition to extra identification information being optional in Request body, identityMatchScore returned is also optional. If identityMatchScore is not calculated by a MNO/API provider, identityMatchScore is not returned. (This is consistent with KYC Match Scoring feature.)

=====

Hope we could conclude the API specifications base as above, except for how to calculate the aggregated score.

Best regards,
Toshi

@GillesInnov35
Copy link
Collaborator

Thanks @ToshiWakayama-KDDI , I'd prefer to remove Required and to let
phoneNumber [Only Required in case a 2-legged flow has been agreed between API Provider and API Consumer; otherwise, none]

BR
Gilles

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Thanks @GillesInnov35 . I updated my previous comment. ( #81 (comment) )

Thanks.
Toshi

@GillesInnov35
Copy link
Collaborator

hi @HuubAppelboom, thanks a lot for your detailed and intereting proposition for match score calculation. Is it a experience feedback from what you've implemented ? For information as the idDocument is not used at Orange, we won't be concerned by most of the cases. But for the others it could work.

BR
Gilles

@HuubAppelboom
Copy link
Collaborator

@GillesInnov35 This is mostly based on the experience we have had so far with Match and other identity propositions, and several pocs that have been done with different customer groups. We do have the iDdocument, but the API Consumers that have it probably have the DoB as well form the ID Document, so probably you will not see it that much in requests.

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Hi @GillesInnov35 , @HuubAppelboom , @KevScarr , @rartych ,

I have another proposal to the current YAML, in addition to the proposals shared in PR #50.

As we have decided to make phoneNumber 'not included in the request' for Age Verification API, I think we need to modify the Error handling part of the API Description, becuase current text is not applicable. (I think it is ok because Guidlielines is just a guideline.)

The following is an idea for modification.

---Current---

Identifying a device from the access token

This specification defines the phoneNumber field as optional in API requests, specifically in cases where the API is accessed using a 3-legged access token, and the device can be uniquely identified by the token. This approach simplifies API usage for API consumers by relying on the device information associated with the access token used to invoke the API.

Handling of device information:

Optional phoneNumber for 3-legged tokens:

  • When using a 3-legged access token, the device associated with the access token must be considered as the device for the API request. This means that the phoneNumber is not required in the request, and if included it must identify the same device, therefore it is recommended NOT to include it in these scenarios to simplify the API usage and avoid additional validations.

Validation mechanism:

  • The server will extract the device identification from the access token, if available.
  • If the API request additionally includes a phoneNumber parameter when using a 3-legged access token, the API will validate that the device identifier provided matches the one associated with the access token.
  • If there is a mismatch, the API will respond with a 403 INVALID_TOKEN_CONTEXT error, indicating that the device information in the request does not match the token.

Error handling for unidentifiable devices:

  • If the phoneNumber parameter is not included in the request and the device information cannot be derived from the 3-legged access token, the server will return a 422 UNIDENTIFIABLE_DEVICE error.

Restrictions for tokens without an associated authenticated identifier:

  • For scenarios which do not have a single device identifier associated to the token during the authentication flow, e.g. 2-legged access tokens, the phoneNumber parameter MUST be provided in the API request. This ensures that the device identification is explicit and valid for each API call made with these tokens.

---Proposed change---

Identifying a device from the access token

This specification defines the phoneNumber field as required optional in API requests, specifically in cases where the API is accessed using a 2-legged access token (under agreement between API Consumer and API Provider). However, this specification defines it as none in cases where the API is accessed using a 3-legged access token, and because the device can be uniquely identified by the token. This approach simplifies API usage for API consumers by relying on the device information associated with the access token used to invoke the API.

Handling of device information:

Optional phoneNumber for 3-legged tokens:

  • When using a 3-legged access token, the device associated with the access token must be considered as the device for the API request. This means that the phoneNumber is not required in the request, and so if included it must be neglected identify the same device, therefore it is recommended NOT to include it in these scenarios to simplify the API usage and avoid additional validations.

Validation mechanism:

  • The server will extract the device identification from the access token, if available.
  • If the API request additionally includes a phoneNumber parameter when using a 3-legged access token, the API will validate that the device identifier provided matches the one associated with the access token.
  • If there is a mismatch, the API will respond with a 403 INVALID_TOKEN_CONTEXT error, indicating that the device information in the request does not match the token.

Error handling for unidentifiable devices:

  • If the phoneNumber parameter is not included in the request and the device information cannot be derived from the 3-legged access token, the server will return a 422 UNIDENTIFIABLE_DEVICE error.

Restrictions for tokens without an associated authenticated identifier:

  • For scenarios which do not have a single device identifier associated to the token during the authentication flow, e.g. 2-legged access tokens, the phoneNumber parameter MUST be provided in the API request. This ensures that the device identification is explicit and valid for each API call made with these tokens.

What do you think?

BR
Toshi

@rartych
Copy link
Collaborator

rartych commented Nov 19, 2024

The new recommended template for info.description is proposed in camaraproject/Commonalities#324.
The release candidate of Commonalities should be ready by mid of December.
I guess we can go with PR #50, and then apply the changes required Spring25 meta-release in Commonalities.

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Hi @GillesInnov35 , @HuubAppelboom , @KevScarr , @rartych, all,

I think there is one thing missing. We should set a certain range for ageThreshold value, and if an input value is out of the range, a 400 error will be returned for API customers' benefit, although technically ageThreshold can be any integer value.

I have no firm idea, but for example:
-ageThreshold: integer betwee 0 and 200
(In future, or in a certain country, an age 0 child could have a subscription contract?)
(Human beings will never turn 200?)

Any thoughts, any practise?

Thanks,
Toshi

@KevScarr
Copy link
Collaborator

@ToshiWakayama-KDDI You raise a good point and Im wondering rather than a maximum whether there should be a minimum?
ie if in your country you will only age check against a threshold of "18" and above, and you receive "16" in the request as the threshold, what action is taken?

(Im making the assumption that our privacy teams will set a value that we will not do checks against, ie >12)

@HuubAppelboom
Copy link
Collaborator

@KevScarr @ToshiWakayama-KDDI In Europe, there is a lower limit of 16 years, below which you need to acquire parental consent for processing personal data. For the details, see https://gdpr-info.eu/art-8-gdpr/ (and you check also loal regulation).

In practice, at KPN all contract owners need to be 18+ (because of national legislation), so we can't do anyhting with threshold requests below 18. In case the developer asks for 16 or 17, we propose to return the (exsisting) error 422 with the message Service not supported for this phoneNumber.

@GillesInnov35
Copy link
Collaborator

hi @HuubAppelboom, why not 'not_available' returned for ageCheck in this case ? WDYT

@KevScarr
Copy link
Collaborator

@HuubAppelboom Completely aligned, for the UK launch I would fully expect the same 18+ rule to be in affect; happy to support the use of error:422 for this scenario.

@HuubAppelboom
Copy link
Collaborator

@GillesInnov35 I would only provide not available in case it is not available for this particular number (but for other numbers it is and can be supported). Very much in line with what we do with Match. For cases where you will never get an answer, use the 422 error. That may trigger people to stop sending the data to you as well, which is better.

@GillesInnov35
Copy link
Collaborator

thanks @HuubAppelboom, it seems OK but I've to see with my Production team, 422 Service not supported is already use for eligibility of the concerned phoneNumber.
BR
Gilles

@ToshiWakayama-KDDI
Copy link
Collaborator Author

ToshiWakayama-KDDI commented Nov 22, 2024

Hi @GillesInnov35 , @HuubAppelboom , @KevScarr ,

Thanks for your comments. Well, I don't think we (Japan) have such restriction.

OK, so, how about this kind of description?

ageThreshold: interger 0-120

-if ageThreshold input is either below 0, over 120, not interger ->400 Invalid argument or 400 Out of range
-above is passed, then if ageThreshold is below each compnany/country's specified limit ->422 not supported

(Note: chatGPT advised me that 120 is widely used for the max age in this kind of system design. In addition, a 2016 study published in Nature says that 115 would be the maximum human lifecycle, and historically 122 was the highest age for a human who died in 1997 (a French woman) .)

WDYT

Regards,
Toshi

@ToshiWakayama-KDDI
Copy link
Collaborator Author

Hi @HuubAppelboom , @GillesInnov35 , @KevScarr , @claraserranosolsona , all,

Thank you very much for today's discussion on ageThreshold value range. If I understand correctly, we have agreed that 'ageThreshold' input value must be an interger between 0 and 120, and if any value do not follow this rule, an error is returned. How to handle additional restriction / limitation due to specific rules / regulation is to be discussed further.

I thought '400 Out of range' is better than '400 Invalid argument', but it seems '400 Out of range' does not fit 'not integer' error. So, the following is my modified proposal:

ageThreshold: interger, 0-120
-> if ageThreshold input is not interger, '400 Invalid argument' is returned.
-> if ageThreshold input is either below 0 or over 120, '400 Out of range' error is returned.

Hope this would be fine with you all.

Thanks,
Toshi

@HuubAppelboom
Copy link
Collaborator

@ToshiWakayama-KDDI @GillesInnov35 @KevScarr all,

I discussed the legal limit for minors under the GDPR with our privacy officer, and we think we don't need to create an error code for this.

The reason is that when the API Consumer is going to process personal data for people under 16, they need to acquire parental consent. If they obtained it, there is no problem, but if they did not, they are already breaking the law, and shouldn't be sending the data anyhow the API Provider.

The best solution for the API Provider is to put in the contract with the API Consumer that they are responsible for acquiring parental consent in any case.

If you want to play it safe, the API Provider could also generate an error in case a date of birth in present in the API Request is below 16 years of age, but the API Provider does not know whether the API Consumer has acquired parental consent. In any case, we can not put this in the specification, because teh API Consumer may have aquired it (and that would be blocking cases which are perfectly fine).

We conclude that the best solution is to not include a lower age limit check in the specification, and leave the 16+ check entirely up to the API Consumer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
subproject management Indicating issues with subproject repository or release management process
Projects
None yet
Development

No branches or pull requests

5 participants