hyperledger / anoncreds-spec

The specification for AnonCreds verifiable credential exchange.
https://hyperledger.github.io/anoncreds-spec/
Apache License 2.0
47 stars 24 forks source link

Reconsider usage of `AnonCredsPredicate` in an AnonCreds VP #194

Open TimoGlastra opened 9 months ago

TimoGlastra commented 9 months ago

I've been re-reading the DIF PE specification to create test vectors for AnonCreds W3C credentials and exchange messages.

I now noticed in the spec the following sections:

image

This requires that the returned value is a boolean, only if a predicate is used. I think this is based on the assumption that each attribute will only have one predicate query associated with it (so not age > 10 and age < 50 as then you won't be able to use a boolean anymore).

Based on this I think it may be good for now to limit anoncreds w3c presentations to only a single predicate per attribute (I've never seen different), and use the approach as described in DIF PE.

Then we will be aligned with the spec, and this would actually make it a lot easier for us to get this working with e.g. the PEX implementation we use in JS which is not created by us (https://github.com/sphereon-Opensource/pex).

cc @swcurran @Artemkaaas @gvelez17 @2mau

swcurran commented 9 months ago

Interesting. The “”age”: true” approach is what I thought we would do.

I think it would not be particularly limiting to allow only one predicate per attribute of a given name. In theory, multiple predicates could be referencing like-named attributes in different source credentials (which would be OK), but that’s really an edge case.

TimoGlastra commented 9 months ago

@Artemkaaas During the WG call yesterday we landed on using true as the result of the predicate. Do you think you could update the code to not use AnonCredsPredicate but rather use a boolean value?

Artemkaaas commented 8 months ago

Yes. I can update to use boolean value instead object. I believe we even can avoid making mentioned above limitations regarding the predicates' usage (single predicate per attribute and unique name across all predicates) by reintroducing explicit mapping put under encoded proof value.

          "mapping": {
            "revealedAttributes": {
              ....
            },
            "requestedPredicates": {
              "0_age": {
                "attr_name": "age",
                "p_type": ">=",
                "value": 18
              },
              "1_age": {
                "attr_name": "age",
                "p_type": "<=",
                "value": 30
              }
            }
          },
TimoGlastra commented 8 months ago

Hmm now that you say this, I think maybe multiple predicates should even be possible without the mapping right?

I can create the following DIF PD:

{
  "id": "5591656f-5b5d-40f8-ab5c-9041c8e3a6a0",
  "name": "Age Verification",
  "purpose": "We need to verify your age before entering a bar",
  "input_descriptors": [
    {
      "id": "age-verification",
      "name": "A specific type of VC + Issuer",
      "purpose": "We want a VC of this type generated by this issuer",
      "schema": [
        {
          "uri": "https://www.w3.org/2018/credentials/v1"
        }
      ],
      "constraints": {
        "limit_disclosure": "required",
        "fields": [
          {
            "path": ["$.issuer"],
            "filter": {
              "type": "string",
              "const": "did:key:z6MkwXG2WjeQnNxSoynSGYU8V9j3QzP3JSqhdmkHc6SaVWoT"
            }
          },
          {
            "path": ["$.credentialSubject.name"]
          },
          {
            "path": ["$.credentialSubject.height"]
          },
          {
            "path": ["$.credentialSubject.age"],
            "predicate": "preferred",
            "filter": {
              "type": "number",
              "minimum": 18,
             "maximum": 21
            }
          }
        ]
      }
    }
  ],
  "format": {
    "di_vc": {
      "proof_type": ["DataIntegrityProof"],
      "cryptosuite": ["anoncredspresvc-2023", "eddsa-rdfc-2022"]
    }
  }
}

This will translate to two different predicates:

I think the only thing that is important here is that we need a consistent way to map from a PD to an AnonCreds proof request (mainly the group names are important here I think)

Artemkaaas commented 8 months ago

For doing credential subProof verification, we have to pass predicate type and value as well. When we change a credential predicate representation to have a bool as a value, we need to find the corresponding entry in the AnonCreds proof request. In case of multiple predicates with the same name, we can take a wrong one if there is no restriction.