decentralized-identity / presentation-exchange

Specification that codifies an inter-related pair of data formats for defining proof presentations (Presentation Definition) and subsequent proof submissions (Presentation Submission)
https://identity.foundation/presentation-exchange
Apache License 2.0
85 stars 37 forks source link

constraints #350

Open tlodderstedt opened 2 years ago

tlodderstedt commented 2 years ago

Hi,

we come across some issues with the way the constraints element. In my opinion, it mixes expressions for filtering Credentials with a definition of the claims a verifier wants to get selectively disclosed.

Let's take a look at this example:

{
   "id":"example_vc_sd",
   "input_descriptors":[
      {
         "id":"id_credential",
         "format":{
            "ldp_vc":{
               "proof_type":[
                  "Ed25519Signature2018"
               ]
            }
         },
         "constraints":{
            "limit_disclosure":"required",
            "fields":[
               {
                  "path":[
                     "$.type"
                  ],
                  "filter":{
                     "type":"array",
                     "contains":{
                        "const":"IDCredential"
                     }
                  }
               },
               {
                  "path":[
                     "$.credentialSubject.first_name"
                  ]
               },
               {
                  "path":[
                     "$.credentialSubject.last_name"
                  ]
               }
            ]
         }
      }
   ]
}

The "limit_disclosure" turns on selective disclosure of claims from the credential. But what elements shall be selectively disclosed?

There are three fields in this constraint. The first "field" element has a filter that selects credentials of type "IDCredential". The second and third field just identify two end-user claims.

What is the meaning of the overall constraint element? Is it meant to selectively disclose "type", "first_name", and "last_name"?

I guess no. It is meant to selectively disclose "first_name", and "last_name" along with the rest of the credential metadata.

I think the text needs clarification. I also think it would be better to use the constraints object for only constraining the credential to be selected and control selective disclosure with a different element.

csuwildcat commented 2 years ago

@tlodderstedt maybe this needs to be a per-field designation?

nklomp commented 2 years ago

Or move limit_disclosure to an object and allow it to express paths

tlodderstedt commented 2 years ago

I think constraints related to picking a credential and what is disclosed from this credential are different aspects. I therefore feel those aspects should be represented in different elements of the input descriptor.. Moving limit_disclosure outside of constraints and making it an object containing paths to the elements to be disclosed sounds reasonable to me.

bumblefudge commented 2 years ago

Hey @tlodderstedt -- we discussed this on today's call and realized that the LD-Frame object (section 7.5 of today's spec) could be used to specify more explicitly for selectively-disclosed properties (derived from LD-based (and semantically-anchored) VCs) rather than filtering purely by static paths (in, e.g. JWT-VCs or JWTs). A PR for disambiguated spec-text or additional examples would be welcome!

tlodderstedt commented 2 years ago

I'm not sure what direction you want to go. Do you suggest to remove the "limit_disclosure" element underneath "constraints" and use "frame" instead?

tlodderstedt commented 2 years ago

I took a look at the frame definition. I don't think this is a suitable solution as it does not remove the ambiguity of the current construct and it is framed to LDP. I can do a PR but this would entail a new syntax to clearly distinguish between filtering and disclosing.

Note: whatever the solution will be, it is certainly normative as it requires a different syntax.

tlodderstedt commented 1 year ago

Here is my proposal: Introduce a new contain element selective_disclosure and use it to list the fields that shall be selectively disclosed and use constraints for selecting the credentials, only.

{
   "id": "example_vc_sd",
   "input_descriptors": [
      {
         "id": "id_credential",
         "format": {
            "ldp_vc": {
               "proof_type": [
                  "Ed25519Signature2018"
               ]
            }
         },
         "constraints": {
            "fields": [
               {
                  "path": [
                     "$.type"
                  ],
                  "filter": {
                     "type": "array",
                     "contains": {
                        "const": "IDCredential"
                     }
                  }
               }
            ]
         },
         "selectiv_disclosure": {
            "fields": [
               {
                  "path": [
                     "$.credentialSubject.first_name"
                  ]
               },
               {
                  "path": [
                     "$.credentialSubject.last_name"
                  ]
               }
            ]
         }
      }
   }
]
}
bumblefudge commented 1 year ago

Came back to this today on today's call, and had a clarifying question: does the Verifier really trust the Wallet/Holder to do this selection? Is it somehow enforced on the holder/wallet/client side?

Would this example be equivalent/better?

{
   "id": "example_vc_sd",
   "input_descriptors": [
      {
         "id": "id_credential",
         "format": {
            "ldp_vc": {
               "proof_type": [
                  "Ed25519Signature2018"
               ]
            }
         },
         "constraints": {
            "fields": [
               {
                  "path": [
                     "$.type"
                  ],
                  "filter": {
                     "type": "array",
                     "contains": {
                        "const": "IDCredential"
                     }
                  }
               }
            ]
         },
         "selectiv_disclosure": {
            "fields": [
               {
                  "path": [
                     "$.type"
                  ]
               },
               {
                  "path": [
                     "$.credentialSubject.first_name"
                  ]
               },
               {
                  "path": [
                     "$.credentialSubject.last_name"
                  ]
               }
            ]
         }
      }
   }
]
}

Or is the proposed container specific to SD_JWT or SD_JWT + AnonCreds?

We discussed a couple different interpretations on the call today and feel like we're filling in gaps dangerously in the intent of this proposal!