Skip to content

Commit

Permalink
feat: Add OID4VCI frontend demo
Browse files Browse the repository at this point in the history
  • Loading branch information
nklomp committed Jun 27, 2023
1 parent 7e83267 commit fa7e208
Show file tree
Hide file tree
Showing 112 changed files with 8,678 additions and 329 deletions.
167 changes: 127 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,80 +1,167 @@
<h2 style="text-align: center; vertical-align: middle">
<center><a href="https://www.sphereon.com"><img src="https://sphereon.com/content/themes/sphereon/assets/img/logo.svg" alt="Sphereon" width="320" style="vertical-align: middle" ></a></center>

<br>SIOPv2 and OID4VP Example/Demo Environment
<br>OID4VC Issuer and Verifier Demo
<br>
<br>
</h2>

#### This is a demo to showcase our ["Self Issued OpenID Provider v2 and OID4VP" library](https://github.com/Sphereon-Opensource/siopv2-openid4vp).
#### This is a demo to showcase our OpenID for Verifiable Credentials libraries and components.

**NOTE: Please note, this is not intended as production code.
It is a quite simple implementation to show how the SIOPv2 and OpenID4VP technology works.**
**Please note that this is not intended as production code. It is a relative simple implementation to show how the
OID4VC technologies, SIOPv2 (peer to peer authentication), OID4VP (Verification), OID4VCI (Issuance) end Presentation
Exchange (requirements by verifiers) work.**

### Getting started
The demo consists of 3 components, which can be found in the packages folder.

