Issue-credential flow
This page documents the Issue-credential technical flow (as described in the spec here) between two Aries agents: Agent A (the Issuer) and Agent B (the Holder).
There are three alternate flows. We will be focusing on the "holder begins with a proposal" flow. The other two flows are essentially just subsets of this flow.
- We're taking the "happy path" - no errors.
- An ack for the receipt of the credential was not requested.
Before implementing the full flow, we could instead start with a simpler version first, and then expand upon it later. Here's what a simplified version might look like. It eliminates the propose-offer cycle and instead merges the proposal message into the request message, effectively turning the exchange into a two-step process:
High Level Design - Methods, Inputs/Actions - Simplified Flow
SendCredentialRequest
Sends a request-credential message to another agent.
Input:
- Connection ID: Used to identify the agent to send this proposal to.
- Desired credential data (optional)
- Requested formats for credential.
- Comment (optional)
- Schema ID - a filter to request credentials based on a particular schema (optional).
- Credential definition ID - a filter to request a credential based on a particular credential definition (optional).
Actions:
- Send request-credential message to other agent, along with a unique Credential_exchange_id.
- Create a credential_exchange_record with the unique Credential_exchange_id.
- Update state to credential-requested for given credential_exchange_record.
HandleCredentialRequest
Receives a request-credential message from another agent.
Input:
- A credential_exchange_id.
- A request-credential message.
Actions:
- Validate incoming message.
- Update state to credential_requested for given credential_exchange_record.
- Notify business logic via client.
SendIssueCredential
Sends an issue-credential message to another agent.
Input:
- A credential_exchange_id.
- The issued credentials.
- Comment (optional)
Actions:
- Send issue-credential message to other agent.
- Update state to credential-issued for given credential_exchange_record.
HandleIssueCredential
Receives an issue-credential message from another agent.
Input:
- A credential_exchange_id.
- An issue-credential message.
Actions:
- Validate incoming message.
- Store the credential.
- Update state to credential_received for given credential_exchange_record.
- Notify business logic via client.
Below shows the full flow.
High Level Design - Methods, Inputs/Actions - Full Flow
SendProposal
Sends a propose-credential message to another agent.
Input:
- Connection ID: Used to identify the agent to send this proposal to.
- Desired credential data (optional)
- Comment (optional)
- Schema ID - a filter to request credentials based on a particular schema (optional)
- Credential definition ID - a filter to request a credential based on a particular credential definition (optional)
Actions:
- Send proposal message to other agent, along with a unique Credential_exchange_id.
- Create a credential_exchange_record with the unique Credential_exchange_id.
- Update state to proposal_sent for given credential_exchange_record.
HandleProposal
Receives a propose-credential message from another agent.
Input: A propose-credential message and a credential_exchange_id.
Actions:
- Validate incoming message.
- Create a credential_exchange_record with the provided unique credential_exchange_id.
- Update state to proposal_received for given credential_exchange_record.
- Notify business logic.
SendOffer
Sends offer-credential message to another agent.
Input:
- A credential_exchange_id.
- Connection ID: Used to identify the agent to send this offer to.
- Credential preview: Represents the credential data that the issuer wants to issue.
- "Offers" attachment: An array of attachments that further define the credential being offered. Could be used to clarify the format of the credentials.
- Comment (optional)
Actions:
- Validate incoming message.
- Send offer-credential message to other agent.
- Update state to offer_sent for given credential_exchange_record.
HandleOffer
Receives an offer-credential message from another agent.
Input: An offer-credential message and a credential_exchange_id.
Actions:
- Update state to offer_sent for given credential_exchange_record.
- Notify business logic via client.
SendCredentialRequest
Sends a request-credential message to another agent.
Input:
- A credential_exchange_id.
- Requested formats for credential.
Actions:
- Send request-credential message to other agent.
- Update state to credential-requested for given credential_exchange_record.
HandleCredentialRequest
Receives a request-credential message from another agent.
Input:
- A credential_exchange_id.
- A request-credential message.
Actions:
- Validate incoming message.
- Update state to credential_requested for given credential_exchange_record.
- Notify business logic via client.
SendIssueCredential
Sends an issue-credential message to another agent.
Input:
- A credential_exchange_id.
- The issued credentials.
- Comment (optional)
Actions:
- Send issue-credential message to other agent.
- Update state to credential-issued for given credential_exchange_record.
HandleIssueCredential
Receives an issue-credential message from another agent.
Input:
- A credential_exchange_id.
- An issue-credential message.
Actions:
- Validate incoming message.
- Store the credential.
- Update state to credential_received for given credential_exchange_record.
- Notify business logic via client.
Additional details
Layer responsibilities
Business logic: Initiates the protocol and ultimately determines whether to accept/refuse going to the next step.
Client: The first step in sending a message to another agent happens here. The business logic/controller does not call the underlying service directly. Note that there can be different clients depending on the need (e.g. Go client, REST client, etc)
Service: Last step in the chain for sending messages and also the first step in the chain for receiving messages. Responsible for tracking state and saving messages to the local store.
Other Details
The issuer and holder are assumed to have already established a connection previously via DID Exchange.
Unknowns - Clarification Needed!
The spec generally seems to be assuming that Indy is being used. There are some parts of the spec that, in the absence of Indy, are unclear:
The propose-credential message has schema_id and cred_def_id fields. In the ACA-Py demo they are used to identify the credential format, which is stored in the ledger. What should we do here?
The offer-credential message has an "offers~attach" field. It says that it's supposed to be an "array of attachments that further define the credential being offered". The specific example it provides describing what this looks like is for Indy. What do we do?
The request-credential message has a "requests~attach" field. Similar to the "offers~attach" field from offer-credential, it is supposed to define the requested formats for the credential. In the absence of Indy, what does this look like?
One of the supported flows is to send a request-credential message without going through the propose-offer cycle. How does this work?
Design Questions TBD :
- How to register schema on the ledger?
- Go through VC and refactor if required ?
- At what point we need to store the schema to the ledger and retrieve from ledger ?
- If schema ID is related to verifiable credential ?