Skip to content

Commit

Permalink
feat: openid4vc guides
Browse files Browse the repository at this point in the history
Signed-off-by: Timo Glastra <timo@animo.id>
  • Loading branch information
TimoGlastra committed Jun 4, 2024
1 parent 86f6217 commit 7b13eff
Show file tree
Hide file tree
Showing 16 changed files with 710 additions and 16 deletions.
2 changes: 1 addition & 1 deletion guides/getting-started/set-up/cheqd/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,4 @@ The cosmosPayerSeed can be a 32-bit seed value or a mnemonic, which can be manag

- [Cheqd DID Module](../../../tutorials/cheqd/index.md)
- [Register Schema and Credential Definition](../../../tutorials/registering-schema-and-credential-definition.md)
- [Issue a Credential](../../../tutorials/issue-a-credential.md)
- [Issue an AnonCreds Credential over DIDComm](../../../tutorials/issue-an-anoncreds-credential-over-didcomm.md)
37 changes: 37 additions & 0 deletions guides/getting-started/set-up/openid4vc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# OpenID for Verifiable Credentials

The OpenID4VC module provides support for the [OpenID for Verifiable Credentials group of protocols](https://openid.net/sg/openid4vc/) defined under the OpenID Foundation. Currently this includes the [OpenID for Verifiable Credential Issuance](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html), [Self-Issued OpenID Provider v2](https://openid.net/specs/openid-connect-self-issued-v2-1_0.html), and [OpenID for Verifiable Presentations](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html).

For the current supported versions for any of the OpenID4VC protocols, please refer to the [OpenID4VC Feature](../../features/openid4vc.md) page.

The OpenID4VC Module in Credo currently exposes three modules, one for each role in the triangle trust: `OpenId4VcIssuerModule`, `OpenId4VcHolderModule`, and `OpenId4VcVerifierModule`. The issuer and verifier modules are expected to run in a cloud environment, as they require several endpoints to be exposed to the public internet. The holder module can run in a cloud environment or on a mobile device.

### Installing OpenID4VC Module

When using Credo with OpenID4VC you need to install the `@credo-ts/openid4vc` module:

```console
yarn add @credo-ts/openid4vc@^0.5.3
```

### Adding OpenID4VC Modules to the Agent

After installing the dependencies, we can register the the different modules on the agent.

#### Issuer and Verifier

If you want to issue or verify credentials using OpenID for Verifiable Credentials, you can add the `OpenId4VcIssuerModule` and the `OpenId4VcVerifierModule`. These modules can only run on the server, in Node.JS and don't work in a React Native environment. These modules can be added separately, it's not required to use both modules. The set up for the issuer and verifier module can be combined with the set up for the holder module below to support issuance, holding, and verification OpenID4VC flows within the same agent.

In the example we haven't implemented the `credentialRequestToCredentialMapper` method for the issuer module yet, this is covered in the [OpenID4VC Guides](/guides/tutorials/openid4vc).

```typescript showLineNumbers set-up-openid4vc-issuer-verifier.ts section-1

```

### Holder

If you want to receive and present credentials using OpenID for Verifiable Credentials, you can add the `OpenId4VcHolderModule`. This module can run in both Node.JS and React Native.

```typescript showLineNumbers set-up-openid4vc-holder.ts section-1

```
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Issue a credential
# Issue an AnonCreds credential over DIDComm

In this tutorial we will issue a credential from the _Issuer_ to a _Holder_. We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the _Issuer_ and the _Holder_ and the _Issuer_ also has a registered schema and credential definition. After initializing the _Issuer_ will send a credential to the _holder_, and will then accept this credential and automatically store it in their wallet.
In this tutorial we will issue an AnonCreds credential from the _Issuer_ to a _Holder_ over DIDComm. We will start with setting up both their agents with the minimal configuration required to follow this tutorial. It is assumed that there is a connection between the _Issuer_ and the _Holder_ and the _Issuer_ also has a registered schema and credential definition. After initializing the _Issuer_ will send a credential to the _holder_, and will then accept this credential and automatically store it in their wallet.

_Using [AnonCreds](https://anoncreds-wg.github.io/anoncreds-spec/) and the [Issue Credential V2 Protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md) or the [Issue Credential V1 Protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0036-issue-credential/README.md)._

:::info

This section assumes that

1. You have [set-up your develoment environment](../getting-started).
1. You have [set-up your development environment](../getting-started).
1. You have basic knowledge of the required fields in the [Agent Config](./agent-config)
1. You have completed the [Create a Connection tutorial](./create-a-connection)
1. You have a registered schema and credential definition. This can be done by following the [Registering on a AnonCreds Registry](./registering-schema-and-credential-definition)
Expand Down Expand Up @@ -53,7 +53,7 @@ ngrok http <PORT>

:::issuer

```typescript showLineNumbers issue-a-credential.ts section-1
```typescript showLineNumbers issue-anoncreds-credential-didcomm.ts section-1

```

Expand All @@ -70,7 +70,7 @@ For the _Holder_ we need to setup a basic agent with a wallet, mediator, outboun
:::holder

```typescript showLineNumbers issue-a-credential.ts section-2
```typescript showLineNumbers issue-anoncreds-credential-didcomm.ts section-2

```

Expand All @@ -82,7 +82,7 @@ When we want to accept a credential, we have to listen to incoming credentials a

:::holder

```typescript showLineNumbers issue-a-credential.ts section-3
```typescript showLineNumbers issue-anoncreds-credential-didcomm.ts section-3

```

Expand All @@ -100,7 +100,7 @@ Now that everything is setup on both sides, the _Issuer_ can now offer a credent

:::issuer

```typescript showLineNumbers issue-a-credential.ts section-4
```typescript showLineNumbers issue-anoncreds-credential-didcomm.ts section-4

```

Expand All @@ -110,7 +110,7 @@ Now that everything is setup on both sides, the _Issuer_ can now offer a credent

:::issuer

```typescript showLineNumbers issue-a-credential.ts section-5
```typescript showLineNumbers issue-anoncreds-credential-didcomm.ts section-5

```

Expand Down
7 changes: 7 additions & 0 deletions guides/tutorials/openid4vc/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import DocCardList from '@theme/DocCardList';

# OpenID for Verifiable Credentials Tutorials

This section covers all tutorials related to the OpenID for Verifiable Credentials module in Credo. Before you start, make sure you have configured the required OpenID4VC modules on your agent according to the [OpenID4VC Setup Guide](/guides/getting-started/set-up/openid4vc.md)

<DocCardList />
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Issuing Credentials using the OpenID4VC Issuer Module

This tutorial will guide you through the process of issuing credentials using the OpenID4VC Issuer Module. Before starting this tutorial, make sure you have completed the [OpenID4VC Issuer Module Setup](/guides/getting-started/set-up/openid4vc.md).

This guides only covers the issuance of credentials using the OpenID4VC Issuer Module. Follow the [Receiving and Proving Credentials using the OpenID4VC Holder Module](/guides/tutorials/openid4vc/receiving-and-proving-credentials-using-openid4vc-holder-module.md) guide to learn how to receive and prove credentials using the OpenID4VC Holder Module.

## Creating the issuer

Once you have set-up your agent (under `issuer` variable), we first need to configure your issuer and the credentials you want to issue.

```typescript showLineNumbers sd-jwt-vc-openid4vc.ts section-2

```

If you want to update the display metadata or the credentials supported by the issuer, you can use the `issuer.modules.openId4VcIssuer.updateIssuer` method.

## Creating a credential offer

Once you have configured the issuer, you can create a credential offer. The credential offer method will generate a credential offer URI that you can share with a holder.

```typescript showLineNumbers sd-jwt-vc-openid4vc.ts section-3

```

We have also added an event listener that listens for state changed events, this allows us to know when the issuance session is done.

## Implementing the credential mapper

The OpenID4VC Issuer Module setup didn't cover the implementation of the `credentialRequestToCredentialMapper` yet. When you create a credential offer with the OpenID4VC Issuer Module in Credo, you don't have to provide the credential data directly.

Instead, you provide a `credentialRequestToCredentialMapper` function in the agent configuration, that will be called when the holder requests the credential.

This allows you to dynamically generate the credential data based on the holder's request, and means you also don't have to store any credential data in the agent.

Below is an example `credentialRequestToCredentialMapper` function that generates a credential based on the holder's request. Make sure to register this function in the agent configuration `modules.openId4VcIssuer.endpoints.credential.credentialsRequestToCredentialMapper`.

```typescript showLineNumbers sd-jwt-vc-openid4vc.ts section-4

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Receiving and Proving Credentials using the OpenID4VC Holder Module

This tutorial will guide you through the process of receiving and proving credentials using the OpenID4VC Holder Module. Before starting this tutorial, make sure you have completed the [OpenID4VC Holder Module Setup](/guides/getting-started/set-up/openid4vc.md).

This guides only covers the receiving and proving of credentials using the OpenID4VC Holder Module. Follow the [Issuing Credentials using the OpenID4VC Issuer Module](/guides/tutorials/openid4vc/issuing-credentials-using-openid4vc-issuer-module.md) and [Verifying Credentials using the OpenID4VC Verifier Module](/guides/tutorials/openid4vc/verifying-credentials-using-openid4vc-verifier-module.md) guides to learn how to issue and verify credentials using the OpenID4VC Issuer and Verifier Modules.

## Resolving and accepting a credential offer

Once you have set-up your agent (under `holder` variable), and have a credential offer (either created using the issuer module, or an external OpenID4VC issuer), we can resolve and accept the credential offer.

The `credentialBindingResolver` is a method you need to provide that configures how the credential should be bound to the wallet. The implemented binding resolver in this tutorial first checks if the issuer supports `did:key` and will use that. Otherwise it will check if jwk is supported.

```typescript showLineNumbers sd-jwt-vc-openid4vc.ts section-6

```

Finally the credentials are stored using the SD JWT VC and W3C modules. In a wallet application you could choose to first show the credential to the user before storing it in the wallet.

## Resolving and accepting an authorization request (presentation request)

Once you have a credential in your wallet, you can start presenting it based on a receive authorization request including an OpenID4VP presentation request (either created using the verifier module, or an external OpenID4VC verifier). First we resolve the authorization request, and then we accept it and present the credential in our wallet.

```typescript showLineNumbers sd-jwt-vc-openid4vc.ts section-9

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Verifying Credentials using the OpenID4VC Verifier Module

This tutorial will guide you through the process of verifying credentials using the OpenID4VC Verifier Module. Before starting this tutorial, make sure you have completed the [OpenID4VC Verifier Module Setup](/guides/getting-started/set-up/openid4vc.md).

This guides only covers the verification of credentials using the OpenID4VC Verifier Module. Follow the [Issuing Credentials using the OpenID4VC Issuer Module](/guides/tutorials/openid4vc/issuing-credentials-using-openid4vc-issuer-module.md) and [Receiving and Proving Credentials using the OpenID4VC Holder Module](/guides/tutorials/openid4vc/receiving-and-proving-credentials-using-openid4vc-holder-module.md) guide to learn how to issuer, receive and prove credentials using the OpenID4VC Issuer and Holder Modules.

## Creating the verifier

Once you have set-up your agent (under `verifier` variable), we first need to configure your verifier.

```typescript showLineNumbers sd-jwt-vc-openid4vc.ts section-7

```

## Creating an authorization request

Once you have configured the verifier, you can create an authorization request including an OpenID4VP presentation request based on [DIF Presentation Exchange V2](https://identity.foundation/presentation-exchange/spec/v2.0.0/). The authorization request method will generate an authorization request URI that you can share with a holder.

```typescript showLineNumbers sd-jwt-vc-openid4vc.ts section-8

```

We have also added an event listener that listens for state changed events, this allows us to know when the verification session is done.
2 changes: 1 addition & 1 deletion guides/updating/versions/0.2-to-0.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ This procedure can be done in module's `register(dependencyManager, featureRegis

### Ledger Module

Apart from the aforementioned indyLedgers configuration, you should also [note a slight change](../../tutorials/issue-a-credential.md#side-notes) in behaviour when attempting to register credential definitions that already exists on the ledger but not in the wallet.
Apart from the aforementioned indyLedgers configuration, you should also [note a slight change](../../tutorials/issue-an-anoncreds-credential-over-didcomm.md#side-notes) in behaviour when attempting to register credential definitions that already exists on the ledger but not in the wallet.

### Proofs Module

Expand Down
2 changes: 1 addition & 1 deletion guides/updating/versions/0.4-to-0.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ await agent.modules.openId4VcHolder.acceptCredentialOfferUsingPreAuthorizedCode(
// NOTE: example implementation. Adjust based on your needs
// Return the binding to the credential that should be used. Either did or jwk is supported

if (supportsAllDidMethods || supportedDidMethods?.include('did:key')) {
if (supportsAllDidMethods || supportedDidMethods?.includes('did:key')) {
const didResult = await agent.dids.create<KeyDidCreateOptions>({
method: 'key',
options: {
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@
"devDependencies": {
"@docusaurus/module-type-aliases": "^2.3.1",
"@tsconfig/docusaurus": "^1.0.5",
"prettier": "^2.7.1",
"typescript": "^4.6.4",
"@types/node": "18",
"ts-node": "^10.8.1"
"prettier": "^2.7.1",
"ts-node": "^10.8.1",
"typescript": "^4.6.4"
},
"browserslist": {
"production": [
Expand Down
14 changes: 13 additions & 1 deletion sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const sidebars = {
'getting-started/set-up/anoncreds',
'getting-started/set-up/indy-vdr',
'getting-started/set-up/cheqd/index',
'getting-started/set-up/openid4vc',
],
},
],
Expand Down Expand Up @@ -65,8 +66,18 @@ const sidebars = {
'tutorials/create-a-connection',
'tutorials/cheqd/index',
'tutorials/registering-schema-and-credential-definition',
'tutorials/issue-a-credential',
'tutorials/issue-an-anoncreds-credential-over-didcomm',
'tutorials/mediation',
{
type: 'category',
label: 'OpenID for Verifiable Credentials',
link: { type: 'doc', id: 'tutorials/openid4vc/index' },
items: [
'tutorials/openid4vc/issuing-credentials-using-openid4vc-issuer-module',
'tutorials/openid4vc/receiving-and-proving-credentials-using-openid4vc-holder-module',
'tutorials/openid4vc/verifying-credentials-using-openid4vc-verifier-module',
],
},
],
},
{
Expand All @@ -79,6 +90,7 @@ const sidebars = {
'updating/versions/0.1-to-0.2',
'updating/versions/0.2-to-0.3',
'updating/versions/0.3-to-0.4',
'updating/versions/0.4-to-0.5',
],
},
'ecosystem/index',
Expand Down
3 changes: 2 additions & 1 deletion snippets/current/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"dev:mediator-setup": "ts-node --esm src/mediator-setup.ts",
"dev:mediation-recipient": "ts-node --esm src/mediation-recipient.ts",
"dev:connection": "ts-node --esm src/create-a-connection.ts",
"dev:credential": "ts-node --esm src/issue-a-credential.ts",
"dev:issue-anoncreds-credential-didcomm": "ts-node --esm src/issue-anoncreds-credential-didcomm.ts",
"dev:openid4vc": "ts-node --esm src/sd-jwt-vc-openid4vc.ts",
"dev:register-with-indy": "ts-node --esm src/register-schema-and-cred-def.ts",
"dev:set-up": "ts-node --esm src/set-up.ts"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ holder.events.on<CredentialStateChangedEvent>(CredentialEventTypes.CredentialSta
console.log('received a credential')
// custom logic here
await holder.credentials.acceptOffer({ credentialRecordId: payload.credentialRecord.id })
break
case CredentialState.Done:
console.log(`Credential for credential id ${payload.credentialRecord.id} is accepted`)
// For demo purposes we exit the program here.
Expand Down
Loading

0 comments on commit 7b13eff

Please sign in to comment.