Look ahead for provided claims in distributed/aggregated claims

Issue #1242 resolved
Torsten Lodderstedt created an issue

Ross Little Armitt from GRIDS project (https://grids-cef.eu/) approached Daniel and me with an inquiry regarding aggregated/distributed claims. The aim is to put more information in the ID Token/UseInfo response to allow the RP to determine what verified End-User claims are available in what aggregated/distributed claims source.

So far, we only make transparent that “verified_claims” is available. Here is an example:

{
  "iss": "https://server.example.com",
  "sub": "248289761001",
  "email": "janedoe@example.com",
  "email_verified": true,
  "_claim_names": {
    "verified_claims": [
      "src1",
      "src2"
    ]
  },
  "_claim_sources": {
    "src1": {
      "JWT": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwcz
      ovL3NlcnZlci5vdGhlcm9wLmNvbSIsInN1YiI6ImU4MTQ4NjAzLTg5MzQtNDI0N
      S04MjViLWMxMDhiOGI2Yjk0NSIsInZlcmlmaWVkX2NsYWltcyI6eyJ2ZXJpZmlj
      YXRpb24iOnsidHJ1c3RfZnJhbWV3b3JrIjoiaWFsX2V4YW1wbGVfZ29sZCJ9LCJ
      jbGFpbXMiOnsiZ2l2ZW5fbmFtZSI6Ik1heCIsImZhbWlseV9uYW1lIjoiTWVpZX
      IiLCJiaXJ0aGRhdGUiOiIxOTU2LTAxLTI4In19fQ.FArlPUtUVn95HCExePlWJQ
      6ctVfVpQyeSbe3xkH9MH1QJjnk5GVbBW0qe1b7R3lE-8iVv__0mhRTUI5lcFhLj
      oGjDS8zgWSarVsEEjwBK7WD3r9cEw6ZAhfEkhHL9eqAaED2rhhDbHD5dZWXkJCu
      XIcn65g6rryiBanxlXK0ZmcK4fD9HV9MFduk0LRG_p4yocMaFvVkqawat5NV9QQ
      3ij7UBr3G7A4FojcKEkoJKScdGoozir8m5XD83Sn45_79nCcgWSnCX2QTukL8Ny
      wIItu_K48cjHiAGXXSzydDm_ccGCe0sY-Ai2-iFFuQo2PtfuK2SqPPmAZJxEFrF
      oLY4g"
    },
    "src2": {
      "endpoint": "https://server.yetanotherop.com/claim_source",
      "access_token": "ksj3n283dkeafb76cdef"
    }
  }
}

The RP now needs to query the distributed claims source in order to determine what is available there. That might cause additional cost without providing the required claims, so the question is whether some more details can be provided to support the RP’s decision.

Ross proposed an extension to the “_claim_names” structure like this:

{
    "iss": "https://self-issued.me",
    "sub": "248289761001",
    "preferred_username": "superman445",
    "_claim_names": {
        "verified_claims": {
            "given_name": [
                "src1",
                "src2"
            ],
            "family": [
                "src1",
                "src2"
            ],
            "legal_name": "src1",
            "legal_person_identifier": "src1",
            "lei": "src1"
        }
    }, 

}

Comments (11)

  1. Torsten Lodderstedt reporter

    My proposal would be to add additional metadata to the claims source element itself. This would allows to use a fully fledged structure giving rise to the fulfilled verification requirements as well.

    {
        "iss": "https://self-issued.me",
        "sub": "248289761001",
        "preferred_username": "superman445",
        "_claim_names": {
            "verified_claims": [
                "src1",
                "src2"
            ]
        },
        "_claim_sources": {
            "src1": {
                "JWT": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwcz
         ovL3NlcnZlci5vdGhlcm9wLmNvbSIsInN1YiI6ImU4MTQ4NjAzLTg5MzQtNDI0N
         S04MjViLWMxMDhiOGI2Yjk0NSIsInZlcmlmaWVkX2NsYWltcyI6eyJ2ZXJpZmlj
         YXRpb24iOnsidHJ1c3RfZnJhbWV3b3JrIjoiaWFsX2V4YW1wbGVfZ29sZCJ9LCJ
         jbGFpbXMiOnsiZ2l2ZW5fbmFtZSI6Ik1heCIsImZhbWlseV9uYW1lIjoiTWVpZX
         IiLCJiaXJ0aGRhdGUiOiIxOTU2LTAxLTI4In19fQ.FArlPUtUVn95HCExePlWJQ
         6ctVfVpQyeSbe3xkH9MH1QJjnk5GVbBW0qe1b7R3lE-8iVv__0mhRTUI5lcFhLj
         oGjDS8zgWSarVsEEjwBK7WD3r9cEw6ZAhfEkhHL9eqAaED2rhhDbHD5dZWXkJCu
         XIcn65g6rryiBanxlXK0ZmcK4fD9HV9MFduk0LRG_p4yocMaFvVkqawat5NV9QQ
         3ij7UBr3G7A4FojcKEkoJKScdGoozir8m5XD83Sn45_79nCcgWSnCX2QTukL8Ny
         wIItu_K48cjHiAGXXSzydDm_ccGCe0sY-Ai2-iFFuQo2PtfuK2SqPPmAZJxEFrF
         oLY4g"
            },
            "src2": {
                "claims_available": {
                    "verified_claims": {
                        "verification": {
                            "trust_framework": {
                                "value": "eidas"
                            },
                            "identity_assurance_level": {
                                "value": "high"
                            }
                        },
                        "claims": {
                            "given_name": null,
                            "family_name": null,
                            "birthdate": null,
                            "legal_name": null,
                            "legal_person_identifier": null,
                            "lei": null
                        }
                    }
                }
            },
            "endpoint": "https://op.mymno.com/claim_source",
            "access_token": "ksj3n283dkeafb76cdef"
        }
    }
    }
    

  2. Ross Little

    To follow the OpenID specification approach, I would propose a small update to move all this under _claim_names as per the example below. WDYT?

    {
    "_claim_names": {
    "verified_claims": [
    {
    "src1": {
    "verified_claims_available": {
    "verification": {
    "trust_framework": {
    "value": "grids_kyb"
    },
    "evidence": [
    {
    "type": {
    "value": "company_register"
    }
    }
    ]
    },
    "claims": {
    "legal_name": null,
    "legal_person_identifier": null,
    "lei": null,
    "vat_registration": null,
    "address": null,
    "tax_reference": null,
    "sic": null,
    "business_role": null,
    "sub_jurisdiction": null,
    "trading_status": null
    }
    }
    }
    },
    {
    "src2": {
    "verified_claims_available": {
    "verification": {
    "trust_framework": {
    "value": "grids_kyb"
    },
    "evidence": [
    {
    "type": {
    "value": "company_register"
    }
    }
    ]
    },
    "claims": {
    "legal_name": null,
    "legal_person_identifier": null,
    "sic": null,
    "business_role": null,
    "sub_jurisdiction": null,
    "trading_status": null
    }
    }
    }
    }
    ]
    },
    "_claim_sources": {
    "src1": {
    "endpoint": "https://data_provider1.example.com/claim_source",
    "access_token": "eyJhbGciOIkpXVCJ9.eyJpcI6ImU4MTQ4NjAzLTg5MzQtNDI0N.S04MjViLWMxMDhiOGI2"
    },
    "src2": {
    "endpoint": "https://data_provider2.example2.com/claim_source",
    "access_token": "Btui76787687GciOIkpXVCJ9.zxc45ReyJpcI6zLTg5MzQtNDI0N.ViLWMxMDhi323"
    }
    }
    }

  3. Ross Little

    Ok i re-do the example with indents:

    {
      "_claim_names": {
        "verified_claims": [
          {
          "src1":   { 
            "verified_claims_available": {
                "verification": {
                    "trust_framework": {
                      "value": "grids_kyb"
                    },
                    "evidence": [
                     {
                      "type": {
                          "value": "company_register"
                      }
                     }
                    ]
                },
                "claims": {
                    "legal_name": null,
                    "legal_person_identifier": null,
                    "lei": null,
                    "vat_registration": null,
                    "address": null,
                    "tax_reference": null,
                    "sic": null,
                    "business_role": null,
                    "sub_jurisdiction": null,
                    "trading_status": null
                }
         }
        }
        },
            {
          "src2":   {
            "verified_claims_available": {
                "verification": {
                    "trust_framework": {
                      "value": "grids_kyb"
                    },
                    "evidence": [
                     {
                      "type": {
                          "value": "company_register"
                      }
                     }
                    ]
                },
                "claims": {
                    "legal_name": null,
                    "legal_person_identifier": null,
                    "sic": null,
                    "business_role": null,
                    "sub_jurisdiction": null,
                    "trading_status": null
                }
          }
            }
          }
        ]
      },
      "_claim_sources": {
        "src1": {
            "endpoint": "<https://data_provider1.example.com/claim_source",>
            "access_token": "eyJhbGciOIkpXVCJ9.eyJpcI6ImU4MTQ4NjAzLTg5MzQtNDI0N.S04MjViLWMxMDhiOGI2"
        },
        "src2": {
            "endpoint": "<https://data_provider2.example2.com/claim_source",>
            "access_token": "Btui76787687GciOIkpXVCJ9.zxc45ReyJpcI6zLTg5MzQtNDI0N.ViLWMxMDhi323"
        }
      }
    }
    

  4. Ross Little

    We propose a slight modification to use named objects in the claims object instead of an array as proposed below:

    {
      "_claim_names": {
        "verified_claims":
         {
          "src1":   { 
            "verified_claims_available": {
                "verification": {
                    "trust_framework": {
                      "value": "grids_kyb"
                    },
                    "evidence": [
                     {
                      "type": {
                          "value": "company_register"
                      },
                      "registry": {
                        "country": {
                          "essential": true,
                          "purpose": "string",
                          "value": "ES"
                        }
                      },
                      "document": {
                        "SKU": {
                          "value": "REX"
                        }
                      }
                     }
                    ]
                },
                "claims": {
                    "legal_name": null,
                    "legal_person_identifier": null,
                    "lei": null,
                    "vat_registration": null,
                    "address": null,
                    "tax_reference": null,
                    "sic": null,
                    "business_role": null,
                    "sub_jurisdiction": null,
                    "trading_status": null
                }
            }
          },
          "src2":   {
            "verified_claims_available": {
                "verification": {
                    "trust_framework": {
                      "value": "grids_kyb"
                    },
                    "evidence": [
                     {
                      "type": {
                          "value": "company_register"
                      },
                      "registry": {
                        "country": {
                          "essential": true,
                          "purpose": "string",
                          "value": "ES"
                        }
                      },
                      "document": {
                        "SKU": {
                          "value": "REX"
                        }
                      }
                     }
                    ]
                },
                "claims": {
                    "legal_name": null,
                    "legal_person_identifier": null,
                    "sic": null,
                    "business_role": null,
                    "sub_jurisdiction": null,
                    "trading_status": null
                }
              }
            }
        }
      },
      "_claim_sources": {
        "src1": {
            "endpoint": "https://data_provider1.example.com/claim_source",
            "access_token": "eyJhbGciOIkpXVCJ9.eyJpcI6ImU4MTQ4NjAzLTg5MzQtNDI0N.S04MjViLWMxMDhiOGI2"
        },
        "src2": {
            "endpoint": "https://data_provider2.example2.com/claim_source",
            "access_token": "Btui76787687GciOIkpXVCJ9.zxc45ReyJpcI6zLTg5MzQtNDI0N.ViLWMxMDhi323"
        }
      }
    }
    

    The corresponding YAML would be as shown below:

        _claim_names:
          type: object
          nullable: true
          properties:
            verified_claims:
              type: object
              nullable: true
              additionalProperties:
                type: object
                properties:
                  verified_claims_available:
                    oneOf:
                    - $ref: '#/components/schemas/verified_claims_def'
                    - type: array
                      items:
                        $ref: '#/components/schemas/verified_claims_def' 
    
        verified_claims_def:
          type: object
          properties:
            verification:
              type: object
              properties:
                trust_framework:
                  $ref: '#/components/schemas/constrainable_element'
                userinfo_endpoint:
                 $ref: '#/components/schemas/constrainable_element'
                time:
                  $ref: '#/components/schemas/datetime_element'
                verification_process:
                  $ref: '#/components/schemas/simple_element'
                evidence:
                  type: array
                  minItems: 1
                  items:
                    oneOf:
                    - $ref: '#/components/schemas/utility_bill'
                    - $ref: '#/components/schemas/id_document'
                    - $ref: '#/components/schemas/qes'
                    - $ref: '#/components/schemas/company_register'
              required:
                - trust_framework
              additionalProperties: false
            claims:
              type: object
              nullable: true
              additionalProperties:
                type: object
                description: In this case the claim is requested with options to provide more info regarding if it is essential and its purpose
                properties:
                  essential:
                    type: boolean
                    example: true
                  purpose:
                    type: string
                    minLength: 3
                    maxLength: 300
                    example: To make communication look more personal
          required:
            - verification
            - claims
          additionalProperties: false
    

  5. Ross Little

    We have noticed the yaml didn’t match the example and the yaml should be updated for:

    '

    _claim_names:
      type: object
      nullable: true
      properties:
        verified_claims:
          type: object
          nullable: true
          additionalProperties:
            type: object
            properties:
              verified_claims_available:
                $ref: '#/components/schemas/verified_claims_def'
    

  6. Log in to comment