# HL Aries Interop (Issue Credentials V2)
## Intro
This protocol can either start with the Issuer or the Holder and can involve multiple credential negotiation steps.
NOTE: The credential negotation can either start with an offer-credential message or a propose-credential message and can include multiple roundtrips. For simplicity reasons, we don't need to support this for now. It is also unclear which use cases would really require this.
Relevant HL Aries RFCs:
- [0453 - Issue Credential Protocol 2.0](https://github.com/hyperledger/aries-rfcs/tree/master/features/0453-issue-credential-v2)
- [0511 - Credential-Manifest Attachment format for requesting and presenting credentials](https://github.com/hyperledger/aries-rfcs/tree/master/features/0511-dif-cred-manifest-attach)
Other relvant specs:
- [DIF Credential Manifest Specification](https://identity.foundation/credential-manifest/)
- [DIF Presentation Exchange Specification](https://identity.foundation/presentation-exchange/)
### Flows
The flows involve the following message types:
- offer-credential
- propose-credential
- request-credential
- issue-credential
- report-problem
- ack
The flow can start with the following message types:
- offer-credential
- propose-credential
- request-credential
`offer-credential` allows the Issuer to start the interaction. It contains the DIF Credential Manifest (DIF CM) which tells the Holder what credential can be obtained. It also includes UX suggestions such as logo, etc. from the Issuer. Optionally, it tells the Holder what input data is required to obtain the credential. If input data is required, the DIF CM will include a `presentation_definition` property that is a DIF Presentation Definition (DIF PD) according to the DIF Presentation Exchange (DIF PE) specification. Therefore, two important cases need to be distinguished:
- DIF Credential Manifest omits `presentation_definition`
- DIF Credential Manifest includes `presentation_definition`
`propose-credential` allows the Holder to start the interaction by proposing the credential the Holder wants to receive. The message includes a DIF CM that was obtained out-of-band typically without the Presentation Request. The Issuer would then respond with a `offer-credential` message that may then include a DIF CM with a `presentation_definition` containing `challenge` and `domain` parameters.
NOTE: IMO, for security reasons and to specifically protect against replay attacks, it is not recommended to statically host a DIF CM with `challenge` and `domain` parameters. These should be obtained through a `offer-credential` message.
`request-credential` allows the Holder to tell the Issuer he wants to receive the offered credential. The message includes a DIF CM or a DIF Presentation Submission (DIF PS). A DIF PS is included if input data was requested.
NOTE: the flow may start with a `request-credential` message that includes a Presentation Submission containing previously obtained `challenge` and `domain` parameters. This is out-of-scope for now.
`issue-credential` allows to send the actual credential from the Issuer to the Holder.
`report-problem` allows either of the involved parties to indicate an error.
`ack` indicates that the credential was received by the Holder.
The state machine is quite comprehensive and we do not need to support all transitions. In the next sections the recommended flows are described.
#### Issuer starts Flow
It is expected that the DID of the Holder was exchanged OOB. We should not use the DID of the recipient in the DIDComm-Messaging v2 envelope and we should not automatically assume that the Issuer picks any DID from a VC from the `presentation_submission`.
If the DID should be exchanged in the `request-credential` message as part of a `presentation_submission`, the `offer-credential` should ask for the DID of the Holder.
:::spoiler Example `offer-credential` asking for a DID
```json=
{
"id": "dfedaad3-bd7a-4c33-8337-fa94a547c0e2",
"type": "https://didcomm.org/issue-credential/2.0/offer-credential",
"body": {
"comment": "<some comment>",
"formats" : [{
// corresponds with offers-attach @id
"attach_id" : "76cd0d94-8eb6-4ef3-a094-af45d81e9528",
"format" : "dif/credential-manifest@v1.0"
}],
"offers~attach": [{
// corresponds with formats attach_id
"@id": "76cd0d94-8eb6-4ef3-a094-af45d81e9528",
"mime-type": "application/json",
"data": {
"json": {
// challenge/domain needed for generating the VP
"challenge": "1f44d55f-f161-4938-a659-f8026467f126",
"domain": "us.gov/DriverLicense",
// The following is the minimal form of a DIF CM
"credential_manifest": {
"issuer": "did:example:123",
"credential": {
"name": "Washington State Class A Commercial Driver License",
"schema": "ipfs:QmPXME1oRtoT627YKaDPDQ3PwA8tdP9rWuAAweLzqSwAWT"
},
// Minimal definition that asks for a DID
"presentation_definition": {
"input_descriptors": [
{
"id": "did_input",
"schema": {
"uri": [
"https://schema-with-did.com/did-schema.json"
],
"name": "Any Schema That Has a DID",
"purpose": "We need your DID."
},
"constraints": {
"limit_disclosure": true,
"subject_is_issuer": "preferred",
"fields": [
{
"path": [
"$.credentialSubject.id"
],
"purpose": "We need your DID from a VC",
"filter": {
"type": "string",
"pattern": "did:*:*"
}
}
]
}
}
]
}
}
}
}
}]
}
}
```
:::
##### Flow not requiring input data from Holder
The following flow contains a DIF CM that does not require any input data from the Holder.
```sequence
Issuer -> Holder: 1.1 | offer-credential (with DIF CM)
Holder --> Issuer: 202 Accepted (non-normative)
Holder -> Issuer: 2.1 | request-credential (without DIF CM)
Issuer --> Holder: 202 Accepted (non-normative)
Issuer -> Holder: 3.1 | issue-credential (W3C VC)
Holder --> Issuer: 202 Accepted (non-normative)
Holder -> Issuer: 4.1 | ack
Issuer --> Holder: 202 Accepted (non-normative)
```
:::spoiler Example `offer-credential` in 1.1
```json=
{
"id": "dfedaad3-bd7a-4c33-8337-fa94a547c0e2",
"type": "https://didcomm.org/issue-credential/2.0/offer-credential",
"body": {
"comment": "<some comment>",
"formats" : [{
// corresponds with offers-attach @id
"attach_id" : "76cd0d94-8eb6-4ef3-a094-af45d81e9528",
"format" : "dif/credential-manifest@v1.0"
}],
"offers~attach": [{
// corresponds with formats attach_id
"@id": "76cd0d94-8eb6-4ef3-a094-af45d81e9528",
"mime-type": "application/json",
"data": {
"json": {
// The following is the minimal form of a DIF CM
// NOTE: it assumes that the DID of the credential
// subject was exchanged OOB.
"credential_manifest": {
"issuer": "did:example:123",
"credential": {
"name": "Washington State Class A Commercial Driver License",
"schema": "ipfs:QmPXME1oRtoT627YKaDPDQ3PwA8tdP9rWuAAweLzqSwAWT"
}
}
}
}
}]
}
}
```
:::
:::spoiler Example `request-credential` in 2.1
```json=
{
"id": "d19c2efd-32ee-40e3-83cb-5434aba98a7b",
"type": "https://didcomm.org/issue-credential/2.0/request-credential",
"thread_id": "dfedaad3-bd7a-4c33-8337-fa94a547c0e2",
"body": {
"comment": "<some comment>",
"formats" : [],
"requests~attach": []
}
}
```
:::
:::spoiler Example `issue-credential` in 3.1
```json=
{
"id": "7ff4d4f5-1737-4ec5-a08a-48f2edfd9d0b",
"type": "https://didcomm.org/issue-credential/2.0/issue-credential",
"thread_id": "dfedaad3-bd7a-4c33-8337-fa94a547c0e2",
"body": {
"comment": "<some comment>",
"formats" : [
{
"attach_id" : "1e76e598-5bc0-4c77-826c-b6d730056f01",
// NOTE: the format for JWT/LD-Proofs is just a guess:
// 'dif/credential-format-designator/ldp_vc@v1.0' (LD-Proofs)
// 'dif/credential-format-designator/jwt_vc@v1.0' (JWT)
"format" : "dif/credential-format-designator/jwt_vc@v1.0"
}
]
"credentials~attach": [
{
"@id": "1e76e598-5bc0-4c77-826c-b6d730056f01",
"mime-type": "application/jwt",
"data": {
"base64": "<bytes for base64>"
}
}
]
}
}
```
:::
:::spoiler Example `ack` in 4.1
```json=
{
"id": "78f5eb0b-19c0-47f2-95e6-0a8fa936eef0",
"type": "https://didcomm.org/notification/1.0/ack",
"thread_id": "dfedaad3-bd7a-4c33-8337-fa94a547c0e2",
// NOTE: potential values are OK, FAIL (and PENDING)
"status": "OK"
}
```
:::
##### Flow requiring input data from Holder
The following flow contains a DIF CM that requires input data from the Holder.
```sequence
Issuer -> Holder: 1.2 | offer-credential (with DIF CM + DIF PD)
Holder --> Issuer: 202 Accepted (non-normative)
Holder -> Issuer: 2.2 | request-credential (with DIF PS)
Issuer --> Holder: 202 Accepted (non-normative)
Issuer -> Holder: 3.2 | issue-credential (W3C VC)
Holder --> Issuer: 202 Accepted (non-normative)
Holder -> Issuer: 4.2 | ack
Issuer --> Holder: 202 Accepted (non-normative)
```
:::spoiler Example `offer-credential` in 1.2
```json=
{
"id": "dfedaad3-bd7a-4c33-8337-fa94a547c0e2",
"type": "https://didcomm.org/issue-credential/2.0/offer-credential",
"body": {
"comment": "<some comment>",
"formats" : [{
// corresponds with offers-attach @id
"attach_id" : "76cd0d94-8eb6-4ef3-a094-af45d81e9528",
"format" : "dif/credential-manifest@v1.0"
}],
"offers~attach": [{
// corresponds with formats attach_id
"@id": "76cd0d94-8eb6-4ef3-a094-af45d81e9528",
"mime-type": "application/json",
"data": {
"json": {
"challenge": "1f44d55f-f161-4938-a659-f8026467f126",
"domain": "us.gov/DriverLicense",
// The following is the minimal form of a DIF CM
"credential_manifest": {
"issuer": "did:example:123",
"credential": {
"name": "Washington State Class A Commercial Driver License",
"schema": "ipfs:QmPXME1oRtoT627YKaDPDQ3PwA8tdP9rWuAAweLzqSwAWT"
},
"presentation_definition": {
// defines what input data is required, e.g., a DID
}
}
}
}
}]
}
}
```
:::
:::spoiler Example `request-credential` in 2.2
```json=
{
"id": "d19c2efd-32ee-40e3-83cb-5434aba98a7b",
"type": "https://didcomm.org/issue-credential/2.0/request-credential",
"body": {
"comment": "<some comment>",
"formats" : [{
// corresponds with offers-attach @id
"attach_id" : "76cd0d94-8eb6-4ef3-a094-af45d81e9528",
"format" : "dif/credential-manifest@v1.0"
}],
"requests~attach": [{
// corresponds with formats attach_id
"@id": "76cd0d94-8eb6-4ef3-a094-af45d81e9528",
"mime-type": "application/json",
"data": {
"json": {
// no credential_manifest required
"presentation_submission": {
// presentation submission object
}
}
}
}]
}
}
```
:::
:::spoiler Example `issue-credential` in 3.2
```json=
{
"id": "7ff4d4f5-1737-4ec5-a08a-48f2edfd9d0b",
"type": "https://didcomm.org/issue-credential/2.0/issue-credential",
"thread_id": "dfedaad3-bd7a-4c33-8337-fa94a547c0e2",
"body": {
"comment": "<some comment>",
"formats" : [
{
"attach_id" : "1e76e598-5bc0-4c77-826c-b6d730056f01",
// NOTE: the format for JWT/LD-Proofs is just a guess:
// 'dif/credential-format-designator/ldp_vc@v1.0' (LD-Proofs)
// 'dif/credential-format-designator/jwt_vc@v1.0' (JWT)
"format" : "dif/credential-format-designator/jwt_vc@v1.0"
}
]
"credentials~attach": [
{
"@id": "1e76e598-5bc0-4c77-826c-b6d730056f01",
"mime-type": "application/jwt",
"data": {
"base64": "<bytes for base64>"
}
}
]
}
}
```
:::
:::spoiler Example `ack` in 4.2
```json=
{
"id": "78f5eb0b-19c0-47f2-95e6-0a8fa936eef0",
"type": "https://didcomm.org/notification/1.0/ack",
"thread_id": "dfedaad3-bd7a-4c33-8337-fa94a547c0e2",
// NOTE: potential values are OK, FAIL (and PENDING)
"status": "OK"
}
```
:::
##### Error flows
In case the Holder is not happy with the `offer-credential`, the Holder can report a problem and abendon the interaction.
```sequence
Issuer -> Holder: offer-credential (with DIF CM)
Holder --> Issuer: 202 Accepted (non-normative)
Holder -> Issuer: report-problem (Credential Reject)
Issuer --> Holder: 202 Accepted (non-normative)
```
:::spoiler Example minimal `report-problem` after `offer-credential`
```json=
{
"id": "6dff98d9-d313-4c8f-80f0-1385767a5244",
"type": "https://didcomm.org/report-problem/1.0/problem-report",
"thread_id": "dfedaad3-bd7a-4c33-8337-fa94a547c0e2",
"description" : { "en": "localized message", "code": "credential-reject" }
}
```
:::
```sequence
Issuer -> Holder: offer-credential (with DIF CM)
Holder --> Issuer: 202 Accepted (non-normative)
Holder -> Issuer: report-problem (Request Reject)
Issuer --> Holder: 202 Accepted (non-normative)
```
:::spoiler Example `report-problem` after `request-credential`
```json=
{
"id": "9d7f2369-c270-45ab-b8ac-77552f7c7be0",
"type": "https://didcomm.org/report-problem/1.0/problem-report",
"thread_id": "dfedaad3-bd7a-4c33-8337-fa94a547c0e2",
"description" : { "en": "localized message", "code": "request-reject" }
}
```
:::
#### Holder starts Flow
Out of scope for now.
The Holder can start the interaction with a `propose-credential` or `request-credential` message in case information was pre-populated.