Open swcurran opened 2 years ago
Questions:
Only change I had to make to get it to work is the added "example" context -- needed by the ACA-Py handling. Any thoughts on that @andrewwhitehead .
This proves that the processing is possible. Is there more we can do to show that having multiple proofs on the same credential would work? I'm guessing this is details in the ACA-Py implementation?
I tried including the "proofs" part of the AnonCreds W3C-format VC as part of the source (to try to get multiple signatures in the Proof section) and ACA-Py complained about the missing proofPurpose
, verificationMethod
, created
fields. Are those actually required? Should they be part of the AnonCreds proof
?
In the ACA-Py back and forth, an @id
is added via a proposal from Alice using her did:key
. Presumably we could "deal with that" in a unified piece of code that created an intentionally doubly signed VC?
Thanks!
That's odd that it would require the example context, I'm pretty sure we don't use any terms from there.
We could add proofPurpose
, verificationMethod
or created
to the proof but I think it would need to be authenticated by the ZKP somehow. verificationMethod would normally reference the issuer's public key, in this case maybe the cred def. Those properties are currently defined by the proof method, so they are not required for all proofs.
The example context was not needed for the "pure" AnonCreds credential. I'm pretty sure that somewhere along the line, ACA-Py is adding id
into the credentialSubject
, and so to get that processed, the example context is needed.
There is some weird things in the ACA-Py implementation of LD-Signatures, I think -- see this ACA-Py Issue I created. I think id
is added in if not present, but added in badly. May be in the demo code or in ACA-Py itself.
If the credential already has a proof (or more) I believe ACA-Py should be stripping that off before generating the new proof and adding it to the original credential.
I doubt we have handling for multiple proofs at the moment, never mind unit tests, but it might not be that hard to add.
@swcurran Some questions/observations I have:
did:key
method is created, any issue with using a public did:sov
wallet?Here's an example I was playing around with, following the current vc-api spec. I also added a totally made-up/incorrect credentialStatus method to provide the revocation registry associated with the cred_def.
The body can be pasted into the "doc" section of an aca-py's admin api json-ld/sign
endpoint and use the verkey from the verificationMethod
for the "verkey" section of the payload. Obviously the issuer did/verification method will have to be changed according to your agent.
{
"credential": {
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1",
"https://andrewwhitehead.github.io/anoncreds-w3c-mapping/schema.json"
],
"type": [
"VerifiableCredential",
"AnonCredsCredential"
],
"id": "did:web:idlab.org",
"issuer": "did:indy:bcovrin:dev:9PGvwPsJMLXrmtiNwTaQTM",
"issuanceDate": "2023-02-23 18:39:30.294333",
"credentialStatus": {
"type": "TailsRevocation2023",
"uri": "did:indy:bcovrin:dev:9PGvwPsJMLXrmtiNwTaQTM:4:9PGvwPsJMLXrmtiNwTaQTM:3:CL:18546:Idlab demo:CL_ACCUM:62bc54d2-e7de-4974-8e8e-1eb2e65fcbb1"
},
"credentialSchema": {
"type": "AnonCredsDefinition",
"id": "did:indy:bcovrin:dev:9PGvwPsJMLXrmtiNwTaQTM:3:CL:18546:Idlab demo",
"schema": "did:indy:bcovrin:dev:9PGvwPsJMLXrmtiNwTaQTM:2:idlab_demo:0.0.3"
},
"credentialSubject": {
"id": "did:web:did.actor:alice",
"givenName": "Alice"
}
},
"options": {
"verificationMethod": "did:indy:bcovrin:dev:9PGvwPsJMLXrmtiNwTaQTM#5a36pxvK2KDpaFVXD8bwRxhcjPRdZXratDrTKxnUDAhc",
"proofPurpose": "assertionMethod",
"type": "Ed25519Signature2018"
}
}
The verifier will then be able to resolve the did, schema, cred_def and rev_reg.
Here is the VC obtained, which you should be able to verify for yourself.
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://www.w3.org/2018/credentials/examples/v1",
"https://andrewwhitehead.github.io/anoncreds-w3c-mapping/schema.json"
],
"type": [
"VerifiableCredential",
"AnonCredsCredential"
],
"id": "did:web:idlab.org",
"issuer": "did:indy:bcovrin:dev:9PGvwPsJMLXrmtiNwTaQTM",
"issuanceDate": "2023-02-23 18:51:21.741980",
"credentialStatus": {
"type": "TailsRevocation2023",
"uri": "did:indy:bcovrin:dev:9PGvwPsJMLXrmtiNwTaQTM:4:9PGvwPsJMLXrmtiNwTaQTM:3:CL:18546:Idlab demo:CL_ACCUM:62bc54d2-e7de-4974-8e8e-1eb2e65fcbb1"
},
"credentialSchema": {
"type": "AnonCredsDefinition",
"id": "did:indy:bcovrin:dev:9PGvwPsJMLXrmtiNwTaQTM:3:CL:18546:Idlab demo",
"schema": "did:indy:bcovrin:dev:9PGvwPsJMLXrmtiNwTaQTM:2:idlab_demo:0.0.3"
},
"credentialSubject": {
"id": "did:web:did.actor:alice",
"givenName": "Alice"
},
"proof": {
"verificationMethod": "did:indy:bcovrin:dev:9PGvwPsJMLXrmtiNwTaQTM#5a36pxvK2KDpaFVXD8bwRxhcjPRdZXratDrTKxnUDAhc",
"proofPurpose": "assertionMethod",
"type": "Ed25519Signature2018",
"created": "2023-02-23T23:55:41Z",
"jws": "eyJhbGciOiAiRWREU0EiLCAiYjY0IjogZmFsc2UsICJjcml0IjogWyJiNjQiXX0..Kyky_ps9h8QvQa8C4cqpN_FWiMp-jppnmcg4QmOx1z73BfKBI6ud6Kiu7QlnyEOkCrxd745sNRzjgRC3eXqLCA"
}
}
You can verify this credential on the admin json-ld/verify
endpoint using the verkey
from the verificationMethod
and it will return true.
Furthermore the credentialSubjet.id could be set to a did:key from the holder an enable the nonTransferable property for some sort of holder-binding.
Responses to your questions/comments:
The ID of the schema/cred def implies the AnonCreds Method to use. Embedded within the object is the controller ID that created the AnonCreds object (Schema or CredDef) and that ID might also be included in the ID of the object itself — as does for any Hyperledger Indy AnonCreds method (using Legacy Indy or did:indy
).
For the LD Signature, a published key, such as one on a Hyperledger Indy ledger (a did:sov or a did:indy) definitely could be used.
Agreed.
On the examples — very cool. I had to reread your comment about the CredentialStatus :-) . Interesting to see if the data for the AnonCreds revocation proof could go into that part of the Credential.
ACA-Py Process:
"https://www.w3.org/2018/credentials/examples/v1",
to the@context
array in the payloadPost /credentials/W3C
endpoint with an empty payload{}
to get a list of the credentials Alice has.Here is a current example of working
/issue-credential-v2/send
:Resulting signed Credential, retrieved using the Post /credentials/w3c admin endpoint: