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

Adapt PID rulebook to latest SD-JWT VC #160

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

danielfett
Copy link

@danielfett danielfett commented Mar 26, 2024

The current description of the usage of SD-JWT in the PID rulebook is not sufficient to result in PID attestations that are compatible to existing conventions and standards like JWTs and SD-JWT VC in particular. The changes proposed here adapt the PID rulebook to be compatible with SD-JWT VC and to work in the direction proposed in SD-JWT VC DM.

The goal is also to make the best usage of SD-JWT VC Type Metadata, even though not all parts of that have made it into SD-JWT VC yet. This allows for automated discovery and processing of type metadata, like schemas (e.g., for relying parties) and rendering information

@danielfett danielfett marked this pull request as ready for review March 27, 2024 14:14
@danielfett danielfett requested review from peppelinux and c2bo March 27, 2024 14:14
Copy link

@peppelinux peppelinux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only editorials by my side, some further readings makes me more sensible from the reader perspective. I consider this approved even If I'm requesting these trivial editorials

docs/annexes/annex-06-pid-rulebook.md Outdated Show resolved Hide resolved
docs/annexes/annex-06-pid-rulebook.md Outdated Show resolved Hide resolved
docs/annexes/annex-06-pid-rulebook.md Outdated Show resolved Hide resolved
docs/annexes/annex-06-pid-rulebook.md Outdated Show resolved Hide resolved
docs/annexes/annex-06-pid-rulebook.md Outdated Show resolved Hide resolved
docs/annexes/annex-06-pid-rulebook.md Outdated Show resolved Hide resolved
docs/annexes/annex-06-pid-rulebook.md Outdated Show resolved Hide resolved
Copy link

@c2bo c2bo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I have any power to approve here but looks good to me

Copy link

@awoie awoie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great to me.

Copy link

@awoie awoie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, this looks good and fills an important gap in the specification. I really appreciate this addition.

@joelposti
Copy link
Contributor

The proposed claim set does not seem to include a claim that would specify the namespace/credential type eu.europa.ec.eudi.pid.1 in an issuer-agnostic way. Lack of such a claim makes it difficult for an RP to make a request where they say that they want a presentation of certain claims from a PID of any member state.

Consider the following presentation definition with which an RP requests given_name from a PID of any member state. The following request will not work without a credential_type or similar claim.

{
  "id": "foobar",
  "vp_formats": {
    "vc+sd-jwt": {
      "sd-jwt_alg_values": [
        "ES256"
      ],
      "kb-jwt_alg_values": [
        "ES256"
      ]
    }
  },
  "input_descriptors": [
    {
      "id": "given_name",
      "constraints": {
        "fields": [
          {
            "path": [
              "$.credential_type"
            ],
            "filter": {
              "const": "eu.europa.ec.eudi.pid.1"
            }
          },
          {
            "path": [
              "$.given_name"
            ],
            "filter": {
              "type": "string"
            }
          }
        ]
      }
    }
  ]
}

Also, the claim set does not include issuing_country which prevents an RP from requesting a PID from a specific member state. Vct might not work for this purpose because a PID Provider might need to add a version number to the vct value. Consider the following scenario:

  1. A PID Provider issues PIDs with vct value https://memberstate.example/credential/pid and vct#integrity claim having the SHA-384 digest of the metadata document.
  2. The metadata document contais a typo in one claims[].display['de-DE'].label field. The PID Provider cannot fix this typo by modifying the metadata document because then the SHA-384 digest of the metadata document would change breaking the metadata integrity for all PIDs the Provider has so far issued.
  3. To fix the typo the PID Provider needs to create a new metadata document and needs to start issuing PIDs with a new different vct value https://memberstate.example/credential/pid/1.1 and a new vct#integrity value.
  4. The new PIDs issued in step 3 are not accepted by RPs because in their presentation definitions they select PIDs having vct value https://memberstate.example/credential/pid specifically.

If the RPs instead selected using credential_type and issuing_country, which do not change between metadata document versions, the old and new PIDs would both be accepted by RPs in step 4. Below is a presentation definition with which an RP requests given_name from a PID of a specific member state. The request will not work without credential_type and issuing_country claims.

