Developing Digital Identity Applications Using Hyperledger Indy, Ursa and Aries Frameworks — Messaging Protocols

Omer Dogan
stm-blockchain
Published in
5 min readMar 16, 2021
Hyperledger Aries Indy Ursa

This is part 2 of a 3 part series:

Part 1: Developing Digital Identity Applications Using Hyperledger Indy, Ursa and Aries Frameworks — Concepts

Part 2: Developing Digital Identity Applications Using Hyperledger Indy, Ursa and Aries Frameworks — Messaging Protocols

Part 3: Developing Digital Identity Applications Using Hyperledger Indy, Ursa and Aries Frameworks — Building an Agent

Introduction

In part 1, we have focused on the concepts and terms used in digital identity and Hyperledger Indy & Aries world. Now it is time to look into how the agents communicate and the protocols they use while establishing connection, issuing credentials and presenting proofs. The messaging protocols that we will focus on are as follows:

  • Agents establish connection
  • Issuer issues credentials to Holder (and Holder stores them in the wallet)
  • Holder presents proof (credentials or proof of having those credentials) to Verifier

For the details of how cryptographic functions and Zero Knowledge Proof (ZKP) work in these protocols, you can visit the post How Zero-Knowledge Proofs work on Indy Network.

Everything Starts with a Connection

The first step in starting communication is establishing a connection between two agents.

Step 1: Invitation

For establishing a connection, usually one of the agents invites the other agent for creating a connection. Invitation is a plain-text JSON data to be transfered to the other agent for processing (i.e. accepting) it. The invitation JSON data is usually rendered as a QR Code image by the inviter and made available to the other agent by sending in an email, showing on a web page or even printing on a paper. The invitee usually uses a mobile phone to scans the QR and extracts the actual invitation data. Invitation can also be sent to the other agent in plain text. This process is totally out of the messaging between the two agents. It is the phase just before the messaging starts.

The following is a sample invitation data in JSON format.

{
"@id": "2fa5d559-5588-4bc9-a6ff-b58afc61855f",
"serviceEndpoint": "http://endpointaddress",
"recipientKeys":["PFwmLCc3psR2YSjA3rksDc31nj8dk1zyoEy54bapxMsd"],
"label": "My Holder Agent",
"imageUrl": "http://imageURL"
}

And a corresponding QR Code image can be generated by the inviter and made available to the other agent via any channel.

As seen in the above JSON, the important data are the service endpoint address and the public keys of the inviter agent. These two will be used by the invitee to accept invitation and communicate back. The other two fields, label and imageUrl, are for distinguishing the agent by text and/or image.

Another version of the invitiation data can be generated by using the public DID of the inviter agent; if the inviter agent has a public DID registered on the ledger. In this case, serviceEndpoint and recepientKeys are not included in the invitation, but public DID instead; as shown below:

{
"@id": "53d96e74-f7ee-4bc7-ac55-40b5ec6ea4d8",
"label": "My Issuer Agent",
"did": "did:sov:NTKxqEWDjZov2Yq9jRZjs3",
"imageUrl": "http://imageURL"
}

When public DID exists in the invitation, it can be used to resolve the DID document of the inviter agent, which already includes service endpoint and public keys.

Step 2: Connection Request

When the invitee reveives the invitation information, it generates a new DID and corresponding DID document for this connection to be established. It then packages them, including the received Invitation ID, into a connection request by encypting it with the public key of the inviter. The invitee sends the packaged connection request to the service endpoint of the inviter.

Step 3: Connection Response

When the encrypted connection request is received by the inviter, it can decrypt it since it was encrypted with the inviter’s public key. Now the inviter has DID and DIDDoc from the invitee and it uses them to create a connection response and sends the connection response to the invitee. The invitee gets the connection response and after validation, creates the connection record in its wallet.

Step 4: Connection Completion

When the connection response processed on the invitee, the inviter is still now aware of that. Therefore, the invitee sends a completion message to the inviter so that the inviter can also finalize the connection establishment process.

There are more details on the connection protocol, which can be read on the 0160: Connection Protocol page of aries-rfcs github repository.

Issuing Credentials

Issuer is the agent who who can issue credentials. We can think of issuer examples like a University issuing diploma to graduates, a public institute issuing driver licenses etc. The agent who receives the issued credentials and stores them in the wallet has the role of Holder. The credential issuing process has a few steps between the Issuer and the Holder. Please note that connection should have been set up between these two agents before the credential issuing process.

Issue Credential Sequence Diagram

Both the Holder agent and Issuer agent should apply the protocol steps for a successful credential issuance process. There are more details on this protocol on Aries RFC 0453: Issue Credential Protocol 2.0 page of aries-rfcs github repository.

Presenting Proof

Holder, the agent who has already received credentials from an issuer, presents proofs of having some required credentials or satisfying some constraints to the Verifier. Verifier is the role who expects Holder to present some verifiable information so that the Verifier can ensure that the Holder meets some criteria. For the popular “university — job applicant — employer” VC example, employer has the role of Verifier.

Present Proof Sequence Diagram

In a presentation, there may be two types of information to be sent to the Verifier: attributes to be revealed and predicates to be proven that they are satisfied. A classical example of predicate is proving that the Holder is older than 18. When the Holder sends proof of being older than 18, actual age or the birth date is not needed to be revealed. Proving that the Holder satisfies a predicate without revealing the actual attribute values is provided by the Zero Knowledge Proof (ZKP).

The following is “presentation preview” object to be contained in the exchanged messages in this protocol.

{
"@type": "https://didcomm.org/present-proof/1.0/presentation-preview",
"attributes": [
{
"name": "<attribute_name>",
"cred_def_id": "<cred_def_id>",
"mime-type": "<type>",
"value": "<value>",
"referent": "<referent>"
},
// more attributes
],
"predicates": [
{
"name": "<attribute_name>",
"cred_def_id": "<cred_def_id>",
"predicate": "<predicate>",
"threshold": <threshold>
},
// more predicates
]
}

There are more details on this protocol on Aries RFC 0037: Present Proof Protocol 1.0 page of aries-rfcs github repository.

Summary

This post explains the main messaging protocols between the agents of a digital identity application. In the next post of this series, we will start developing/running a digital identity application.

--

--