hyperledger / anoncreds-spec

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

Define `AnonCredsCredentialDefinition` verification method #195

Open TimoGlastra opened 7 months ago

TimoGlastra commented 7 months ago

In the AnonCreds RS implementation for W3C AnonCreds credentials we've opted to include the credential definition id as the verificationMethod property in the proof.

I think this makes sense, as the cred def contains the public key material needed to verify an AnonCreds credential. However the DI spec assumes that a verificationMethod included in the proof links to a controller document with an underlying verificationMethod.

For that purpose I think it would be good to also include in this spec a definition for an AnonCreds credential definition verification method. Implementers of this spec could then integrate this into their document loaders to resolve verificationMethods based on AnonCreds credential definitions.

{
  "id": "did:indy:sovrin:5nDyJVP1NrcPAttP3xwMB9/anoncreds/v0/CLAIM_DEF/56495/npdb",
  "type": "AnonCredsCredentialDefinition",
  "controller": "did:indy:sovrin:5nDyJVP1NrcPAttP3xwMB9", // same as issuerId from the anoncreds objects
}

In addition, (but this is for later) I think we may want to move the Data Integrity definition for AnonCreds out into a separate spec, e.g. based on https://www.w3.org/TR/vc-di-eddsa/. I think this makes it look even more like AnonCreds is just another proof type you can use now

TimoGlastra commented 7 months ago

If it needs to be returned as a controller document it could be returned as something like:

{
  "id": "did:indy:sovrin:5nDyJVP1NrcPAttP3xwMB9",
   "verificationMethod": [
        {
          "id": "did:indy:sovrin:5nDyJVP1NrcPAttP3xwMB9/anoncreds/v0/CLAIM_DEF/56495/npdb",
          "type": "AnonCredsCredentialDefinition",
          "controller": "did:indy:sovrin:5nDyJVP1NrcPAttP3xwMB9", // same as issuerId from the anoncreds objects,
           "<some-property>": "<encodedOrJsonOfCredDefId>"
        }
   ],
   "assertionMethod": ["did:indy:sovrin:5nDyJVP1NrcPAttP3xwMB9/anoncreds/v0/CLAIM_DEF/56495/npdb"]
}

It won't be returned in the normal did document for indy, but for e.g. cheqd you can see all the resources that have been created for a did, and thus you would easily be able to add it to the resulting did document as well.

One issue I see though is that the DI spec limits the types of verification methods to JsonWebKey and MultiKey

TimoGlastra commented 7 months ago

@msporny does it make sense to define a verificationMethod for the new AnonCreds data integrity suite?

Is there a way we can be compliant without leveraging JsonWebKey or MultiKey?

msporny commented 7 months ago

@TimoGlastra wrote:

One issue I see though is that the DI spec limits the types of verification methods to JsonWebKey and MultiKey

The intention of the DI spec is NOT to limit the types of verification methods. The ones defined in the DI spec are just the ones that we've been able to get the VCWG to come to consensus on (and even those two were a long, drawn out scuffle).

You can define your own key types and still be conformant with DI. If you think there is something in the DI spec that suggests that you cannot do that, we need to fix that in the DI spec. Maybe what we should do is just put an advisement in the specification noting that DI doesn't restrict other key types from existing. Please raise an issue on the DI spec if you'd like us to do this, writing that PR would be fairly easy.

@msporny does it make sense to define a verificationMethod for the new AnonCreds data integrity suite?

If the AnonCreds stuff differs enough from Multikey and JsonWebKey (and based on the commentary above, it does), then yes, that would make sense to define that in a spec like vc-di-anoncreds that is modeled after vc-di-eddsa.

Is there a way we can be compliant without leveraging JsonWebKey or MultiKey?

Yes, just define your own key type. I will note that there will be some VCWG members that are going to be super cranky about this, but the response to them is: You should've been more inclusive about key types, and when you're not inclusive about key types, you see new key type definitions such as this.

An alternate would be to define it as a Multikey and pack all the information above in <some-property> in a Multikey with a header that specifies that they key is an AnonCredsCredentialDefinition verification method. That would bring you more inline w/ the DI spec and has some benefits (such as not having to define a new keytype but still giving you all of the expressibility you need to express the key type).

Did that answer your question, @TimoGlastra?

TimoGlastra commented 7 months ago

The intention of the DI spec is NOT to limit the types of verification methods. The ones defined in the DI spec are just the ones that we've been able to get the VCWG to come to consensus on (and even those two were a long, drawn out scuffle).

Okay that is good to hear, thanks. I was put off by the following sentence:

To increase the likelihood of interoperable implementations, this specification limits the number of formats for expressing verification material in a controller document. The fewer formats that implementers have to implement, the more likely it will be that they will support all of them. This approach attempts to strike a delicate balance between easing implementation and providing support for formats that have historically had broad deployment.

But after reading it again, it doesn't say you can't use other types, just that these are not described in the DI proofs spec.

If the AnonCreds stuff differs enough from Multikey and JsonWebKey (and based on the commentary above, it does), then yes, that would make sense to define that in a spec like vc-di-anoncreds that is modeled after vc-di-eddsa.

Yes it differs quite drastically from other types, and even if we could embed it into a MultiKey I don't think that we should do it for this instance. There's quite some data in a cred def, so labeling it as a key is not very clear I think. Benefit of using MultiKey is that it would be easier to use AnonCreds credentials with different did methods and controller documents without those having to support keys with type AnonCredsCredentialDefinition

Thanks @msporny for the input!

msporny commented 7 months ago

I was put off by the following sentence

Yeah, some folks in the WG insisted on that language.

There's this mantra in global standards that you should try to force all ecosystems into ONE solution (which becomes THE standard). While it's an ideal goal, the world is messier than that, and there are many key formats and there will continue to be many key formats (because, at times the use cases requires it, and at other times -- for whatever reason -- the community creating a solution has picked a different key format).

Data Integrity attempts to recognize this by allowing other key types to slot into the ecosystem w/o creating some huge fight over "right vs. wrong". As long as there isn't some horrible vulnerability, different encodings (especially if they have different requirements) are fine. Multiple key types exist, that's a reality, so we should build our systems to recognize that reality instead of trying to shove a single key format down everyone's throats.

In any case, the path you're picking to go forward is fine as far as I'm concerned. Don't be surprised if other folks from IETF insist that you use JWK, and if you don't do that, you're doing the wrong thing. :)