- The agent using our [SSI-SDK](https://github.com/Sphereon-OpenSource/SSI-SDK), responsible for key-management, DIDs,
Presentation Exchange storage, Issuer Metadata Storage, as well as
actual issuance and verification of Credentials. It can handle multiple issuer configurations as well as
Verifiers/Presentation definitions at the same time, although the frontends only will use one
- A Demo Issuer frontend, allowing you to fill out a simple form, or using a wallet, to supply some information, which
then will be used to issue a credential containing that information. This code can be exported and run on a regular
webserver if you want. It is a frontend communicating with the agent, using some of our OID4VC SSI-SDK plugins.
- A Demo Verifier frontend, allowing you to verify the Credential issued by the agent (the demo issuer, also contains
similar functionality if you would follow the wallet flow btw). Be aware that we will replace this demo frontend with
something a bit more appealing soon.

The Demo is using code from our [SSI-SDK](https://github.com/Sphereon-OpenSource/SSI-SDK), providing 11 modules for
OID4VC, QR code generation, as well as Issuance branding. Integrating these technologies with a Key Management System,
DID methods etc. The OID4VC modules in the SDK in turn are using our less opinionated lower-level
libraries, allowing people to integrate OID4VC functionalities that do not desire full agent functionality, or have
their own agent support, like for
instance [Aries Framework Javascript](https://github.com/hyperledger/aries-framework-javascript).
Obviously integrating the low-level libraries will be a bit more work, but does bring flexibility.
The most prominent low-level libraries are:

- [OpenID for Verifiable Credential Issuance (client and issuer library)](https://github.com/Sphereon-Opensource/OID4VCI)
- [Self Issued OpenID v2 and OpenID for Verifiable Presentations](https://github.com/Sphereon-Opensource/SIOP-OID4VP)
- [Presentation Exchange v1 and v2](https://github.com/Sphereon-Opensource/PEX)

## Wallet Prerequisites

You will need an OID4VC capable wallet, that supports SIOPv2, OID4VP, OID4VCI and Presentation Exchange. You can use our
Open-Source wallet from the stores. See https://github.com/Sphereon-OpenSource/ssi-mobile-wallet

## Issuer demo

If you run `pnpm run start:dev` the Issuer frontend, the verifier frontend and the agent will be started. Your browser
should automatically
open https://localhost:5001. You can also go to https://ssi.sphereon.com/demo/issuer, for an online hosted
demo. https://ssi.dutchblockchaincoalition.org/demo/issuer hosts a different integration/use case.

You should be greeted with the introduction screen

<img src="resources/issuer-demo-intro.png" width="500">

There are 2 flows. One is a manual flow, where you will fill out some information (the information will not be
shared/stored) in order to receive a credential. The other flow is using your wallet to request the information
required (SIOPv2/OID4VP). Obviously the demo is having a few more screens than strictly necessary, just to show the
different steps involved.

The flow should be pretty self-explanatory. In the end your wallet should end up with a credential-offer that you can
accept or decline:

<img src="./resources/Wallet_Credential_offer.jpg" alt="Wallet credential offer" width="300px"/>

## Verifier demo

Next to the Issuer frontend, the verifier frontend will also be started with the `pnpm run start:dev` command. Your
browser
should automatically
open https://localhost:5002. You can also go to https://ssi.sphereon.com/demo/verifier, for an online hosted
demo. https://dutchblockchaincoalition.org/userLogin hosts an integration into the DBC website and Craft CMS.

You should be greeted with the introduction screen

<img src="resources/start-screen.png" width="500px"/>


Click "Sign in"
A QR code will appear which can be scanned with the mobile SIOPv2/OID4VP OP authenticator module from our SSI-SDK.

<img src="resources/login-qr-screen.png" width="500px"/>

It will ask for a certain type of credential, you should now have in your wallet

<img src="./resources/Wallet_Credential_Verifier.jpg" alt="Wallet credential Verifier" width="300px"/>

Once the SIOP accepts the receipt of the Presentation Definition the screen will change to:

<img src="resources/login-wait-def-screen.png" width="500px"/>

As soon as the SIOP sends in the Verifiable Presentation that conforms to the definition the SIOP will be authenticated:

<img src="resources/vp-received-screen.png" width="500px"/>

Note the Information in the top left corner which actually comes from the Verifiable Credential sent by the SIOP.

## Developers

#### Configure environment

In the `./packages/agent folder`, update the file called .env and populate it using .env as example. A valid
config will look like this
In the `./packages/agent`, `./packages/oid4vci-demo-frontend`, `./packages/oid4vp-demo-frontend` directories copy the
file called .env to .env.local and populate it using .env as example. A valid
config will look like below. Not all properties are listed.

**agent .env.local**

```dotenv
NODE_ENV=development
PORT=3002
COOKIE_SIGNING_KEY=8E5er6YyAO6dIrDTm7BXYWsafBSLxzjb
BACKEND_BASE_URI=https://backend.example.com
OID4VP_AGENT_BASE_URI=https://backend.example.com
AUTH_REQUEST_EXPIRES_AFTER_SEC=180
NODE_ENV=local
HOSTNAME=0.0.0.0 # bind to all network adapters
PORT=5000 # The port to use
DB_ENCRYPTION_KEY=29739248cad1bd1a0fc4d9b75cd4d2990de535baf5caadfdf8d8f86664aa830c # The key used to encrypt certain database fields
OID4VP_ENABLED="true" # Whether to enable OpenID for Verifiable Presentations
OID4VP_WEBAPP_BASE_URI=http://192.168.2.90:5000 # The base URL of the webapp. This will be communicated in the QR code. Please use an IP or hostname that is resolvable from your wallet
OID4VP_AGENT_BASE_URI=http://192.168.2.90:5000 # The base URL of the agent. Please use an IP address, or hostname that is resolvable from you wallet
AUTH_REQUEST_EXPIRES_AFTER_SEC=180 # How long to keep a session alive. You need to finish the auth with a certain QR code /deeplink in this time
CONF_PATH="./my-config-path" #Allows you to set a custom configuration path
```

Except for the IP address/hostname in the `BACKEND_BASE_URI` and `OID4VP_AGENT_BASE_URI` this is a valid configuration to test with. You will need to replace it with the public IP
interface/address or ideally hostname where the
backend will be running and make sure it is accessible from your phone and the port is open in the firewall.
**oid4vci-demo-frontend .env.local**

#### Update REACT_APP_BACKEND_BASE_URI in frontend .env
Update the REACT_APP_BACKEND_BASE_URI value in .env or a new .env.local file in the `packages/frontend` directory
It should have the same value as the `BACKEND_BASE_URI` above
```dotenv
REACT_APP_OID4VP_AGENT_BASE_URL=http://192.168.2.90:5000 # The ip/hostname and port where the frontend will contact the agent
REACT_APP_OID4VP_PRESENTATION_DEF_ID=sphereon # The presentation definition ID as recognized by the SSI-SDK agent verifier
REACT_APP_OID4VCI_AGENT_BASE_URL='http://192.168.2.90:5000/sphereon2023' # The base url of the SSI-SDK agent. The agent can support multiple VCI issuers at the same time depending on their config
REACT_APP_ENVIRONMENT=sphereon # The branding and built in credential defnitions and metadata to use. Supported values: sphereon, dbc, triall, fmdm
PORT=5001 # The port to use when running pnpm run start:dev. Please note that you can also build the project, and host it on a regular webserver.
```

**openid4vp-demo-frontend .env.local**

```dotenv
REACT_APP_QR_CODE_EXPIRES_AFTER_SEC=300 # How long with the authentication session be valid
REACT_APP_PRESENTATION_DEF_ID=sphereon2023 # The presentation definition ID supported by the SSI-SDK agent (the agent can support multiple definitions)
REACT_APP_BACKEND_BASE_URI=http://192.168.2.90:5000 # The base URL of the agent, needs to be resolvable by the wallet!
PORT=5002 # The port to use when running pnpm run start:dev. Please note that you can also build the project, and host it on a regular webserver.
```

#### Build & start

We use pnpm. Currently you cannot use regular npm or yarn to build this project!
install pnpm globally using `npm -g install pnpm`

From the root directory

- pnpm install
- pnpm build
- pnpm start:dev

The server will start on port 5000, the client will start & open a browser on http://localhost:3000/
The server will start on port 5000, the client will start & open a browser on http://localhost:5001/ for the issuer
and https://localhost:5002 for the verifier

#### Usage

Once the demo site has loaded, you should see the following screen:

![/resources/start-screen.png](/resources/start-screen.png)

Click "Sign in"
A QR code will appear which can be scanned with the mobile OP authenticator module from our SSI-SDK.

![login-qr-screen.png](resources/login-qr-screen.png)

Once the SIOP accepts the receipt of the Presentation Definition the screen will change to:
![login-wait-def-screen.png](resources/login-wait-def-screen.png)

As soon as the SIOP sends in the Verifiable Presentation that conforms to the definition the SIOP will be authenticated:
![login-wait-def-screen.png](resources/vp-received-screen.png)

Note the Information in the top left corner which actually comes from the Verifiable Credential sent by the SIOP.

app "[rn-did-siop-example-app](https://github.com/Sphereon-OpenSource/rn-did-siop-example-app)"
After a successful login two extra page will appear in the menu navigation.

#### Docker

From the root folder run:

```bash
docker build -t siopv2-oid4vp-example .
docker run -it -p 5001:5001 -p 3000:3000 onto-web-demo
docker build -t sphereon-oid4vci-demo .
docker run -it -p 5000:5000 -p 5001:5001 -p 5002:5002 sphereon-oid4vci-demo
```

### Docker compose
Expand Down
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ services:
dockerfile: ./Dockerfile
ports:
- 5001:5001
- 5002:5002
- 3000:3000
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"clean": "rimraf --glob **/dist **/coverage **/pnpm-lock.yaml packages/**/node_modules node_modules packages/**/tsconfig.tsbuildinfo",
"test": "pnpm run test",
"start:dev": "pnpm -r --stream start:dev",
"start": "pnpm -r --stream start:prod",
"start:prod": "pnpm -r --stream start:prod",
"publish:latest": "lerna publish --conventional-commits --include-merged-tags --create-release github --yes --dist-tag latest --registry \"https://registry.npmjs.org/:_authToken=${NPM_TOKEN}\"",
"publish:next": "lerna publish --conventional-prerelease --force-publish --canary --no-git-tag-version --include-merged-tags --preid next --pre-dist-tag next --yes --registry \"https://registry.npmjs.org/:_authToken=${NPM_TOKEN}\"",
"publish:unstable": "lerna publish --conventional-prerelease --force-publish --canary --no-git-tag-version --include-merged-tags --preid unstable --pre-dist-tag unstable --yes --registry \"https://registry.npmjs.org/:_authToken=${NPM_TOKEN}\""
Expand Down
2 changes: 1 addition & 1 deletion packages/agent/.env
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ OID4VP_ENABLED="true"
OID4VP_WEBAPP_BASE_URI=http://192.168.2.90:5000
OID4VP_AGENT_BASE_URI=http://192.168.2.90:5000
AUTH_REQUEST_EXPIRES_AFTER_SEC=180
OID4CI_ENABLED="true"
OID4VCI_ENABLED="true"

CONF_PATH="./conf"
UNIVERSAL_RESOLVER_RESOLVE_URL="https://dev.uniresolver.io/1.0/identifiers"
148 changes: 148 additions & 0 deletions packages/agent/conf-examples/oid4vci_metadata/sphereon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
{
"correlationId": "http://192.168.2.90:5000/sphereon2023",
"overwriteExisting": true,
"metadata": {
"credential_issuer": "http://192.168.2.90:5000/sphereon2023",
"credential_endpoint": "http://192.168.2.90:5000/sphereon2023/credentials",
"display": [
{
"name": "Sphereon International",
"description": "Sphereon International"
}
],
"credentials_supported": [
{
"display": [
{
"name": "Sphereon guest",
"description": "Sphereon guest credential for demo purposes.",
"text_color": "#FFFFFF",
"background_image": {
"url": "https://i.ibb.co/kmfrH4F/tulips.png",
"alt_text": "Black and white photo of tulips with one red tulip"
},
"logo": {
"url": "https://i.ibb.co/NWQQ9kt/sphereon-logo.png",
"alt_text": "Red square depicting Sphereon logo."
}
},
{
"locale": "en-US",
"name": "Sphereon guest",
"description": "Sphereon guest credential for demo purposes.",
"text_color": "#FFFFFF",
"background_image": {
"url": "https://i.ibb.co/kmfrH4F/tulips.png",
"alt_text": "Black and white photo of tulips with one red tulip"
},
"logo": {
"url": "https://i.ibb.co/NWQQ9kt/sphereon-logo.png",
"alt_text": "Red square depicting Sphereon logo."
}
},
{
"locale": "nl-NL",
"name": "Sphereon gast",
"description": "Sphereon gast credential wordt uitgegeven voor demo doeleinden.",
"text_color": "#FFFFFF",
"background_image": {
"url": "https://i.ibb.co/kmfrH4F/tulips.png",
"alt_text": "Black and white photo of tulips with one red tulip"
},
"logo": {
"url": "https://i.ibb.co/NWQQ9kt/sphereon-logo.png",
"alt_text": "Red square depicting Sphereon logo."
}
}
],
"order": [
"firstName",
"lastName",
"email",
"type"
],
"credentialSubject": {
"firstName": {
"value_type": "string",
"display": [
{
"name": "FirstName"
},
{
"name": "FirstName",
"locale": "en-US"
},
{
"name": "Voornaam",
"locale": "nl-NL"
}
]
},
"lastName": {
"value_type": "string",
"display": [
{
"name": "LastName"
},
{
"name": "LastName",
"locale": "en-US"
},
{
"name": "Achternaam",
"locale": "nl-NL"
}
]
},
"email": {
"value_type": "string",
"display": [
{
"name": "Email"
},
{
"name": "Email",
"locale": "en-US"
},
{
"name": "Email",
"locale": "nl-NL"
}
]
},
"type": {
"value_type": "string",
"display": [
{
"name": "Type"
},
{
"name": "Type",
"locale": "en-US"
},
{
"name": "Type",
"locale": "nl-NL"
}
]
}
},
"id": "sphereon2023",
"types": [
"VerifiableCredential",
"GuestCredential"
],
"format": "jwt_vc_json",
"cryptographic_binding_methods_supported": [
"did:web",
"did:jwk"
],
"cryptographic_suites_supported": [
"ES256",
"ES256K",
"EdDSA"
]
}
]
}
}
9 changes: 9 additions & 0 deletions packages/agent/conf-examples/oid4vci_options/sphereon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"definitionId": "sphereon2023",
"correlationId": "http://192.168.2.90:5000/sphereon2023",
"issuerOpts": {
"didOpts": {
"checkLinkedDomains": "if_present"
}
}
}
8 changes: 8 additions & 0 deletions packages/agent/conf-examples/oid4vp_options/sphereon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"definitionId": "sphereon2023",
"rpOpts": {
"didOpts": {
"checkLinkedDomains": "if_present"
}
}
}
Loading

0 comments on commit fa7e208

Please sign in to comment.