# Aries RFC XXXX: W3C Verifiable Credential Data Integrity Attachment format for requesting and issuing credentials
- Authors: Timo Glastra (Animo Solutions)
- Status: [PROPOSED](/README.md#proposed)
- Since: 2023-12-18
- Status Note:
- Supersedes: [Aries RFC 0593: JSON-LD Credential Attachment](https://github.com/hyperledger/aries-rfcs/blob/main/features/0593-json-ld-cred-attach/README.md)
- Start Date: 2023-12-18
- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [credentials](/tags.md#credentials), [test-anomaly](/tags.md#test-anomaly)
## Summary
This RFC registers an attachment format for use in the [issue-credential V2](../0453-issue-credential-v2/README.md) protocol based on W3C Verifiable Credentials with [Data Integrity Proofs](https://www.w3.org/TR/vc-data-integrity/) from the [VC Data Model](https://www.w3.org/TR/vc-data-model/#linked-data-proofs).
## Motivation
The Issue Credential protocol needs an attachment format to be able to exchange W3C verifiable credentials. It is desirable to make use of specifications developed in an open standards body, such as the [Credential Manifest](https://identity.foundation/credential-manifest/) for which the attachment format is described in [RFC 0511: Credential-Manifest Attachment format](../0511-dif-cred-manifest-attach/README.md). However, the _Credential Manifest_ is not finished and ready yet, and therefore there is a need to bridge the gap between standards.
## Tutorial
Complete examples of messages are provided in the [reference section](#reference).
## Reference
## Credential Offer Attachment Format
Format identifier: `didcomm/w3c-di-vc-offer@v0.1`
```json
{
// Q: do we want to indicate which suites will be included in the credential?
// Q: If suites are going to use DataIntegrityProof, it still doesn't indicate which
// crypto suite will be used
"crypto_suites_supported": ["Ed25519Signature2018", "AnonCredsProof2023"],
// Q: what is the default?
// Q: what should the `credential` use?
// Q: should we not support multiple versions?
// Q: can a VC be compliant with both v1.1 and v2.0 at the same time?
"data_model_versions_supported": ["1.1", "2.0"],
"binding_methods": {
"anoncreds_link_secret": {
"nonce": "1234",
"cred_def_id": "did:web:example.com/123",
"key_correctness_proof": "<key_correctness_proof>",
},
"didcomm_signed_attachment": {
"algs_supported": ["EdDSA"],
"binding_methods_supported": ["did:key", "did:web"],
"nonce": "1234",
}
},
// contents of VC without `proof`. May omit fields such as credentialSubject.id if they
// are only known at time of issuance. Can use the value "<placeholder>" (TBD) to indicate
// the value will be defined at issuance, but not currently.
"credential": {
// contents of VC
},
"options": {
"credentialStatus": {
"type": "AnonCredsCredentialStatusList2023"
}
}
}
```
### Credential Request Attachment Format
Format identifier: `didcomm/w3c-di-vc-request@v0.1`
This format is used to request a verifiable credential. The JSON structure might look like this:
```json
{
"binding_proof": {
"anoncreds_link_secret": {
"entropy": "<random-entropy>",
"blinded_ms": {},
"blinded_ms_corectness_proof": {},
"nonce": "<random-nonce>"
},
// should we inline the signed attachment?
"didcomm_signed_attachment": {
"attachment_id": "<@id of the attachment>"
}
}
}
```
- `binding_proof` - Object containing one or more binding proof methods to bind the credential to a holder. The keys of the object must match with the keys of the `binding_methods` from the offer. It is allowed if a binding proof is not provided for all binding methods, and in this case the credential can be issued with no or a subset of the binding methods. (TODO: problem report if binding is required on the issuer side.)
### Credential Attachment Format
Format identifier: `didcomm/w3c-di-vc@v0.1`
This format is used to transmit a verifiable credential. The JSON structure might look like this:
```json
{
"credential": {
// vc with proof object or array
}
}
```
- `credential` - The signed credential. Must be a valid verifiable credential object with one or more proofs.
A complete [`issue-credential` message from the Issue Credential protocol 2.0](../0453-issue-credential-v2/README.md#issue-credential) might look like this:
```json
{
"@id": "284d3996-ba85-45d9-964b-9fd5805517b6",
"@type": "https://didcomm.org/issue-credential/2.0/issue-credential",
"comment": "<some comment>",
"formats": [
{
"attach_id": "5b38af88-d36f-4f77-bb7a-2f04ab806eb8",
"format": "didcomm/w3c-di-vc@v0.1"
}
],
"credentials~attach": [
{
"@id": "5b38af88-d36f-4f77-bb7a-2f04ab806eb8",
"mime-type": "application/ld+json",
"data": {
"base64": "ewogICAgICAgICAgIkBjb250ZXogWwogICAgICAg...(clipped)...RNVmR0SXFXZhWXgySkJBIgAgfQogICAgICAgIH0="
}
}
]
}
```
### Binding Methods
The attachment format supports different methods to bind the credential to the receiver of the credential. In the offer message the issuer can indicate which binding methods are supported in the `binding_methods_supported` array.
This section defines a set of binding methods supported by this attachment format, but other binding methods may be used. Based on the binding method, the request needs to include a `binding_proof` object where the `method` defines the specific binding method that is chosen.
#### AnonCreds Link Secret
Identifier: `anoncreds_link_secret`
This binding method is intended to be used in combination with a credential containing an AnonCreds proof. The structure of the `binding_proof` in the request MUST match the structure of the [Credential Request](https://hyperledger.github.io/anoncreds-spec/#credential-request) as defined in the AnonCreds specification, with the addition of the `method` key.
```json
{
"anoncreds_link_secret": {
"entropy": "<random-entropy>",
"blinded_ms": {},
"blinded_ms_corectness_proof": {},
"nonce": "<random-nonce>"
}
}
```
#### DIDComm Signed Attachment
Identifier: `didcomm_signed_attachment`
This binding method leverages [DIDComm signed attachments](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0017-attachments/README.md#signing-attachments) to bind a credential to a specific key and/or identifier.
The attachment MUST be signed by including a signature in the `jws` field of the attachment. The data MUST be a JSON document encoded in `base64` field. The structure of the signed attachment is described below.
```json
{
"didcomm_signed_attachment": {
"attachment_id": "<@id of the attachment>"
}
}
```
- `attachment_id` - The id of the appended attachment included in the offer message that contains the signed attachment.
##### Signed Attachment Content
**JWS Payload**
```json
{
"nonce": "<request_nonce>",
"aud": "did:web:example.com"
}
```
- `nonce` - The `nonce` from the `didcomm_signed_attachment` object within `binding_methods` from the credential offer
- `aud` - Intended audience of the signed attachment. MUST be the same as the issuer identifier in the `credential` from the offer
**Protected Header**
- `alg`: REQUIRED. A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. MUST NOT be none or an identifier for a symmetric algorithm (MAC).
- `kid`: REQUIRED. JOSE Header containing the key ID. If the Credential shall be bound to a DID, the kid refers to a DID URL which identifies a particular key in the DID Document that the Credential shall be bound to.
A signed attachment appended to a request message might look like this:
```json
{
"@id": "284d3996-ba85-45d9-964b-9fd5805517b6",
"@type": "https://didcomm.org/issue-credential/2.0/request-credential",
"comment": "<some comment>",
"formats": [
{
"attach_id": "5b38af88-d36f-4f77-bb7a-2f04ab806eb8",
"format": "didcomm/w3c-di-vc@v0.1"
}
],
"~attach": [{
"@id": "123",
"mime-type": "application/json",
"data": {
"base64": "<base64-encoded-json-attachment-content>",
"jws": {
"protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)",
"signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)"
}
}
}]
"credentials~attach": [
{
"@id": "5b38af88-d36f-4f77-bb7a-2f04ab806eb8",
"mime-type": "application/ld+json",
"data": {
"base64": "ewogICAgICAgICAgIkBjb250ZXogWwogICAgICAg...(clipped)...RNVmR0SXFXZhWXgySkJBIgAgfQogICAgICAgIH0="
}
}
]
}
```
## Drawbacks
While it has a similar setup and structure compared to OpenID for Verifaible Credential Issuance, this attachment format only focuses on issuance of W3C Verifiable Credentials. Therefore another (but probably quite similar) attachment format needs to be defined to support issuance of non-W3C VCs
## Rationale and alternatives
[RFC 0593: JSON-LD Credential Attachment](https://github.com/hyperledger/aries-rfcs/blob/main/features/0593-json-ld-cred-attach/README.md), [W3C VC API](https://w3c-ccg.github.io/vc-api/) allows issuance of credentials using only linked data signatures, while [RFC 0592: Indy Attachment](https://github.com/hyperledger/aries-rfcs/blob/main/features/0592-indy-attachments/README.md) supports issuance of AnonCreds credentials. This attachment format aims to support issuance of both previous attachment formats (while for AnonCreds it now being in the W3C model), as well as supporting additional features such as issuance W3C JWT VCs, credentials with multiple proofs, and cryptographic binding of the credential to the holder.
## Prior art
The attachment format in this RFC is heavily inspired by [RFC 0593: JSON-LD Credential Attachment](https://github.com/hyperledger/aries-rfcs/blob/main/features/0593-json-ld-cred-attach/README.md), [W3C VC API](https://w3c-ccg.github.io/vc-api/) and [OpenID for Verifiable Credential Issuance](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html).
## Unresolved questions
- Should we support multi-credential offers?
- It may be desirable to have multi-format (so jwt or ldp_vc), or should that also be handled by multiple attachment formats?
- Should we support `jwk` as well, in addition to `kid` in the header? Would allow a credential to be bound to a JWK rather than a did
- With VCDM 2.0 being mostly ready for usage, it might be worth to support both v1.x and v2.x versions of the VCDM in this attachment format. Version support could be indicated in the proposal/offer/request messages using a `data_model_version` property. An implementer is not required to support all versions, but we would define both `v1.1` and `v2.0` as currently recognized data model versions.
- Do we need to support multiple binding methods for a single credential?
- Relevant in case of W3C VC with AnonCreds + Ed22519
- Wondering whether AnonCreds should be a separate format? Ideally not, but in that case we need to define some properties that can be included for specific proof.type values.
- Is it required for the receiver to know upfront which proof type(s) the issuer will use to secure the integrity of the VC?