{
  "id": "foobar",
  "vp_formats": {
    "vc+sd-jwt": {
      "sd-jwt_alg_values": [
        "ES256"
      ],
      "kb-jwt_alg_values": [
        "ES256"
      ]
    }
  },
  "input_descriptors": [
    {
      "id": "given_name",
      "constraints": {
        "fields": [
          {
            "path": [
              "$.credential_type"
            ],
            "filter": {
              "const": "eu.europa.ec.eudi.pid.1"
            }
          },
          {
            "path": [
              "$.issuing_country"
            ],
            "filter": {
              "const": "DE"
            }
          },
          {
            "path": [
              "$.given_name"
            ],
            "filter": {
              "type": "string"
            }
          }
        ]
      }
    }
  ]
}

@joelposti
Copy link
Contributor

joelposti commented Jun 13, 2024

Thank you very much @danielfett for your replies to my comments and for the changes you made!

The proposed claim set does not seem to include a claim that would specify the namespace/credential type eu.europa.ec.eudi.pid.1 in an issuer-agnostic way. Lack of such a claim makes it difficult for an RP to make a request where they say that they want a presentation of certain claims from a PID of any member state.
Consider the following presentation definition with which an RP requests given_name from a PID of any member state. The following request will not work without a credential_type or similar claim.
(...)

Just as for ISO formats, the query language needs to accommodate for specifics of the credential format. Here, the logic is that a query for a base type may result in a response containing a credential of a type that extends the base type. Therefore, the query can ask for vct == urn:eu.europa.ec.eudi:pid:1 and may receive a credential with the vct https://example.bmi.bund.de/credential/pid/1.0.

So essentially vct: urn:eu.europa.ec.eudi:pid:1 in the presentation definition would map to vct: https://example.bmi.bund.de/credential/pid/1.0 in the credential. I would like to contest that idea: that mapping is custom domain specific logic. It deviates from Presentation Exchange and JSON Schema specifications. Presentation Exchange 2.0.0 says in section 5.1.1 Input Descriptor Object that filter field in an input descriptor should be a JSON Schema descriptor:

The fields object MAY contain a filter property, and if present its value MUST be a JSON Schema descriptor used to filter against the values returned from evaluation of the JSONPath string expressions in the path array.

The wallet and the RP would not be able to rely on existing JSON Schema implementations because "filter": { "const": "urn:eu.europa.ec.eudi:pid:1" } would not match by string comparison with any claim in the credential. Custom mapping logic would be required whose inclusion in my opinion needlessly complicates the implementation of presentation definition and filter evaluation. Evaluation of both is already complex. I don't think it is advised to make it more complex with additional custom logic.

Such custom mapping logic could require that each party, that evaluates presentation definitions¹, would need to maintain or download from somewhere a list of vct values that map to urn:eu.europa.ec.eudi:pid:1. Keeping such a list updated quickly becomes untenable, if PID Providers keep changing their vct values or the version numbers in them.

An alternative vct value mapping solution, which I think the SD-JWT VC specification is suggesting, would be that the evaluating party downloads a chain of extending metadata documents until they finally arrive to the one whose data can be used to determine that https://example.bmi.bund.de/credential/pid/1.0 == urn:eu.europa.ec.eudi:pid:1. The performance of synchronously downloading multiple metadata documents from different places would likely be pretty bad. Caching the documents partially solves the performance problem but greatly increases the complexity even further.²

Either way custom mapping logic of vct values makes it difficult to determine whether the credential's type matches with eu.europa.ec.eudi.pid.1. That check is one of the basic checks the evaluating party does every time. It should be easy and quick.

