Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add guides for connect and issue flows #4

Merged
merged 6 commits into from
Feb 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 204 additions & 0 deletions documentation/tutorials/connections/connection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
# Connections

A connection is a stateful relationship between two parties that enables secure communication.

The **Connection protocol** is required to establish secure connections between agents,
allowing them to exchange information and interact.

The protocol provides endpoints for creating and managing connections, as well as for accepting invitations.

## Roles

The connection protocol has two roles:

1. **Inviter**: A subject that initiates a connection request by sending a *connection invitation*.
2. **Invitee**: A subject that receives a connection invitation and accepts it by sending a *connection request*.

## Prerequisites

1. **Inviter** and **Invitee** PRISM Agents up and running

## PRISM Agent endpoints overview

The protocol uses the following REST API endpoints:

1. [`/connections`](/agent-api/#tag/Connections-Management):
- [`POST`](/agent-api/#tag/Connections-Management/operation/createConnection): Creates a new connection and returns an invitation
- [`GET`](/agent-api/#tag/Connections-Management/operation/getConnections): Returns a list of connections
2. [`GET /connections/{connectionId}`](/agent-api/#tag/Connections-Management/operation/getConnection): Returns an existing connection record by id
3. [`POST /connection-invitations`](/agent-api/#tag/Connections-Management/operation/acceptConnectionInvitation): Accepts an externally received invitation

:::info
For more detailed information, please, check the full **[PRISM Agent API](/agent-api).**
:::

## Inviter Flow

1. Generate and share a new Out-of-Band (OOB) invitation (connection is created in `InvitationGenerated` state)
2. Receive a connection request from the **Invitee** (connection is moved to `ConnectionRequestReceived` state)
3. Accept the connection request (connection is moved to `ConnectionResponsePending` state)
4. Send the connection response via the DIDComm Agent (connection achieves `ConnectionResponseSent` state)
antonbaliasnikov marked this conversation as resolved.
Show resolved Hide resolved

The **Inviter**'s state transitions are represented by the following Mermaid diagram:
```mermaid
---
title: Inviter Connection State
---
stateDiagram-v2
[*] --> InvitationGenerated: generate and share new OOB invitation
InvitationGenerated --> ConnectionRequestReceived: receive connection request
ConnectionRequestReceived --> ConnectionResponsePending: accept connection request
ConnectionResponsePending --> ConnectionResponseSent: send connection response (DIDComm)
ConnectionResponseSent --> [*]
```


## Invitee Flow

1. Receive the OOB invitation (`InvitationReceived` state)
2. Accept the invitation (connection is created in `ConnectionRequestPending` state)
3. Send the connection request via DIDComm (connection achieves `ConnectionRequestSent` state)
4. Receive the connection response (connection achieves `ConnectionResponseReceived` state)

The **Invitee**'s state transitions are represented by the following Mermaid diagram:
```mermaid
---
title: Invitee Connection State
---
stateDiagram-v2
[*] --> InvitationReceived: receive OOB invitation
InvitationReceived --> ConnectionRequestPending: accept invitation
ConnectionRequestPending --> ConnectionRequestSent: send connection request (DIDComm)
ConnectionRequestSent --> ConnectionResponseReceived: receive connection response
ConnectionResponseReceived --> [*]
```

## Command line example

The following example demonstrates on how you could use two PRISM Agents API to set up connection between them.

### **Inviter** creates an invitation

```shell
curl -X 'POST' \
'http://localhost:8080/prism-agent/connections' \
-H 'Content-Type: application/json' \
-d '{ "label": "Connect with Alice" }' | jq
```

Example response:
```json
{
"connectionId": "1893e207-4cba-4792-8179-067c78d2acc2",
"createdAt": "2023-02-02T17:14:13.593647Z",
"invitation": {
"from": "did:peer:inviter-did",
"id": "1893e207-4cba-4792-8179-067c78d2acc2",
"invitationUrl": "https://domain.com/path?_oob={RAW_INVITATION}",
"type": "https://didcomm.org/out-of-band/2.0/invitation"
},
"kind": "/connections/1893e207-4cba-4792-8179-067c78d2acc2",
"label": "Connect with Alice",
"self": "Connection",
"state": "InvitationGenerated"
}
```

### **Invitee** accepts OOB invitation

Replace `{RAW_INVITATION}` with the value of the '_oob' query string parameter from the invitation URL above
```shell
curl -X 'POST' \
'http://localhost:8090/prism-agent/connection-invitations' \
-H 'Content-Type: application/json' \
-d '{ "invitation": "{RAW_INVITATION}" }' | jq
```

Example response:
```json
{
"connectionId": "755a457a-878e-4292-a3f2-cb83601f802e",
"createdAt": "2023-02-02T18:05:58Z",
"invitation": {
"from": "did:peer:inviter-did",
"id": "1893e207-4cba-4792-8179-067c78d2acc2",
"invitationUrl": "https://domain.com/path?_oob={RAW_INVITATION}",
"type": "https://didcomm.org/out-of-band/2.0/invitation"
},
"kind": "/connections/755a457a-878e-4292-a3f2-cb83601f802e",
"myDid": "did:peer:invitee-did",
"self": "Connection",
"state": "ConnectionRequestPending",
"theirDid": "did:peer:inviter-did",
"updatedAt": "2023-02-02T18:05:59Z"
}
```

### **Invitee** retrieves the list of connections

```shell
curl -X 'GET' 'http://localhost:8090/prism-agent/connections' | jq
```

Example output:
```json
{
"contents": [
{
"connectionId": "755a457a-878e-4292-a3f2-cb83601f802e",
"createdAt": "2023-02-02T18:05:58Z",
"invitation": {
"from": "did:peer:issuer-did",
"id": "1893e207-4cba-4792-8179-067c78d2acc2",
"invitationUrl": "https://domain.com/path?_oob={RAW_INVITATION}",
"type": "https://didcomm.org/out-of-band/2.0/invitation"
},
"kind": "/connections/755a457a-878e-4292-a3f2-cb83601f802e",
"myDid": "did:peer:holder-did",
"self": "Connection",
"state": "ConnectionResponseReceived",
"theirDid": "did:peer:issuer-did",
"updatedAt": "2023-02-02T18:06:14Z"
}
],
"kind": "Collection",
"self": "/collections"
}
```

### **Inviter** retrieves the list of connections

```shell
curl -X 'GET' 'http://localhost:8080/prism-agent/connections' | jq
```

Example response:
```json
{
"contents": [
{
"connectionId": "1893e207-4cba-4792-8179-067c78d2acc2",
"createdAt": "2023-02-02T17:14:13Z",
"invitation": {
"from": "did:peer:issuer-did",
"id": "1893e207-4cba-4792-8179-067c78d2acc2",
"invitationUrl": "https://domain.com/path?_oob={RAW_INVITATION}",
"type": "https://didcomm.org/out-of-band/2.0/invitation"
},
"kind": "/connections/1893e207-4cba-4792-8179-067c78d2acc2",
"label": "Connect with Alice",
"myDid": "did:peer:issuer-did",
"self": "Connection",
"state": "ConnectionResponseSent",
"theirDid": "did:peer:holder-did",
"updatedAt": "2023-02-02T18:06:16Z"
}
],
"kind": "Collection",
"self": "/collections"
}
```

:::info
For more detailed information, please, check the full **[PRISM Agent API](/agent-api).**
:::
177 changes: 176 additions & 1 deletion documentation/tutorials/credentials/issue.md
Original file line number Diff line number Diff line change
@@ -1 +1,176 @@
# Issue credential
# Issue Credentials

In Atala PRISM, the **Issue Credentials Protocol** allows you to create, retrieve, and manage issued verifiable credentials (VCs) between a VC issuer and a VC holder.

## Roles

In the **Issue Credentials Protocol**, there are two roles:

1. **Issuer** is responsible for creating a new credential offer, sending it to a **Holder**, and issuing the VC once the offer is accepted.
2. **Holder** is responsible for accepting a credential offer from an issuer and receiving the VC.

The **Issuer** and **Holder** interact with the **PRISM Agent API** to perform the operations defined in the protocol.


## Prerequisites

Before using the **Issuing Credentials protocol**, the following conditions must be present:

1. **Issuer** and **Holder** PRISM Agents up and running
2. A connection must be established between the **Issuer** and **Holder** PRISM Agents (see [Connections](../connections/connection.md))

## Overview

The protocol described is a VC issuance process between two Atala PRISM Agents, the **Issuer** and the **Holder**.

The protocol consists of the following main parts:

1. The **Issuer** creates a new credential offer using the [`/issue-credentials/credential-offers`](/agent-api/#tag/Issue-Credentials-Protocol/operation/createCredentialOffer) endpoint, which includes information such as the schema identifier and claims.
2. The **Holder** can then retrieve the offer using the [`/issue-credentials/records`](/agent-api/#tag/Issue-Credentials-Protocol/operation/getCredentialRecords) endpoint and accept the offer using the [`/issue-credentials/records/{recordId}/accept-offer`](/agent-api/#tag/Issue-Credentials-Protocol/operation/acceptCredentialOffer) endpoint.
3. The **Issuer** then uses the [`/issue-credentials/records/{recordId}/issue-credential`](/agent-api/#tag/Issue-Credentials-Protocol/operation/issueCredential) endpoint to issue the credential, which gets sent to the Holder via DIDComm. The Holder receives the credential, and the protocol is complete.

The schema identifier defines the structure and the credential type issued,
while the claims provide specific information about the individual, such as their name or qualifications.

This protocol is applicable in various real-life scenarios, such as educational credentialing, employment verification, and more.
In these scenarios, the **Issuer** could be a school, an employer, etc., and the **Holder** could be a student or an employee.
The VCs issued during this protocol could represent a diploma, a certificate of employment, etc.

## Endpoints

| Endpoint | Description | Role |
| --- | --- | --- |
| [`/issue-credentials/credential-offers`](/agent-api/#tag/Issue-Credentials-Protocol/operation/createCredentialOffer) | This endpoint allows you to create a new credential offer | Issuer |
| [`/issue-credentials/records`](/agent-api/#tag/Issue-Credentials-Protocol/operation/getCredentialRecords) | This endpoint allows you to retrieve a collection of all the existing credential records | Issuer, Holder |
| [`/issue-credentials/records/{recordId}`](/agent-api/#tag/Issue-Credentials-Protocol/operation/getCredentialRecord) | This endpoint allows you to retrieve a specific credential record by its `id` | Issuer, Holder |
| [`/issue-credentials/records/{recordId}/accept-offer`](/agent-api/#tag/Issue-Credentials-Protocol/operation/acceptCredentialOffer) | This endpoint allows you to accept a credential offer | Holder |
| [`/issue-credentials/records/{recordId}/issue-credential`](/agent-api/#tag/Issue-Credentials-Protocol/operation/issueCredential) | This endpoint allows you to issue a VC for a specific credential record. | Issuer |


:::info
For more detailed information, please, check the full **[PRISM Agent API](/agent-api).**
:::

## Issuer interactions

This section describes the Issuer role's available interactions with the PRISM Agent.
antonbaliasnikov marked this conversation as resolved.
Show resolved Hide resolved

### Creating a Credential Offer

To start the process, the issuer needs to create a credential offer.
To do this, make a `POST` request to the [`/issue-credentials/credential-offers`](/agent-api/#tag/Issue-Credentials-Protocol/operation/createCredentialOffer) endpoint with a JSON payload that includes the following information:

1. `subjectId`: This field represents the unique identifier for the subject of the verifiable credential. It is a DID (Decentralized Identifier) string, such as `did:prism:subjectIdentifier`.
2. `schemaId`: This is an identifier for a schema, which defines the structure and format of the data in a verifiable credential. The schema identifier must be unique and typically a URL or a URN.
3. `claims`: The data stored in a verifiable credential. Claims get expressed in a key-value format and must conform to the structure and format defined in the schema. The claims contain the data that the issuer attests to, such as name, address, date of birth, and so on.

Once the request initiates, a new credential record for the issuer gets created with a unique ID. The state of this record is now `OfferPending`.

```shell
antonbaliasnikov marked this conversation as resolved.
Show resolved Hide resolved
# Issuer POST request to create a new credential offer
curl -X 'POST' \
'http://localhost:8080/prism-agent/issue-credentials/credential-offers' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"schemaId": "schema:1234",
"subjectId": "did:prism:subjectIdentifier",
"claims": {
"firstname": "Alice",
"lastname": "Wonderland",
"birthdate": "01/01/2000"
}
}'
```

### Sending the Offer to the Holder

The next step for the **Issuer** is to send the offer to the holder using DIDComm.
To do this, the **Issuer** agent will process the offer and send it to the holder agent.
This process is automatic. The state of the **Issuer**'s record will change to `OfferSent`.

### Issuing the Credential

Once the holder has approved the offer and sent a request to the **Issuer**,
the **Issuer** will receive the request via DIDComm and update the state of the record to `RequestReceived.`

The **Issuer** can then use the [`/issue-credentials/records/{recordId}/issue-credential`](/agent-api/#tag/Issue-Credentials-Protocol/operation/issueCredential) endpoint to issue the credential to the holder.

```shell
# Issuer POST request to issue the credential
# make sure you have `issuer_record_id` extracted from created credential offer
# and the record achieved `RequestReceived` state
curl -X POST \
"http://localhost:8080/prism-agent/issue-credentials/records/$issuer_record_id/issue-credential" \
-H "Content-Type: application/json"
```

When this endpoint gets called, the state of the record will change to `CredentialPending,` and after processing, it will change to `CredentialGenerated.`

Finally, the **Issuer** agent will send the credential to the holder via DIDComm,
and the state of the record will change to `CredentialSent`.
At this point, the **Issuer**'s interactions with the holder are complete.

```mermaid
---
title: Issuer flow
---
stateDiagram-v2
[*] --> OfferPending: create credential offer (`/issue-credentials/credential-offers`)
OfferPending --> OfferSent: send offer (auto via PRISM Agent DIDComm)
OfferSent --> RequestReceived: receive request (auto via PRISM Agent DIDComm)
RequestReceived --> CredentialPending: issue credential (`/issue-credentials/records/{recordId}/issue-credential`)
CredentialPending --> CredentialGenerated: process issued credential (auto via PRISM Agent)
CredentialGenerated --> CredentialSent: send credential (auto via PRISM Agent)
```

## Holder interactions

This section describes the Holder role's available interactions with the PRISM Agent.

### Receiving the VC Offer

The **Holder** will receive the offer from the **Issuer** via DIDComm,
and a new credential record with a unique ID will be created in the `OfferReceived` state.

This process is automatic for the PRISM Agent.

You could check if a new credential offer is available using [`/issue-credentials/records`](/#tag/Issue-Credentials-Protocol/operation/getCredentialRecords) request and check for any records available in `OfferReceived` state:
```shell
# Holder GET request to retrieve credential records
curl "http://localhost:8090/prism-agent/issue-credentials/records" \
-H "Content-Type: application/json"
```


### Approving the VC Offer

To accept the offer, the **Holder** can make a `POST` request to the [`/issue-credentials/records/{recordId}/accept-offer`](/agent-api/#tag/Issue-Credentials-Protocol/operation/acceptCredentialOffer) endpoint:
```shell
# Holder POST request to accept the credential offer
curl -X POST "http://localhost:8090/prism-agent/issue-credentials/records/$holder_record_id/accept-offer" \
-H "Content-Type: application/json"
```

This request will change the state of the record to `RequestPending`.

### Receiving the VC Credential

Once the **Holder** has approved the offer and sent a request to the **Issuer**, the **Holder** agent will process the request and send it to the **Issuer** agent.
The state of the **Holder**'s record will change to `RequestSent`.

After the **Issuer** has issued the credential, the **Holder** will receive the credential via DIDComm, and the state of the **Holder**'s record will change to `CredentialReceived`.
This process is automatic for the PRISM Agent.

**Holder** can check the achieved credential using a GET request to [`/issue-credentials/records/{recordId}/`](/agent-api/#tag/Issue-Credentials-Protocol/operation/getCredentialRecord) endpoint.

```mermaid
---
title: Holder Flow
---
stateDiagram-v2
[*] --> OfferReceived: receive offer (auto via PRISM Agent)
OfferReceived --> RequestPending: accept offer (`/issue-credentials/records/{recordId}/accept-offer`)
RequestPending --> RequestSent: send request (auto via PRISM Agent)
RequestSent --> CredentialReceived: receive credential (auto via PRISM Agent)
```
1 change: 0 additions & 1 deletion documentation/tutorials/credentials/revoke.md

This file was deleted.

1 change: 0 additions & 1 deletion documentation/tutorials/credentials/verify.md

This file was deleted.

Loading