Skip to content

Commit

Permalink
feat(prism-agent): implement AnonCreds issuance flow (#693)
Browse files Browse the repository at this point in the history
Signed-off-by: Shailesh Patil <[email protected]>
Signed-off-by: Benjamin Voiturier <[email protected]>
Signed-off-by: FabioPinheiro <[email protected]>
Signed-off-by: Pat Losoponkul <[email protected]>
Signed-off-by: Bassam Riman <[email protected]>
Signed-off-by: Anton Baliasnikov <[email protected]>
Signed-off-by: Milos Backonja <[email protected]>
Co-authored-by: Pat Losoponkul <[email protected]>
Co-authored-by: Shailesh Patil <[email protected]>
Co-authored-by: Yurii Shynbuiev - IOHK <[email protected]>
Co-authored-by: bvoiturier <[email protected]>
Co-authored-by: Shailesh Patil <[email protected]>
Co-authored-by: Bassam <[email protected]>
Co-authored-by: Anton Baliasnikov <[email protected]>
Co-authored-by: atala-dev <[email protected]>
Co-authored-by: davidpoltorak-io <[email protected]>
Co-authored-by: Milos Backonja <[email protected]>
  • Loading branch information
11 people authored Oct 9, 2023
1 parent a579aa9 commit 9165a6f
Show file tree
Hide file tree
Showing 123 changed files with 4,058 additions and 1,857 deletions.
31 changes: 20 additions & 11 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sbtbuildinfo.BuildInfoPlugin.autoImport.*
import org.scoverage.coveralls.Imports.CoverallsKeys.*
import sbtbuildinfo.BuildInfoPlugin.autoImport.*

inThisBuild(
Seq(
Expand Down Expand Up @@ -302,6 +302,10 @@ lazy val D_EventNotification = new {
val baseDependencies: Seq[ModuleID] = zioDependencies
}

lazy val D_Pollux_AnonCreds = new {
val baseDependencies: Seq[ModuleID] = Seq(D.zio, D.zioJson)
}

lazy val D_PrismAgent = new {

// Added here to make prism-crypto works.
Expand Down Expand Up @@ -508,6 +512,11 @@ lazy val protocolPresentProof = project
.settings(libraryDependencies += D.munitZio)
.dependsOn(models)

lazy val vc = project
.in(file("mercury/mercury-library/vc"))
.settings(name := "mercury-verifiable-credentials")
.dependsOn(protocolIssueCredential, protocolPresentProof) //TODO merge those two modules into this one

lazy val protocolTrustPing = project
.in(file("mercury/mercury-library/protocol-trust-ping"))
.settings(name := "mercury-protocol-trust-ping")
Expand Down Expand Up @@ -554,6 +563,7 @@ lazy val agent = project // maybe merge into models
protocolLogin,
protocolIssueCredential,
protocolPresentProof,
vc,
protocolConnection,
protocolReportProblem,
protocolTrustPing,
Expand Down Expand Up @@ -664,7 +674,7 @@ lazy val polluxCore = project
.dependsOn(irisClient)
.dependsOn(prismAgentWalletAPI)
.dependsOn(polluxVcJWT)
.dependsOn(protocolIssueCredential, protocolPresentProof, resolver, agentDidcommx, eventNotification, polluxAnoncreds)
.dependsOn(vc, resolver, agentDidcommx, eventNotification, polluxAnoncreds)

lazy val polluxDoobie = project
.in(file("pollux/lib/sql-doobie"))
Expand All @@ -687,20 +697,16 @@ lazy val polluxAnoncreds = project
.enablePlugins(JavaAppPackaging)
.settings(
name := "pollux-anoncreds",
Compile / unmanagedJars += baseDirectory.value / "anoncreds-java-1.0-SNAPSHOT.jar",
Compile / unmanagedJars += baseDirectory.value / "anoncreds-jvm-1.0-SNAPSHOT.jar",
Compile / unmanagedResourceDirectories ++= Seq(
baseDirectory.value / "native-lib" / "NATIVE"
),
libraryDependencies ++= D_Pollux_AnonCreds.baseDependencies
)

lazy val polluxAnoncredsTest = project
.in(file("pollux/lib/anoncredsTest"))
.settings(
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "3.2.15" % Test,
("me.vican.jorge" %% "dijon" % "0.6.0" % Test).cross(CrossVersion.for3Use2_13)
),
)
.settings(libraryDependencies ++= Seq("org.scalatest" %% "scalatest" % "3.2.15" % Test))
.dependsOn(polluxAnoncreds % "compile->test")

// #####################
Expand Down Expand Up @@ -752,7 +758,9 @@ lazy val prismAgentWalletAPI = project
.settings(prismAgentConnectCommonSettings)
.settings(
name := "prism-agent-wallet-api",
libraryDependencies ++= D_PrismAgent.keyManagementDependencies ++ D_PrismAgent.postgresDependencies ++ Seq(D.zioMock)
libraryDependencies ++= D_PrismAgent.keyManagementDependencies ++ D_PrismAgent.postgresDependencies ++ Seq(
D.zioMock
)
)
.dependsOn(
agentDidcommx,
Expand Down Expand Up @@ -818,6 +826,7 @@ lazy val aggregatedProjects: Seq[ProjectReference] = Seq(
protocolRouting,
protocolIssueCredential,
protocolPresentProof,
vc,
protocolTrustPing,
resolver,
agent,
Expand All @@ -828,7 +837,7 @@ lazy val aggregatedProjects: Seq[ProjectReference] = Seq(
polluxCore,
polluxDoobie,
polluxAnoncreds,
// polluxAnoncredsTest, REMOVE THIS FOR NOW
polluxAnoncredsTest,
connectCore,
connectDoobie,
prismAgentWalletAPI,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object ConnectionRepositorySpecSuite {

private def connectionRecord = ConnectionRecord(
UUID.randomUUID,
Instant.ofEpochSecond(Instant.now.getEpochSecond),
Instant.now,
None,
UUID.randomUUID().toString,
None,
Expand Down
145 changes: 145 additions & 0 deletions docs/docusaurus/credentialdefinition/create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Create the Credential Definition

The PRISM platform v2.0 exposes REST API for creation, fetching, and searching the [credential definition](/docs/concepts/glossary#credential-definition) records.

The OpenAPI specification and ReDoc documentation describe the endpoint.

In this document, you can find step-by-step instructions for creating the credential definition.

## Step-by-step guide

The following guide demonstrates how to create a birth certificate credential definition.

### 1. Define the Credential Definition for the Verifiable Credential

Assume you are aiming to define a credential for birth certificates. This credential definition has specific properties and ties to a schema in the PRISM platform.

Here's a sample content of the credential definition:

```json
{
"name": "Birth Certificate location",
"description": "Birth certificate Anoncred Credential Definition",
"version": "1.0.0",
"tag": "Licence",
"author": "{{ISSUER_DID_SHORT}}",
"schemaId": "http://host.docker.internal:8080/prism-agent/schema-registry/schemas/{{SCHEMA_ID}}",
"signatureType": "CL",
"supportRevocation": true
}
```

### 2. Create the Credential Definition Record

1. Use your preferred REST API client, such as Postman or Insomnia, or utilize a client stub that's generated based on the OpenAPI specification.

2. In your API client, initiate a new POST request to the `/credential-definition-registry/definitions/` endpoint.

Please note: The `author` field value should align with the short form of a PRISM DID previously created by the same agent. It's okay if this DID is unpublished. You can refer to the [Create DID](../dids/create.md) documentation for more comprehensive details on crafting a PRISM DID.

3. Construct the request body using the following JSON object:

```json
{
"name": "Birth Certificate location",
"description": "Birth certificate Anoncred Credential Definition",
"version": "1.0.0",
"tag": "Licence",
"author": "{{ISSUER_DID_SHORT}}",
"schemaId": "http://host.docker.internal:8080/prism-agent/schema-registry/schemas/{{SCHEMA_ID}}",
"signatureType": "CL",
"supportRevocation": true
}
```

4. Transmit the POST Request to Create the New Credential Definition

Once you've crafted your POST request, send it. Upon success, the server should respond with a GUID that uniquely identifies the new credential definition.

For ease of reference, here's a `curl` example:

```shell
curl -X 'POST' \
'http://localhost:8080/credential-definition-registry/definitions/' \
-H 'accept: application/json' \
-H "apikey: $API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"name": "Birth Certificate location",
"description": "Birth certificate Anoncred Credential Definition",
"version": "1.0.0",
"tag": "Licence",
"author": "{{ISSUER_DID_SHORT}}",
"schemaId": "http://host.docker.internal:8080/prism-agent/schema-registry/schemas/{{SCHEMA_ID}}",
"signatureType": "CL",
"supportRevocation": true
}
```
A potential response could be:
```json
{
"guid": "3f86a73f-5b78-39c7-af77-0c16123fa9c2",
"id": "f2bfbf78-8bd6-4cc6-8b39-b3a25e01e8ea",
"longId": "did:prism:agent/f2bfbf78-8bd6-4cc6-8b39-b3a25e01e8ea?version=1.0.0",
"name": "Birth Certificate location",
"version": "1.0.0",
"description": "Birth certificate Anoncred Credential Definition",
"tag": "Licence",
"author": "did:prism:4a5b5cf0a513e83b598bbea25cd6196746747f361a73ef77068268bc9bd732ff",
"authored": "2023-03-14T14:41:46.713943Z",
"schemaId": "http://host.docker.internal:8080/prism-agent/schema-registry/schemas/{{SCHEMA_ID}}",
"signatureType": "CL",
"supportRevocation": true,
"kind": "CredentialDefinition",
"self": "/credential-definition-registry/definitions/3f86a73f-5b78-39c7-af77-0c16123fa9c2"
}
```
### 3. Retrieve the Created Credential Definition
To obtain details of the newly created credential definition, send a GET request to the `/credential-definition-registry/definitions/{guid}` endpoint. Replace `{guid}` with the unique GUID returned from the previous creation step.
To exemplify this process, use the following `curl` command:
```shell
curl -X 'GET' \
'http://localhost:8080/credential-definition-registry/definitions/3f86a73f-5b78-39c7-af77-0c16123fa9c2' \
-H 'accept: application/json' \
-H "apikey: $API_KEY"
```
You should receive a response containing the JSON object representing the credential definition you've just established:

```json
{
"guid": "3f86a73f-5b78-39c7-af77-0c16123fa9c2",
"id": "f2bfbf78-8bd6-4cc6-8b39-b3a25e01e8ea",
"longId": "did:prism:agent/f2bfbf78-8bd6-4cc6-8b39-b3a25e01e8ea?version=1.0.0",
"name": "Birth Certificate location",
"version": "1.0.0",
"description": "Birth certificate Anoncred Credential Definition",
"tag": "Licence",
"author": "did:prism:4a5b5cf0a513e83b598bbea25cd6196746747f361a73ef77068268bc9bd732ff",
"authored": "2023-03-14T14:41:46.713943Z",
"schemaId": "http://host.docker.internal:8080/prism-agent/schema-registry/schemas/{{SCHEMA_ID}}",
"signatureType": "CL",
"supportRevocation": true,
"kind": "CredentialDefinition",
"self": "/credential-definition-registry/definitions/3f86a73f-5b78-39c7-af77-0c16123fa9c2"
}
```

Remember, in the PRISM platform, the combination of author, id, and version uniquely identifies each credential definition. Thus, using the same agent DID as the author, you cannot establish another credential definition with identical id and version values.

### 4. Update the Credential Definition

To update or upgrade an existing credential definition, follow the steps outlined below:

1. Begin with the first step and make necessary modifications to the Credential Definition.
2. Update the `version` value to reflect the changes made. This is important to ensure that each version of the credential definition remains distinct.
3. Create a new credential definition entry with the updated version and schema.

Note: When you make changes to an existing credential definition, it's essential to version the new entry accurately. This ensures clarity and avoids potential conflicts or misunderstandings among different versions of the same definition.
127 changes: 127 additions & 0 deletions docs/docusaurus/credentialdefinition/credential-definition.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Anoncred Credential Definition Guide

## Abstract

This document details the structure, supported formats, and technical intricacies of Anoncred Credential Definitions within the Atala PRISM Platform.

## 1. Introduction

An Anoncred Credential Definition serves as a standardized format for any given Anoncred Verifiable Credential. By embedding essential attributes unique to each type of credential, it lays the groundwork for diverse categories of verifiable credentials. Integrating this definition on a public blockchain ensures its availability and verifiability for all stakeholders.

The PRISM Platform endorses the Anoncred Credential Definition, conforming to the [Hyperledger AnonCreds specification](https://hyperledger.github.io/anoncreds-spec/#term:schemas).

## 2. Anoncred Credential Definition Attributes

### name (String)

A descriptive and readable name indicating the type or category of the credential.

**Example:**
```json
{
"name": "{{CREDENTIAL_NAME}}"
}
```

---

### description (String)

A succinct descriptor providing an overview of the credential definition's purpose or category.

**Example:**
```json
{
"description": "{{CREDENTIAL_DESCRIPTION}}"
}
```

---

### version (String)

Specifies the version of the credential definition, using the [SemVer](https://semver.org/) protocol.

**Example:**
```json
{
"version": "{{VERSION_NUMBER}}"
}
```

---

### tag (String)

A unique identifier or tag associated with the credential definition.

**Example:**
```json
{
"tag": "{{TAG_IDENTIFIER}}"
}
```

---

### author (DID)

The decentralized identifier (DID) of the entity that created the credential definition.

**Example:**
```json
{
"author": "{{ISSUER_DID_SHORT}}"
}
```

---

### schemaId (URI)

A distinct reference to retrieve the schema from the PRISM Schema Registry.

**Example:**
```json
{
"schemaId": "{{SCHEMA_REGISTRY_URI}}"
}
```

---

### signatureType (String)

Indicates the type of signature applied to the credential definition.

**Example:**
```json
{
"signatureType": "{{SIGNATURE_TYPE}}"
}
```

---

### supportRevocation (Boolean)

Specifies if the credential definition incorporates revocation capabilities.

**Example:**
```json
{
"supportRevocation": "{{BOOLEAN_VALUE}}"
}
```

---

## Conclusion

The Anoncred Credential Definition is a versatile tool that offers a standardized approach for an array of verifiable credentials. By ensuring its correct incorporation within the Atala PRISM Platform, the issuance and validation processes of various credentials can be streamlined and made more efficient.

## References

- [Hyperledger AnonCreds specification](https://hyperledger.github.io/anoncreds-spec/#term:schemas)

**Note:** Throughout the implementation phase within the PRISM platform, it's crucial to replace placeholders (such as `{{CREDENTIAL_NAME}}`, `{{VERSION_NUMBER}}`, and others) with their real, intended values.
14 changes: 14 additions & 0 deletions docs/docusaurus/credentialdefinition/delete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Delete the Credential Definition

Unfortunately, once published (especially in the [Verifiable Data Registry (VDR)](/docs/concepts/glossary#verifiable-data-registry), deleting the credential definition becomes unfeasible.

In the PRISM Platform v2.0, credential definitions aren't published to the VDR. This functionality will be incorporated in subsequent versions of the platform. Hence, the platform currently doesn't provide a REST API for deletion.

If you need to `delete` the credential definition, it's advisable to contact the database administrator or directly remove it from the Postgres instance using its `guid`.

For example:

```sql
DELETE
FROM credential_definition
WHERE guid = '3f86a73f-5b78-39c7-af77-0c16123fa9c2'
Binary file modified docs/docusaurus/credentials/anoncreds-issue-flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 9165a6f

Please sign in to comment.