¹ The evaluating party could be a wallet (in order to respond to the RP's request) or an RP (in order to validate that what they received from the wallet is what they requested).

² Downloading chains of metadata documents also raises the question how the authenticity and authoritativeness of these metadata documents are established. Digest checks at each step of the way?

@c2bo
Copy link

c2bo commented Jun 14, 2024

Either way custom mapping logic of vct values makes it difficult to determine whether the credential's type matches with eu.europa.ec.eudi.pid.1. That check is one of the basic checks the evaluating party does every time. It should be easy and quick.

We will likely have custom attributes in similar credentials - even in the PID if i understand correctly. Imho, it is important to convey that information clearly - what type of PID the presented credential exactly is. Given that mental model, some kind of type hierarchy/derivation seems to be necessary. I do believe it would be dangerous to ignore that aspect and it might also limit the usability of the technology outside of the initial use-cases/scope. That being said, I also agree with you that we need to make sure this is still reasonable easy to implement.

An alternative vct value mapping solution, which I think the SD-JWT VC specification is suggesting, would be that the evaluating party downloads a chain of extending metadata documents until they finally arrive to the one whose data can be used to determine that https://example.bmi.bund.de/credential/pid/1.0 == urn:eu.europa.ec.eudi:pid:1. The performance of synchronously downloading multiple metadata documents from different places would likely be pretty bad. Caching the documents partially solves the performance problem but greatly increases the complexity even further.²

If the vct chain is critical to the functionality of the credential (as it would be in the case of the PID), it could be included in the presentation that is transmitted. The sd-jwt-vc draft proposes to use the unprotected header to optionally transport that kind of information (https://drafts.oauth.net/oauth-sd-jwt-vc/draft-ietf-oauth-sd-jwt-vc.html#name-from-type-metadata-glue-doc). That way for credentials like the PID, the wallet could directly convey that information.

² Downloading chains of metadata documents also raises the question how the authenticity and authoritativeness of these metadata documents are established. Digest checks at each step of the way?

That would be my current understanding of the mechanism and the proposed integrity checks.

@joelposti
Copy link
Contributor

joelposti commented Jun 14, 2024

Either way custom mapping logic of vct values makes it difficult to determine whether the credential's type matches with eu.europa.ec.eudi.pid.1. That check is one of the basic checks the evaluating party does every time. It should be easy and quick.

We will likely have custom attributes in similar credentials - even in the PID if i understand correctly. Imho, it is important to convey that information clearly - what type of PID the presented credential exactly is. Given that mental model, some kind of type hierarchy/derivation seems to be necessary. I do believe it would be dangerous to ignore that aspect and it might also limit the usability of the technology outside of the initial use-cases/scope. That being said, I also agree with you that we need to make sure this is still reasonable easy to implement.

I understand your points and I do agree that there needs to be separate issuer and member state specific metadata documents that describe the custom nuances of each issuer's PID. I am not arguing against the vct claim or the metadata documents. I am trying to say that there should a separate issuer-agnostic credential_type claim in addition to a vct claim. As an evaluating party I want to quickly understand what is the (coarse) type of the presented credential before delving into deeper metadata document-based analysis.

An alternative vct value mapping solution, which I think the SD-JWT VC specification is suggesting, would be that the evaluating party downloads a chain of extending metadata documents until they finally arrive to the one whose data can be used to determine that https://example.bmi.bund.de/credential/pid/1.0 == urn:eu.europa.ec.eudi:pid:1. The performance of synchronously downloading multiple metadata documents from different places would likely be pretty bad. Caching the documents partially solves the performance problem but greatly increases the complexity even further.²

If the vct chain is critical to the functionality of the credential (as it would be in the case of the PID), it could be included in the presentation that is transmitted. The sd-jwt-vc draft proposes to use the unprotected header to optionally transport that kind of information (https://drafts.oauth.net/oauth-sd-jwt-vc/draft-ietf-oauth-sd-jwt-vc.html#name-from-type-metadata-glue-doc). That way for credentials like the PID, the wallet could directly convey that information.

Including the metadata documents in the presentation sounds like a reasonable solution. It would solve the performance and caching issues I mentioned.

@c2bo
Copy link

c2bo commented Jun 14, 2024

I understand your points and I do agree that there needs to be separate issuer and member state specific metadata documents that describe the custom nuances of each issuer's PID. I am not arguing against the vct claim or the metadata documents. I am trying to say that there should a separate issuer-agnostic credential_type claim in addition to a vct claim. As an evaluating party I want to quickly understand what is the (coarse) type of the presented credential before delving into deeper metadata document-based analysis.

Would it be fine to add this also into the unsigned part? Basically something like a credential type "root" that can easily be processed and later on checked for correctness. That way we could initially easily check if the answer is of the expected type (e.g., EU PID) and then properly do the integrity checks + validate if that PID type is really part of the vct chain.

@joelposti
Copy link
Contributor

joelposti commented Jun 14, 2024

I understand your points and I do agree that there needs to be separate issuer and member state specific metadata documents that describe the custom nuances of each issuer's PID. I am not arguing against the vct claim or the metadata documents. I am trying to say that there should a separate issuer-agnostic credential_type claim in addition to a vct claim. As an evaluating party I want to quickly understand what is the (coarse) type of the presented credential before delving into deeper metadata document-based analysis.

Would it be fine to add this also into the unsigned part? Basically something like a credential type "root" that can easily be processed and later on checked for correctness. That way we could initially easily check if the answer is of the expected type (e.g., EU PID) and then properly do the integrity checks + validate if that PID type is really part of the vct chain.

Why in the unsigned part specifically?

I was thinking credential_type would be a claim just like any other in the signed JWS Payload. I think that would make it the simplest to use. It would also be compatible with presentation definition and filter evaluation.

@awoie
Copy link

awoie commented Jun 14, 2024

To @danielfett's point, a similar approach to ISO mdocs could be defined for the vct value in SD-JWT VC.

ISO TS 18013-7 (latest draft) defines a profile of presentation exchanges that describes how to use presentation definition objects with ISO mdocs. Because ISO mdocs are CBOR-based, JSONPath makes no sense. For that reason, a profile definition was needed. For example, the ISO mdoc doctype has to match the id of the input descriptor, only constraints and fields/path are used to match data element values for a data element identifier in a namespace, etc. To use ISO mdocs with presentation exchange, extra rules were defined by the profile in ISO TS 18013-7 (CD).

Example:

{
  "input_descriptors": [
    {
      "id": "org.iso.18013.5.1.mDL",
      "format": {
        "mso_mdoc": {}
      },
      "constraints": {
        "fields": [
          {
            "path": [
              "$['org.iso.18013.5.1']['birth_date']"
            ],
            "intent_to_retain": false
          }
        ]
      }
    }
  ]
}

IMO, another thing I wanted to add is that it is reasonable to assume the wallet itself will always have the full type metadata chain locally cached. I assume the same for relying parties. I don't see a caching issue there.

@joelposti
Copy link
Contributor

IMO, another thing I wanted to add is that it is reasonable to assume the wallet itself will always have the full type metadata chain locally cached. I assume the same for relying parties. I don't see a caching issue there.

It is reasonable to assume that the wallet has the full metadata chain locally cached.

However, it's different for the RP. There are at least 27 PID providers. This could mean that an RP has to cache 27 metadata chains + however many active versions there are of each chain. It's not huge but it's not nothing either.

@c2bo
Copy link

c2bo commented Jun 14, 2024

I understand your points and I do agree that there needs to be separate issuer and member state specific metadata documents that describe the custom nuances of each issuer's PID. I am not arguing against the vct claim or the metadata documents. I am trying to say that there should a separate issuer-agnostic credential_type claim in addition to a vct claim. As an evaluating party I want to quickly understand what is the (coarse) type of the presented credential before delving into deeper metadata document-based analysis.

Would it be fine to add this also into the unsigned part? Basically something like a credential type "root" that can easily be processed and later on checked for correctness. That way we could initially easily check if the answer is of the expected type (e.g., EU PID) and then properly do the integrity checks + validate if that PID type is really part of the vct chain.

Why in the unsigned part specifically?

I was thinking credential_type would be a claim just like any other in the signed JWS Payload. I think that would make it the simplest to use. It would also be compatible with presentation definition and filter evaluation.

That would only work for 1 level of type dependency - if you have 3 or more levels, you wouldn't know what to put in there. Let me try to construct a concrete example - let's assume that we have something like this for credential types:
Worldwide PID -> EU PID -> German PID

A Relying Party could request the EU PID or the worldwide PID and depending on the request, you would expect different values in credential_type to allow for an easier matching. The way I see it, there should be something that makes this a bit easier on the RP, but it should basically be linking the presentation to the request. In that way I would say this is more something that should be dealt with on Request/Response side than directly in the signed parts of the credential.

IMO, another thing I wanted to add is that it is reasonable to assume the wallet itself will always have the full type metadata chain locally cached. I assume the same for relying parties. I don't see a caching issue there.

It is reasonable to assume that the wallet has the full metadata chain locally cached.

However, it's different for the RP. There are at least 27 PID providers. This could mean that an RP has to cache 27 metadata chains + however many active versions there are of each chain. It's not huge but it's not nothing either.

Agreed, especially for cases where we expect a somewhat large amount of different Issuers with different credential types but a common schema, the wallet should IMHO be able to optionally provide this information.

@joelposti
Copy link
Contributor

I understand your points and I do agree that there needs to be separate issuer and member state specific metadata documents that describe the custom nuances of each issuer's PID. I am not arguing against the vct claim or the metadata documents. I am trying to say that there should a separate issuer-agnostic credential_type claim in addition to a vct claim. As an evaluating party I want to quickly understand what is the (coarse) type of the presented credential before delving into deeper metadata document-based analysis.

Would it be fine to add this also into the unsigned part? Basically something like a credential type "root" that can easily be processed and later on checked for correctness. That way we could initially easily check if the answer is of the expected type (e.g., EU PID) and then properly do the integrity checks + validate if that PID type is really part of the vct chain.

Why in the unsigned part specifically?
I was thinking credential_type would be a claim just like any other in the signed JWS Payload. I think that would make it the simplest to use. It would also be compatible with presentation definition and filter evaluation.

That would only work for 1 level of type dependency - if you have 3 or more levels, you wouldn't know what to put in there. Let me try to construct a concrete example - let's assume that we have something like this for credential types: Worldwide PID -> EU PID -> German PID

A Relying Party could request the EU PID or the worldwide PID and depending on the request, you would expect different values in credential_type to allow for an easier matching. The way I see it, there should be something that makes this a bit easier on the RP, but it should basically be linking the presentation to the request. In that way I would say this is more something that should be dealt with on Request/Response side than directly in the signed parts of the credential.

Hmm. I did not know we needed to consider worldwide PIDs. I thought EU PID was the root namespace. Worldwide PID namespace certainly makes credential_type case trickier.

Just as an idea, I have not yet thought this through: credential_type claim could be an array having all the hierarchical identifiers in it:

{
  "credential_type": [
    "<worldwide PID identifier>",
    "eu.europa.ec.eudi.pid.1", // EU PID identifier
    "<German PID identifier>"
  ]
}

An array of hierachical identifiers would make the PID selectable using any of the identifiers in the array. For that we can use JSON Schema's contains keyword. Below is an example presentation definition for requesting given_name attribute from an EU PID of any issuer:

{
  ...
  "input_descriptors": [
    {
      "id": "given_name",
      "constraints": {
        "fields": [
          {
            "path": [
              "$.credential_type"
            ],
            "filter": {
              "type": "array",
              "contains": {
                "const": "eu.europa.ec.eudi.pid.1"
              }
            }
          },
          {
            "path": [
              "$.given_name"
            ],
            "filter": {
              "type": "string"
            }
          }
        ]
      }
    }
  ]
}

@c2bo
Copy link

c2bo commented Jun 17, 2024

Hmm. I did not know we needed to consider worldwide PIDs. I thought EU PID was the root namespace. Worldwide PID namespace certainly makes credential_type case trickier.

I don't think we need to consider worldwide PIDs specifically for the time being, but we should try to design a system (if possible without too much added complexity) that can deal with those kinds of problems. A big part of the adoption of this technology will IMHO be the applicability to other (especially unregulated) use-cases and this kind of type hierarchy will be present in a lot of them.

Providing something like the array of types could definitely work, but I am still not sure that adding this as redundant signed data is the path to go. I would personally prefer to solve this in the query language & credential format specific processing.

@ssanchocanela
Copy link

Dear all.
Following the initial commitment to continue working towards SD-JWT VC DM, we approve this document.
Thanks for the effort.
We will continue providing feedback on minor editorial changes if needed.

@digeorgi
Copy link
Contributor

digeorgi commented Jul 4, 2024

We appreciate your proposal and are in agreement with it in principle. However, we would like to receive feedback from the eIDAS expert group regarding two specific consequences of your proposal:

Increased code complexity:
Your proposal suggests that implementers (such as PID issuers, Wallet Instances, and Relying Parties) will need to use different identifiers, logic, and/or values for the same attributes depending on whether the PID is encoded according to ISO 18013-5 or SD-JWT VC. While this is feasible, it would result in code duplication, leading to increased costs for development, testing, and maintenance.

Namespace and Flexibility Concerns:
According to your proposal, no namespaces will be used for attributes in an SD-JWT VC-compliant PID. Instead, the IANA registry will serve as a de facto namespace. We assume that you intend to use the IANA registry for attributes in other attestation types as well. We question whether this approach is sufficiently flexible and whether it might lead to an undesirable dependency of the EUDI Wallet ecosystem on the IANA registry.

Before we proceed to merge the pull request, we would like to receive feedback from experts of other member states in the expert group. This will ensure a comprehensive evaluation and consensus on the proposed changes.

We look forward to discussing these points further to ensure the robustness of the solution.

@awoie
Copy link

awoie commented Jul 4, 2024

Namespace and Flexibility Concerns: According to your proposal, no namespaces will be used for attributes in an SD-JWT VC-compliant PID. Instead, the IANA registry will serve as a de facto namespace. We assume that you intend to use the IANA registry for attributes in other attestation types as well. We question whether this approach is sufficiently flexible and whether it might lead to an undesirable dependency of the EUDI Wallet ecosystem on the IANA registry.

There is no requirement to use IANA for other attestation types. Attribute names can be defined per attestation type domain by the domain itself, e.g., using collision-resistant identifiers, e.g., example.com:attr1, etc. Alternatively, they can also use a namespace attribute with nested attributes but this is up to the domain to decide, e.g., "example.com": { "attr1" ... }. This is similar to ISO mdocs where domains can decide whether to use nested or flat structures. For PIDs, this is not required since there are already established IANA claims. This should mitigate your namespace/flexibility concern.

@joelposti
Copy link
Contributor

joelposti commented Aug 6, 2024

Continuing the previous discussion about credential_type.

I proposed that in addition to vct claim the SD-JWT VC would have an additional credential_type claim which would be an array of identifiers telling an evaluating party (which can be an RP or a wallet) the type of the credential in an issuer-agnostic way while also conveying hierarchy (eg. EU PID -> German PID). Example of such a claim:

{
  "credential_type": [
    "eu.europa.ec.eudi.pid.1", // EU PID identifier
    "<German PID identifier>"
  ]
}

I understood that @danielfett and @c2bo propose a solution where mapping of vct claim's issuer-specific value is used to achieve the same end result. I am open to both solutions. However, could you provide some practical examples of how this mapping is to be performed in code? Example presentation definitions would also be very welcome.

@spheroid
Copy link

Before we proceed to merge the pull request, we would like to receive feedback from experts of other member states in the expert group. This will ensure a comprehensive evaluation and consensus on the proposed changes.

Any news so far?

@danielfett
Copy link
Author

I fixed the merge conflicts this PR collected since I last touched it.

In the meantime, there has also been progress on the query language in OpenID4VP. Here are the format-specific considerations that describe the vct value matching: https://openid.github.io/OpenID4VP/openid-4-verifiable-presentations-wg-draft.html#name-ietf-sd-jwt-vc


Data element identifiers not listed in Table 3 are used as defined above.

| Data Element Identifier | Claim Name | Note |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to have next to each register claim a reference ?
For instance,

Attribute identifier Claim Name Note Reference
family_name family_name OpenID Connect Core 1.0, Section 5.1
given_name given_name OpenID Connect Core 1.0, Section 5.1
birth_date birthdate OpenID Connect Core 1.0, Section 5.1
age_over_18 age_equal_or_over.18 The 18 property name is a string. PID rulebook
age_over_NN age_equal_or_over.NN The NN property name is a string. PID rulebook
age_in_years age_in_years PID rulebook
age_birth_year age_birth_year PID rulebook
family_name_birth birth_family_name OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
given_name_birth birth_given_name OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
birth_place place_of_birth.locality OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
birth_country place_of_birth.country OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
birth_state place_of_birth.region OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
birth_city place_of_birth.locality OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
resident_address address.formatted OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
resident_country address.country OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
resident_state address.region OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
resident_city address.locality OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
resident_postal_code address.postal_code OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
resident_street address.street_address OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
resident_house_number address.house_number OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
gender gender Data type mismatch - JWT claims use male, female and custom text values.* OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
nationality nationalities Defined as an array, here containing only one entry. OpenID Connect for Identity Assurance Claims Registration 1.0, Section 4
issuance_date iat RFC7519
expiry_date exp RFC7519
issuing_authority issuing_authority PID rulebook
document_number document_number PID rulebook
administrative_number administrative_number PID rulebook
issuing_country issuing_country PID rulebook
issuing_jurisdiction issuing_jurisdiction PID rulebook

"issuing_authority": "DE",
"issuing_country": "DE"
}
```

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be helpful to the reader to have an example of the JWT claim set of the SD-JWT.
Especially to demonstrate the requirement to have selectively disclosable the attributes of claims like age_equal_or_over, address etc.

For instance,

{
    "vct": "https://memberstate.example/credential/pid",
    "vct#integrity": "sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM",
    
    "_sd": [
        "4WIgurnNMUzWOG3sbmmVbhcZScJ2coGwSbmcZrPtumA",
        "XQMnqxzAbDMg-H0XQvS99IrW7Mpl4D2zTBRyfmQgTKY",
        "YtWxyVoyG-gFNACWviWRXHsl1X4RtYSjB22Mspc4Zy0",
        "cACZqNooaasU06tJB4wbqd8a2BWrx2h-nh-QnrE4CGM",
        "fCJZUjADw2ZYmtWHy_AM-rOf9I_YnxUczsYhwpkbpaI",
        "gaxq0QkII8P_QmhGSSaiCPJRuoPIFiEYhp0ZCUP_HAk",
        "qgberZ_GO_M0luD--6ICnKoJoNsGniGMl5bP0mt1KS8",
        "v_ufEM5Ozoub5HdXM6QzPoJefxzn6-9Jp-KYIvp5K78",
        "wkt-dqQ0QJi3Mbw9_1v4PSl5Tyluctzy0BPbPasX4lI"
    ],

    "age_equal_or_over": {
        "_sd": [
            "51F7iAPg_JZLYQOZzmInfVb7Dm4A7ItKjf0DzLaFuRg",
            "8ehSQCxHC90lQQvwPqJmlsE3aBsTLXfSFdABhG1r4oY",
            "XziOO_oHFXgJO6HYVClDMQorsAOMU9P-AUqB4Ab8J6o",
            "kvFx5InkYZJJ72tEwsG27fi3jBGoatsZiVd3vA0b7Ak",
            "lQYi2wOoTefTc4rK-9Cq2mKW2Onwulk-e08f2r7SqDE",
            "vh3-Wnego_RenqKkZ_Alnteo8TVU_9Z-IyfNzaRNoOg"
        ]
    },

    "address": {
        "_sd": [
            "Fc909lFNobvjDRO4JCkkcRS24PtkAxzRarxPVJ4GorY",
            "I-da3bVCY1n6Koam7K2NMjyvTo8plzfvGeytvt7OgeM",
            "NzSDBxiSqMaFdIH92g281e47aBB3c_AXEOmVRucd3zw",
            "dpha7BGCPK1ZQyL9rFiNuEdvvSnkpGYSXfbskeK9T-I",
            "jqepCG5AgZE2zoDo_MjEZbzToSMnwZ90Oo5_3bMuYEE"
        ]
    },

    "place_of_birth": {
        "_sd": [
            "RZbCkkoc5yDveqfCZYxJqJbIKySbvGzfVfY_vwi2Srs",
            "WqbCLRC31iMI67-sdGkdyd5-e7Y-2SdDM-NOrZQR3O0",
            "pEtPxpWa4yYISJR9Po74E6b0Ij_qsVxH3IPv4xzrFNo"
        ]
    },
    
    "cnf": {
        "jwk": {
            "kty": "EC",
            "crv": "P-256",
            "x": "52aDI_ur05n1f_p3jiYGUU82oKZr3m4LsAErM536crQ",
            "y": "ckhZ-KQ5aXNL91R8Eufg1aOf8Z5pZJnIvuCzNGfdnzo"
        }
    }
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be nice, but can we please merge this PR as a starting point, and then do an additional PR to add examples. etc.?

@Sakurann
Copy link

This is starting to cause interoperability issues in international LSP testing. Merging this would really help. Thank you.

| `gender` | `gender` | Note: Data type mismatch - JWT claims use `male`, `female` and custom text values.* |
| `nationality` | `nationalities` | Note: Defined as an array, here containing only one entry.|
| `issuance_date` | `iat` | |
| `expiry_date` | `exp` | |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issuance_date and iat are not necessarily the same thing. The same applies to expiry_date and exp. Compare this to the mdoc PID. The mdoc PID issuance_date and expiry_date attributes are separate from the MSO signed and validUntil timestamps.

issuance_date and expiry_date likely express the administrative validity of the PID while iat and exp express the validity of the JWT which might be considerably shorter than the administrative validity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.