@context
File in a VCWe want to encourage the use of AnonCreds in the W3C VC community, including through the use of multiple signatures (AnonCreds and others) on VCs. The introduction of AnonCreds @context
creates friction in accomplishing that goal. Specifcally, guidance in the JSON-LD specification defines that it is a security risk for a component (such as a verifier) processing a JSON-LD object to dynamically load @context
files. Thus, if a VC has both a NIST and AnonCreds signature, a verifies that receives a VC embedded in a non-AnonCreds VP would refuse to process the VC since it contains an @context
that it has not pre-loaded. If we can eliminate the AnonCreds @context
we can eliminate that friction.
Note that a VP AnonCreds @context
could remain because an AnonCreds VP should not be presented with multiple proofs. It makes no sense to present an AnonCreds VP with embedded VCs that expose all of the data. One would either present an AnonCreds VP and get the privacy-preserving benefits, or present a non-AnonCreds VP and lose those benefits. In this, suggestions are offered on how to eliminate the AnonCreds @context
from the VP as well.
Proposed minimum changes to eliminate the VC AnonCreds @context
array entry:
cryptosuite
of anoncredsvc-2023
.
IssuanceDate
also needs to be changed to validFrom
@context
from a VC issued with an AnonCreds proof.CredentialSchema
and CredentialStatus
items from the VC.proofvalue
of the AnonCreds2023 Data Integrity Proof, possibly such that some of the data is human-readable.For also eliminating the AnonCreds @context
array entry in the VP:
cryptosuite
of anoncredspresvc-2023
.cryptosuite
of anoncredspresvp-2023
.credentialSubject
item for a predicate with a string.
The rest of this document covers the proposed changes and examples of the revised VC and VP.
For a W3C VC, we need to make some updates to the elements of the W3C Format AnonCreds VC to enable eliminating the AnonCreds W3C Context from the VC:
proof
part of the VC.proof.type
DataIntegrityProof and cryptosuite
We should use the proof.type
DataIntegrityProof
, make the cryptosuite
value appropriate for an AnonCreds VC, and move any AnonCreds items in the body of the verifiable credential/presentation to the encoded proofvalue
field in the DataIntegrityProof item. The value of the cryptosuite
is defined in JSON-LD as just a string, and the interpretation of the proofvalue
is whatever we want to use, dependent on the cryptosuite
.
As a result, we can update the revocable VC as follows:
AnonCredsCredential
from the VC type
field.CredentialSchema
item from the VC, moving the CredDef and Schema IDs to the encoded proofvalue
field.CredentialStatus
item from the VC and VP.
The cost of this is human readability, and in particular, not being able to see at least the CredDefId of the VC.
It seems like a good idea to put the revocation information for AnonCreds into the place it belongs in the W3C VC Data Model. Further, the AnonCreds Revocation format could be used a similar (possibly identical) way as the linkable approach used by StatusList2021 but that isn't automatic, and so not an immediately useful approach. Instead, I suggest that we handle revocation in the following way.
If the issuer only supports AnonCreds v1.0 Revocation without change, we should leave off the CredentialStatus
item entirely, moving the data from that section into the proofvalue
item. The unfortunate side-effect is that it looks like the credential is not revokable, when it is. Again, we could use a human-readable element of the proofvalue
to indicate that.
When used with a non-AnonCreds proof
the presentation of the credential would not be revokable.
An issuer could support independent AnonCreds v1.0 Revocation and a StatusList2021 revocation registry, managing the two in parallel โ definitely not ideal. In that case, the issuer would add the CredentialStatus
separately โ outside of the AnonCreds RS issue handling. A side-effect is that it looks like the AnonCreds handling is not revokable, when it is. Again, we could use a human-readable element of the proofvalue
to indicate that.
When used with a non-AnonCreds proof
the presentation of the credential would be revokable via the independent StatusList2022 registry.
An issuer could support an AnonCreds v1.0 Revocation and a dependent StatusList2021 revocation registry. The community would provide a component that implements the StatusList2021 interface (for revocation, only) using data from the AnonCreds revocation registry. When accessed, the component would access the (possibly cached) Revocation Registry state from its AnonCreds location, return the required bit array defined for StatusList2021. In that case, the CredentialStatus
entry would be provided with the URL for a deployed component with the index of the issued credential. It would appear exactly the same as the previous example, but would be based on the same Revocation Registry data used in two different ways.
Note that in a presentation, the revocation status would be shared in different ways depending on the VC proof value being used:
CredentialStatus
section could be present with only the ID of the Revocation Registry included. The verifier would verify the non-revocation proof.This approach could be done as an option in the AnonCreds RS implementation, but for now I suggest we leave it off.
We could eliminate the AnonCreds context entirely with a revision to how we handle the predicate
item in the credentialSubject
. Currently it is defined as follows:
The need for the array (for when there are multiple predicates on a single field) makes another representation tricky. Ideally it would just:
Extending that for arrays is tricky. Perhaps:
Here are the example VC and VP from the AnonCreds repository, revised as recommended here.
VC:
VP: