Only this pageAll pages
Powered by GitBook
1 of 66

IDP Kit

What is the IDP Kit?

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Getting started

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Demos

Tutorials

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Configuration and Setup

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Concepts

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Community

DEVELOPER RELATIONS

Product Editions

Loading...

Loading...

Loading...

Functionality

The IDP Kit makes it easy for you to build and launch your own OIDC compliant identity provider utilizing SSI, NFTs or Sign-In with Ethereum to obtain identity data.

Depending on your requirements the IDP Kit can be configured to map data from verifiable credentials or NFTs to standard OIDC claims (e.g. OIDC profile scope), or to deliver the presented credentials, NFTs or account addresses as they are via the custom vp_token and nft_token siwe claims.

The following overview summarizes the basic features of the IDP Kit:

  • OIDC

    • Standard OIDC protocol support, when interfacing with end user applications

    • Support for OIDC scopes like profile, address, email, and standard claims

      • Support for custom vp_token and nft_token claims, to allow client applications to request credential or nft token data from the user

    • Support for various OIDC flows, including code flow, implicit flow and hybrid flows

    • Support for OIDC auto discovery via well-known endpoint for OpenID provider metadata

  • SSI

    • Credential presentation exchange with SSI wallets via the OIDC/SIOPv2 protocol

    • Verification of credential and presentation signatures, challenges and compliance with the presentation request

      • Pluggability of additional verification policies

      • Support for custom verification policies

  • NFTs

    • NFT metadata exchange with NFT wallets such as MetaMask

    • Verification of NFT collections and traits

  • Sign-In with Ethereum

    • Get account addresses from wallets such as MetaMask

    • Verify ownership of the address

  • Claims and claim mapping

    • Support for mapping credential and NFT data to standard OIDC claims and scopes

    • Custom vp_token claim to propagate the verified presentation including all required credentials to the end user application as user info

    • Custom nft_token claim to propagate verified NFT metadata, such as collection membership and token traits, to the end user application as user info

    • Custom siwe claim to propagate verified addresses to the end user application as user info

  • Client authentication

    • Configuration of client IDs, client secrets and redirect uri, to enforce client authentication (via client_secret_basic mode)

    • Dynamic client registration

  • Signature types

    • Support for RS256, EdDSA and ES256K key and signature types, for signing tokens

    • Publishing of public keys on standard OIDC JWK set endpoint, to enable clients to verify token signatures

Introduction

Compatibility Notice & Updates

This documentation will help you understand how the IDP Kit works and how you can use it.

The IDP Kit is built on top of our SSI and NFT software stacks, including the SSI Kit, the Wallet Kit and the NFT Kit, so

  • if you are new to SSI, NFTs or our software stacks, you may want to start with the documentation of the individual concepts and stack components:

IDP Kit

This section elaborates the theory behind the IDP Kit:

Please note that the IDP-Kit currently only works with the , and , but is not yet compatible with our new products under . We plan to update the IDP-Kit to be fully compatible with the new stack by end of Q1 2024.

if you are already familiar with SSI, NFTs, SSI Kit, Wallet Kit and NFT Kit, you can jump right to the .

- Learn what the IDP Kit is and what it does.

- Explore the architecture and components.

- Explore all features in an overview list

SSI-Kit
Wallet-Kit
NFT-Kit
The Community Stack
introduction of the IDP Kit
SSI - Self Sovereign Identity
NFTs - Non-Fungible Tokens
SSI Kit
Wallet Kit
NFT Kit
IDP Kit Basics
Architecture
Feature List

Architecture

The IDP Kit is built on top of the Wallet Kit, providing the SSI credential verification and SIOP protocol logic and the SSI Kit, providing basic functionality with regards to credential and key management, as well as the NFT Kit for verification of NFTs and interaction with blockchain APIs.

It provides APIs for OIDC-clients to connect and initiate user authentication, as well as the SIOP APIs and NFT verification APIs for communication with the SSI and NFT wallets.

The following picture shows the overall architecture of the IDP Kit:

Dependency (JVM)

The IDP Kit can also be used as direct dependency for JVM-based applications. In this case, an existing application can be easily extended to act as an identity provider.

The following illustrates how the IDP Kit can be used via Gradle:

Repositories

maven("https://maven.walt.id/repository/waltid/")

maven("https://maven.walt.id/repository/waltid-ssi-kit/")

Dependency

implementation("id.walt:waltid-idpkit:<version>")

The code-base as well as more detailed instructions can be found at GitHub

https://github.com/walt-id/waltid-idpkit
Intro IDP-Kit
IDP Architecture

Docker

Run IDP Kit docker container

If you want to quickly try out the latest build of the IDP Kit and connect your web application to it, you can simply run the docker container and configure your application's OIDC client library to connect to it.

Edit the configuration files in waltid-idpkit/config according to your needs and run the container like so:

cd waltid-idpkit
docker run -p 8080:8080 -e WALTID_DATA_ROOT=/data -v $PWD:/data waltid/idpkit run

Now you may open your browser on the exposed swagger documentation to browse and try out the REST APIs:

http://localhost:8080/api/swagger

... or configure your application to read the IDP settings from the well-known OpenID configuration endpoint:

http://localhost:8080/api/oidc/.well-known/openid-configuration

To understand the necessary configuration before running the service, consult the section .

IDP Kit setup and configuration

REST APIs

Installation & Running the Project

Make sure you have Docker or a JDK 16 build environment including Gradle installed on your machine

To get info about available options of the run command, use:

waltid-idpkit run --help

Binding address and port

API services

  • OIDC API is available under the context path /api/oidc/

  • SIOP API is available under the context path /api/siop/

Swagger API documentation

A swagger documentation of all exposed APIs is available under /api/swagger

Publicly deployed API documentation

IDP Kit Setup

Intro

Before you start with the project setup, make sure you have the following dependencies on your local machine:

Getting Started

For running the project, you have two options: Docker or Gradle.

  1. Cloning the project

2. Changing directory

3. Open the project in your feavourite IDEA

5. Building the project

6. Creating an alias (optional)

  1. Cloning the project

2. Changing directory

3. Open the project in your feavourite IDEA

4. Building the project

5. Creating an alias (optional)

Running the IDP-Kit Frontend The frontend with which the user will interact to authenticate by doing a connect wallet.

Change into the frontend directory

Install dependencies using node v.16

Running the project

Run NFT-Kit JS (if ecosystem of your NFTs is not Ethereum or Polygon)

  1. Cloning the project

2. Changing directory

3. Run the following command

4. Run the following command

3. Run project

  1. Cloning the project

git clone https://github.com/walt-id/waltid-idpkit.git

2. Changing directory

cd waltid-idpkit

3. Building the project

docker build --rm -t waltid/idpkit .

4. Creating an alias (optional)

alias waltid-idpkit="docker run -p 8080:8080 -e WALTID_DATA_ROOT=/data -v $PWD:/data waltid/idpkit"

5. Running the project (with alias)

waltid-idpkit run

6. Running the project (without alias)

docker run -p 8080:8080 -e WALTID_DATA_ROOT

7. Configure the IDP Kit to your needs

  1. Cloning the project

git clone https://github.com/walt-id/waltid-idpkit.git

2. Changing directory

cd waltid-idpkit

3. Building the project

./gradlew build install

4. Creating an alias (optional)

alias waltid-idpkit="build/install/waltid-idpkit/bin/waltid-idpkit"

5. Running the project (with alias)

waltid-idpkit run

6. Running the project (without alias)

build/install/waltid-idpkit/bin/waltid-idpkit run

7. Configure the IDP Kit to your needs

For more build options, please refer to the

Refer to , to find out details about binding address and port on which the REST APIs are exposed.

You can find the publicly deployed API documentations for our :

Rolling deployment:

Stable deployment:

4. Create a walt.yaml file in the root directory of the project. Values needed are described in the .

4. Create a walt.yaml file in the root directory of the project. Values needed are described in the .

You also need to run the NFT Kit JS, if your NFT collection is not hosted on the Ethereum or Polygon network. Per default, the project will be run under "". We will need that in the .

IDP Kit configuration and setup
IDP Kit configuration and setup
build section
IDP Kit setup and configuration
stable and rolling deployments
https://idp.walt-test.cloud/api/swagger
https://idp.walt.id/api/swagger
git clone https://github.com/walt-id/waltid-idpkit.git
cd waltid-idpkit
./gradlew build install
alias idpkit="build/install/waltid-idpkit/bin/waltid-idpkit"
git clone https://github.com/walt-id/waltid-idpkit.git
cd waltid-idpkit
docker build --rm -t waltid/idpkit .
alias idpkit="docker run -p 8080:8080 -e WALTID_DATA_ROOT=/data -v $PWD:/data waltid/idpkit"
cd web/waltid-idpkit-ui/
yarn install 

or 

npm install
yarn dev

or 

npm run dev
git clone https://github.com/walt-id/waltid-nftkit.git
cd waltid-nftkit/js
npm install
 npm i --save-dev @types/bn.js
npm start
JDK 16 build environment
Gradle
configuration section
configuration section
NFT collection configuration
http://localhost:3000

Quick Start

The IDP-Kit's latest version is broken. We are currently looking into the issue.

There are different ways to get started with the IDP Kit:

Demos

Tutorials

Please , if you need any immidate support.

: The IDP Kit comes with a to e.g conveniently configure the IDP key among other configuration options.

: Discover the endpoints available to build your solution.

: The IDP Kit can be used directly as for Maven or Gradle.

If you just want to try out the IDP Kit, you may directly use our , which don't require any configuration or build environment.

- Mint a NFT and log into our demo walt.id membership page.

reach out
CLI tool
command-line interface
REST APIs
Dependency (JVM)
JVM-dependency
public deployments
Try Login with NFTs
Login with NFTs | Next.js
Login with NFTs | Keycloak
Login with SSI | Next.js

IDP Kit | Basics

The IDP Kit enables you to launch an OIDC compliant identity provider that utilizes the OIDC-SIOPv2 protocol and/or NFT blockchain APIs to retrieve identity data or NFT metadata via a suitable wallet, providing the data as user info and/or mapping it to standard OIDC claims.

This enables applications, that already support OIDC-based authentication, to connect to SSI, NFT wallets or leverage Sign-in with Ethereum (EIP-4361), where users act as self-issued identity providers, with minimum effort, which in the simplest case could involve nothing more than a configuration change.

Simple authentication flow with IDP Kit

The following picture shows a simple OIDC authentication flow between the end user application and the IDP Kit:

Identity federation via an external identity and access manager

The IDP Kit can be configured as a federated identity provider, with other Identity and Access Management systems, such as KeyCloak, as shown in the picture below:

Login with NFTs | Keycloak

Let your users authenticate in a Next.js app with NFTs.

🤟 Welcome

In this tutorial, we create our own instance of the IDP Kit locally and configure it to check users which want to authenticate for being an owner of a chosen NFT collection. We will register a client and connect it to Keycloak.

NFT collections can be hosted on the following ecosystems:

  • Ethereum

  • Polygon

  • Tezos

  • Near

  • Polkadot

  • Flow

🗂 Modules

📽️ Video Version

Public deployments

We operate the IDP Kit as a public service, in a stable and rolling deployment, for demo and trial purposes only.

The deployed services are not meant for production use and no guarantee for availability and data integrity is given.

Stable deployment

The stable deployment is updated manually whenever a stable release build is ready:

Rolling deployment

A deployment of the bleeding edge developments is updated in a rolling fashion on every successful build of the main branch of the IDP Kit project.

This deployment should not be considered stable and should not be used for demo purposes, unless you want to try out a bleeding edge feature, that is not yet available in the stable deployment.

The rolling deployment is available for demo and trial at:

Next.js

Intro

Create the frontend app

  1. Clone the project

git clone https://github.com/walt-id/waltid-nft-auth-nextjs.git

2. Install the dependencies by running yarn install or npm install

4. Rename .env.example to .env

5. In pages/api/auth/[...nextauth].ts we update the identityProviderURL parameter of the NFTProvider. We can leave the third parameter in the NFTProvider as is, if you have not changed the port on which the IDP Kit is running locally. When you switch the port or use a hosted version of the IDP Kit, you need to update the parameter to reflect the new endpoint of the IDP Kit.

6. Now the project is set up and can be run

yarn dev

//  or 

npm run dev

IDP Kit Setup

Intro

Before you start with the project setup, make sure you have the following dependencies on your local machine:

Getting Started

For running the project, you have two options: Docker or Gradle.

  1. Cloning the project

2. Changing directory

3. Open the project in your feavourite IDEA

5. Building the project

6. Creating an alias (optional)

  1. Cloning the project

2. Changing directory

3. Open the project in your feavourite IDEA

4. Building the project

5. Creating an alias (optional)

Running the IDP-Kit Frontend The frontend with which the user will interact to authenticate by doing a connect wallet.

Change into the frontend directory

Install dependencies using node v.16

Running the project

Run NFT-Kit JS (if ecosystem of your NFTs is not Ethereum or Polygon)

  1. Cloning the project

2. Changing directory

3. Run the following command

4. Run the following command

3. Run project

CLI | Command Line Interface

The IDP Kit provides a simple command line interface, to run and/or configure the service.

In the following sections I will show examples using the command line interface of the IDP Kit.

For the sake of readability, I will shortcut the executable command as:

waltid-idpkit

Installation & Running the Project

Make sure you have Docker or a JDK 16 build environment including Gradle installed on your machine

To get info about available options of the run command, use:

waltid-idpkit run --help

Configuration

For configuring keys and managing verification policies, the IDP Kit integrates some commands from the SSI Kit for key and policy management.

The config command lets you define the context in which you want to execute the command, by specifying the arguments --oidc, --siop, before the respective subcommand.

E.g.

This command lists the keys available in the context of the OIDC manager.

This command lists the verification policies available in the context of the SIOP manager.

To get info about available options of the config command, use:

waltid-idpkit config --help

Build

Docker

To quickly start up the IDPKit using Docker, refer to:

Or continue on the next section, for building and running the IDP Kit on your local development environment.

Local build

To build and run the IDP Kit on your local development environment, make sure to set up your machine with these requirements:

  • JDK 16+

  • NodeJS 18 with Yarn

Project structure

The IDP Kit is structured into a backend (main) and frontend project.

IDP Kit backend

The project is written in Kotlin and compiled for JVM 16+. The build project is set up using Gradle.

IDP Kit frontend

The web UI, which provides the wallet connect and cross-device credential exchange web interfaces, is written in Nuxt.js and set up as a NodeJs/Yarn project.

Backend build

To build the IDP Kit backend, use the gradle wrapper script, which automatically sets up a local installation of gradle and runs the build:

./gradlew build

Alternatively use the build and run functionality of your IDE. We use IntellJ IDEA to build, run and test the project.

Frontend build

To build the frontend, navigate into its subfolder:

cd web/waltid-idpkit-ui

Install the required dependencies, using yarn:

yarn install

Run the dev server, if you're developing:

yarn dev

Or, generate the production build output:

yarn generate

Development build configuration

To run the IDP Kit in a development environment, you need to start both the backend and the frontend services.

Check the following configuration and possibly adapt it to your needs:

Nuxt config

File: web/waltid-idpkit-ui/nuxt.config.js:

Look for the proxy section near the end of the configuration file.

Make sure the host and port mapping of the API paths, corresponds to the host and port, on which the IDP Kit backend is running.

Typically this section will look like this:

Configure the port on which the frontend should be started, by using the server section like this:

IDP config

File: config/idp-config.json:

Let the externalUrl point to an address on which the IDP Kit frontend service is running and reachable from a browser.

E.g.:

Verifier config

File: config/verifier-config.json:

Set the verifierApiUrl to a URL on which the IDP Kit backend is listening, and that is reachable from a browser.

Set the url of the walt.id wallet configuration to the web wallet, which should be used. By default, this is pointing to the wallet deployed on walt-test.cloud.

e.g.:

The IDP Kit uses the OIDC authentication flow, the same technology used by Sign-in with Apple, Facebook, Twitter and many more. If you want to learn more about it and how it works behind the scenes, you can have a look at our as well as how the ideas are translated when using .

- Build and run the project in your local environment

- Retrieve clientId and clientSecret from the IDP Kit, used by Keycloak

- Set NFT collection required by the users to login successfully

- Register IDP-Kit as external Identity Provider with Keycloak

- Use Keycloak in a Next.js application (optional)

You can also watch the full tutorial .

We have prepared a which we can use as a starting point. It uses NextAuth.js for handling authentication and a custom provider build by to connect the IDP Kit easily with NextAuths functionality. We won't go into details of how Next.js or NextAuth.js works.

The user of the frontend application needs or another to share their blockchain address, with which the IDP Kit will be able to check if the user is holder of the required NFT collection.

We will need and or npm

3. Update CLIENT_ID and CLIENT_SECRET based on the response returned by the in the .env.example file.

7. When we visit and press the login button, the authentication is started.

4. Create a walt.yaml file in the root directory of the project. Values needed are described in the .

4. Create a walt.yaml file in the root directory of the project. Values needed are described in the .

You also need to run the NFT Kit JS, if your NFT collection is not hosted on the Ethereum or Polygon network. Per default, the project will be run under "". We will need that in the .

  1. Cloning the project

2. Changing directory

3. Building the project

4. Creating an alias (optional)

5. Running the project (with alias)

6. Running the project (without alias)

7. Configure the IDP Kit to your needs

  1. Cloning the project

2. Changing directory

3. Building the project

4. Creating an alias (optional)

5. Running the project (with alias)

6. Running the project (without alias)

7. Configure the IDP Kit to your needs

For more build options, please refer to the

For more details about the integrated commands, you may want to refer to the documentation of the .

concept section
NFTs
IDP Kit Setup
Client Registration
NFT Collection Configuration
Keycloak
Frontend
here
https://idp.walt.id
https://idp.walt-test.cloud
Next.js example project
walt.id
MetaMask
compatible wallet
Node.js
yarn
client registration step
http://localhost:3000
git clone https://github.com/walt-id/waltid-idpkit.git
cd waltid-idpkit
./gradlew build install
alias idpkit="build/install/waltid-idpkit/bin/waltid-idpkit"
git clone https://github.com/walt-id/waltid-idpkit.git
cd waltid-idpkit
docker build --rm -t waltid/idpkit .
alias idpkit="docker run -p 8080:8080 -e WALTID_DATA_ROOT=/data -v $PWD:/data waltid/idpkit"
cd web/waltid-idpkit-ui/
yarn install 

or 

npm install
yarn dev

or 

npm run dev
git clone https://github.com/walt-id/waltid-nftkit.git
cd waltid-nftkit/js
npm install
 npm i --save-dev @types/bn.js
npm start
waltid-idpkit config --oidc key list
waltid-idpkit config --siop vc policies list
   proxy: {
        '/verifier-api/': "http://localhost:8080/",
        '/api/': "http://localhost:8080/",
        '/webjars/': "http://localhost:8080/"
    }
    server: {
        port: 5000
    }
{
  "externalUrl": "http://localhost:5000",
}
{
  "verifierUiUrl": "",
  "verifierApiUrl": "http://localhost:8080/api/siop/default",

  "wallets": {
    "walt.id": {
      "id": "walt.id",
      "url": "https://wallet.walt-test.cloud",
      "presentPath": "api/siop/initiatePresentation/",
      "receivePath" : "api/siop/initiateIssuance/",
      "description": "localhost wallet"
    }
  }
}
JDK 16 build environment
Gradle
configuration section
configuration section
NFT collection configuration
http://localhost:3000
git clone https://github.com/walt-id/waltid-idpkit.git
cd waltid-idpkit
docker build --rm -t waltid/idpkit .
alias waltid-idpkit="docker run -p 8080:8080 -e WALTID_DATA_ROOT=/data -v $PWD:/data waltid/idpkit"
waltid-idpkit run
docker run -p 8080:8080 -e WALTID_DATA_ROOT
git clone https://github.com/walt-id/waltid-idpkit.git
cd waltid-idpkit
./gradlew build install
alias waltid-idpkit="build/install/waltid-idpkit/bin/waltid-idpkit"
waltid-idpkit run
build/install/waltid-idpkit/bin/waltid-idpkit run
IDP Kit configuration and setup
IDP Kit configuration and setup
build section
SSI Kit command line interface
Docker Container

NFT Collection Configuration

We need to provide the chain and the NFT collection, which the IDP Kit must check, when users are trying to log in. The values can be set in the config/idp-config.json under default_nft_token_claim

Choose the ecosystem of where your NFT collection is hosted

"default_nft_token_claim": {
      "EVM": {
            "chain": "MUMBAI",
            "factorySmartContractAddress": "",
            "smartContractAddress": "0x3496756a84E186DC8C0d7ef91BcD393200ef5Ebc",
            "collectionPath": ""
          }
 }
"default_nft_token_claim": {
      "TEZOS": {
            "chain": "GHOSTNET",
            "factorySmartContractAddress": "",
            "smartContractAddress": "KT1Rc59ukgW32e54aUdYqVzTM9gtHrA4JDYp",
            "collectionPath": ""

          }
 }

We also need to configure other properties in the same file:

"externalUrl": "http://localhost:8080", 
"jsProjectExternalUrl":"http://localhost:3000"

NFT collection configuration example:

"default_nft_token_claim": {
      "NEAR": {
            "chain": "TESTNET",
            "factorySmartContractAddress": "",
            "smartContractAddress": "demo.khaled_lightency1.testnet",
            "collectionPath": ""
          }
 }

We also need to configure other properties in the same file:

"externalUrl": "http://localhost:8080", 
"jsProjectExternalUrl":"http://localhost:3000"

NFT collection configuration example:

"default_nft_token_claim": {
      "POLKADOT": {
            "chain": "OPAL",
            "factorySmartContractAddress": "",
            "smartContractAddress": "1062",
            "collectionPath": ""
          }
 }

We also need to configure other properties in the same file:

"externalUrl": "http://localhost:5000", 
"jsProjectExternalUrl":"http://localhost:4000"
"default_nft_token_claim": {
     "FLOW": {
            "chain": "TESTNET",
            "factorySmartContractAddress": "",
            "smartContractAddress": "0xa9ccb9756a0ee7eb",
            "collectionPath": "/public/exampleNFTCollection"
          }
 }

We also need to configure other properties in the same file:

"externalUrl": "http://localhost:8080", 
"jsProjectExternalUrl":"http://localhost:3000"

Now that we have finished the configuration, we need to rebuild the project for the changes to take effect, run the API and connect our client to it.

  1. Rebuild the project

./gradlew build install

2. Expose the API

idpkit run
  1. Rebuild image

docker build --rm -t waltid/idpkit .

2. Expose the API

idpkit run

Keycloak (18.0.2)

Intro

Since the IDP Kit is compliant with the well adopted OpenID Connect standard for identity provision, it can be easily integrated, as a federated identity provider on Keycloak.

Configuration

To start with the configuration, we log in to the KeyCloak administration console with our admin credentials and navigate to the realm, for which we want to apply the configuration.

New external Identity Provider

  1. In the admin console, we navigate to the Identity Providers section in the left menu bar and open the "Add provider..." drop-down menu and choose "OpenID Connect v1.0":

2. We fill out Alias and Display Name according to how we want the IDP Kit to be referred to in the Login UI

3. We scroll down to Import External IDP Config and enter the URL of the well-known OIDC discovery document of the IDP Kit and click import. For our IDP Kit which is running locally, this would be:

http://localhost:8080/api/oidc/.well-known/openid-configuration

We need to make sure IDP Kit is running, as Keycloak will import all the information it needs from that endpoint as soon as we press "Import".

5. To make sure the IDP-Kit uses our NFT config settings during authentication, we need to provide openid nft_token as the value for Default Scopes and set Prompt to None

6. Now we can create the provider.

Check Redirect URI

Now that we've finished the setup of our Identity provider in Keycloak, we must make sure that the client we registered with the IDP-Kit has the correct redirect URL. The redirect URL should match the value found at Redirect URI in our just created Identity Provider.

Updating IDP-Kit client

In case the redirect URL registered with our IDP-Kit client does not match, we need to make a change.

To update an existing client, we can use the clients register command provided under the OIDC scope of the CLI tool and add the -u flag to note that we want to change a client with the specified id.

idpkit config --oidc clients register -n "myFrontend" -r "http://localhost:8082/realms/NFT/broker/nft/endpoint" -u "client_id"

Parameter description

  • -n - Name of the client

  • -r - The redirect URL which should be used in the OIDC flow

  • -u - The ID of the client we would like to update

After updating the client, we can now run the IDP-Kit and connect Keycloak to an application of our choice. We will be using Next.js and NextAuth.

Frontend - Next.js

Intro

Create the frontend

  1. We will clone the project and install all dependencies

git clone https://github.com/walt-id/waltid-nft-auth-keycloak-nextjs.git

2. Change directories

cd waltid-nft-auth-keycloak-nextjs

3. Install dependencies

yarn install

Create Keycloak client

  1. We log in to the KeyCloak administration console with our admin credentials and navigate to the realm, we used before to configure our external identity provider.

2. Under the Clients section, we create a new client, which we will use in our Next.js app.

3. We provide a Client ID and Name and click on Next.

4. We select Client authentication and the Standard flow and click Save.

5. In the overview of the new client we just created under the General Settings section, we update Valid redirect URIs to match our next.js application nextAuth callback URL: http://localhost:3000/api/auth/callback/keycloak

Connect Keycloak & Frontend

Now that we have the client registered with Keycloak we can add its credentials in our Next.js application.

  1. Let's rename .env.example file to .env

  2. We assign CLIENT_ID and CLIENT_SECRET to the values find in Settings and in the Credentials section respectively of our just created Keycloak client.

  3. The ISSUER we set to the host of our Keycloak instance.

Those values will then be used by the build in NextAuth.js provider for Keycloak which can be found in pages/api/auth/[...nextauth].ts

Running the Project

Now that we have finished all configurations, we can start up our frontend.

yarn dev

What is next

Login with NFTs | Next.js

Let your users authenticate in a Next.js app with NFTs.

🤟 Welcome

In this tutorial, we create our own instance of the IDP Kit locally and configure it to check users which want to authenticate for being an owner of a chosen NFT collection. We will register a client, connect our frontend and enable login with NFTs. The frontend builds on Next.js and will use NextAuth.js as authentication library.

NFT collections can be hosted on the following ecosystems:

  • Ethereum

  • Polygon

  • Tezos

  • Near

  • Polkadot

  • Flow

  • Algorand

🗂 Modules

📽️ Video Version

Overview

Here are the most important things to know about the IDP Kit:

  • It is open source (Apache 2). You can use the code for free and without limitations.

  • It is an out-of-the-box solution that you can simply re-use or even white-label such as for building pilot projects quickly.

  • It is customisable in a sense that you can individualise it based on your requirements.

  • It is composable in a sense that you can plug your existing (d)apps into the IDP Kit in order to supercharge your (d)apps with SSI capabilities.

  • It abstracts complexity such as low-level functionality related to key handling, data storage, signing and interactions with third party systems and SSI wallets.

  • It is built on open standards to ensure interoperability and prevent lock-in effects.

  • It is flexible in a sense that you can deploy and run an IDP on-premise, in your (multi) cloud environment or directly integrate our libraries.

NFT Collection Configuration

Intro

We need to provide the chain and the NFT collection, which the IDP Kit must check, when users are trying to log in. The values can be set in the config/idp-config.json under default_nft_token_claim

Choose the ecosystem of where your NFT collection is hosted

"default_nft_token_claim": {
      "EVM": {
            "chain": "MUMBAI",
            "factorySmartContractAddress": "",
            "smartContractAddress": "0x3496756a84E186DC8C0d7ef91BcD393200ef5Ebc",
            "collectionPath": ""
          }
 }
"default_nft_token_claim": {
      "TEZOS": {
            "chain": "GHOSTNET",
            "factorySmartContractAddress": "",
            "smartContractAddress": "KT1Rc59ukgW32e54aUdYqVzTM9gtHrA4JDYp",
            "collectionPath": ""

          }
 }

We also need to configure other properties in the same file:

"externalUrl": "http://localhost:8080", 
"jsProjectExternalUrl":"http://localhost:3000"

NFT collection configuration example:

"default_nft_token_claim": {
      "NEAR": {
            "chain": "TESTNET",
            "factorySmartContractAddress": "",
            "smartContractAddress": "demo.khaled_lightency1.testnet",
            "collectionPath": ""
          }
 }

We also need to configure other properties in the same file:

"externalUrl": "http://localhost:8080", 
"jsProjectExternalUrl":"http://localhost:3000"

NFT collection configuration example:

"default_nft_token_claim": {
      "POLKADOT": {
            "chain": "OPAL",
            "factorySmartContractAddress": "",
            "smartContractAddress": "1062",
            "collectionPath": ""
          }
 }

We also need to configure other properties in the same file:

"externalUrl": "http://localhost:5000", 
"jsProjectExternalUrl":"http://localhost:4000"
"default_nft_token_claim": {
     "FLOW": {
            "chain": "TESTNET",
            "factorySmartContractAddress": "",
            "smartContractAddress": "0xa9ccb9756a0ee7eb",
            "collectionPath": "/public/exampleNFTCollection"
          }
 }

We also need to configure other properties in the same file:

"externalUrl": "http://localhost:8080", 
"jsProjectExternalUrl":"http://localhost:3000"
"default_nft_token_claim": {
       "ALGORAND": {
            "chain": "ALGORAND_TESTNET",
            "factorySmartContractAddress": "",
            "smartContractAddress": "GYFVJLKGSWQDHFBHBLABUXYHHSU544RV3WH4ZCF3S6HONSDP73TK4VGY3Y",
            "collectionPath": ""
        }
 }

In the "smartContractAddress": You should provide the asset Creator Account

Now that we have finished the configuration, we need to rebuild the project for the changes to take effect, run the API and connect our client to it.

  1. Rebuild the project

./gradlew build install

2. Expose the API

idpkit run
  1. Rebuild image

docker build --rm -t waltid/idpkit .

2. Expose the API

idpkit run

Client Registration

Clients and why we need one

To use the IDP Kits functionality, we need to register our frontend application as client and collect client_id and client_secret. Those credentials will be used by the frontend to make requests to the IDP Kit, which will in turn ask the user if they want to sign in and check if they are allowed to do so, based on the NFTs they hold in their wallet. After collecting the consent of the user and validating that they are allowed to log in, the IDP Kit will give the frontend a secret with which it can request information about the authenticated user the user.

Client registration

Now that we know what we need and why we need it, let's go ahead and create our first client. Depending on the situation and personal preference, there are two options available: CLI tool, API.

Register client

To register a new client, we can use the clients register command provided under the OIDC scope of the CLI tool.

idpkit config --oidc clients register -n "myFrontend" -r "http://localhost:3000/api/auth/callback/walt-id-nft"

Parameter description

  • -n - Name of the client

  • -r - The redirect URL which should be used in the OIDC flow

Other Options:

  • --all-redirect-uris - Redirect can go to any URL specified in the OIDC flow requests

Why we set a redirect URL?

If we set a redirect URL we can make sure that no other party will be able to use our authentication flow, even if they would get access to our secrets. For our project we set the URL http://localhost:3000 as this will be the URL under which our frontend application will be hosed. Later if we were to put the application into production it would be something like https://applicationName.com. In this case we would need to update our registerd client and reflect the new redirect URL.

Update client

To update an existing client, we can use the clients register command provided under the OIDC scope of the CLI tool and add the -u flag to note that we want to change a client with the specified id.

idpkit config --oidc clients register -n "myFrontend" -r "https://applicationName.com" -u "client_id"

Parameter description

  • -n - Name of the client

  • -r - The redirect URL which should be used in the OIDC flow

  • -u - The ID of the client we would like to update

Exposing the API

In order to use the API, we need to launch it first.

idpkit run

Register client

Get master_token

To get the master_token we can execute the clients token command under the OIDC scope of the CLI tool.

idpkit config --oidc clients token

Register client request

We need to replace master_token in the Authorization request header before executing.

curl -X POST http://localhost:8080/api/oidc/clients/register \
-H "Authorization: Bearer master_token" \
-H "Content-Type: application/json" \
-d '{"client_name": "MyApp","redirect_uris": ["http://localhost:3000/api/auth/callback/walt-id-nft"],"all_redirect_uris": false}'

Save the response somewhere, where you can later retrieve the information. Most importantly, the client_id and client_secret.

Why we set a redirect URL?

If we set a redirect URL we can make sure that no other party will be able to use our authentication flow, even if they would get access to our secrets. For our project we set the URL http://localhost:3000 as this will be the URL under which our frontend application will be hosed. Later if we were to put the application into production it would be something like https://applicationName.com. In this case we would need to update our registerd client and reflect the new redirect URL.

Update client

To update a client we make a PUT request to the /api/oidc/clients/<client_id> and provide the registration_access_token, which we got during client registration. In order for the update to go through, we need to provide the whole response we got from the client registration step in the update request body.

Make sure before executing the request, to replace the clientid in the request URL and the registration_access_token

curl -X PUT http://localhost:8080/api/oidc/clients/96baIcn5YUD7z2H69nPkd1KrizaixBs3IWcRS_qDCmM \
-H "Authorization: Bearer eyJraWQiOiI2YzA2M2Y3NjBjNGM0M2VlYjNkMDNmNmQzODQ1NGU1OSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI5NmJhSWNuNVlVRDd6Mkg2OW5Qa2QxS3JpemFpeEJzM0lXY1JTX3FEQ21NIn0.RgNdqkK_o2paGvJhM95jtrEqUPTiIQVB4kZFY8QIAKypAFC2Iq6WTll_nyAM_osbSluEQGlQvwpFf4xnF4aM2JxAkeTE1SCHA3EWODIn2uDzKDFkpNOdw9xJHiIstqy2WK1x8jsi1RK_iaa6gf_3Pm0xazEekkjvRGtXn9jfoyYiUVN75EJDU_pbSju9vXNIO2nd2FIBzmyd3DWohat0Lgb1m7fv8eFWXjC-PYICrv-qLP7-cVuhNnrkmCXSIwhXcXbdjyqAB6cgFVqecUaiTCi928uIxTRsAS7_vnPCiWxnPTGCTGsE05hspbnTuubxs0oYGFOZ7adURvCkgxFsHw" \
-H "Content-Type: application/json" \
-d '{"client_secret_expires_at": 0, "all_redirect_uris": false, "registration_client_uri": "http://localhost:8080/api/oidc/clients/96baIcn5YUD7z2H69nPkd1KrizaixBs3IWcRS_qDCmM", "redirect_uris": ["http://localhost:3000"], "client_id_issued_at": 1662617990, "client_secret": "hMAi7khf6cgZ2wRXlN89FQ1zB99654j8cyF4O3AAmk0", "client_name": "MyApp", "registration_access_token": "eyJraWQiOiI2YzA2M2Y3NjBjNGM0M2VlYjNkMDNmNmQzODQ1NGU1OSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI5NmJhSWNuNVlVRDd6Mkg2OW5Qa2QxS3JpemFpeEJzM0lXY1JTX3FEQ21NIn0.RgNdqkK_o2paGvJhM95jtrEqUPTiIQVB4kZFY8QIAKypAFC2Iq6WTll_nyAM_osbSluEQGlQvwpFf4xnF4aM2JxAkeTE1SCHA3EWODIn2uDzKDFkpNOdw9xJHiIstqy2WK1x8jsi1RK_iaa6gf_3Pm0xazEekkjvRGtXn9jfoyYiUVN75EJDU_pbSju9vXNIO2nd2FIBzmyd3DWohat0Lgb1m7fv8eFWXjC-PYICrv-qLP7-cVuhNnrkmCXSIwhXcXbdjyqAB6cgFVqecUaiTCi928uIxTRsAS7_vnPCiWxnPTGCTGsE05hspbnTuubxs0oYGFOZ7adURvCkgxFsHw", "client_id": "96baIcn5YUD7z2H69nPkd1KrizaixBs3IWcRS_qDCmM"}' \

OIDC Manager configuration

In this section we look at the configuration of the OIDC Manager sub module.

IDP configuration

The configuration of the OIDC manager can be adapted, by modifying the file

config/idp-config.json

External URL

Configure the URL via which the IDP/OIDC API will be reachable from an external source (i.e. from the client application):

Signature key for issued tokens

By default, the OIDC Manager creates an RSA key for RS256 token signatures on first startup.

To enforce a certain key or key/signature type, specify the key id in the configuration file like this:

Open client registration

To allow unauthenticated client registration via the dynamic client registration API, specify the following configuration option:

Fallback authorization mode

If the authorization mode, SIOP or NFT, can not be derived from the scopes and claims specified in the authorization request by the client application, or the request is ambiguous, the IDP Kit will choose the preferred mode based on this configuration option:

Claim configuration

To configure how the IDP Kit maps the scopes and claims from the authorization request to verifiable presentation requests for SSI, or NFT claims, one can define claim mappings and default claims in the claim configuration object. E.g.:

Configuration example

Here's a complete example for the idp-config.json:

Verifiable Credential Config

Intro

The verifiable credential data can be transformed and sent back to the client in various ways. In the IDP-Kit's default configuration (found in the file config/idp-config.json), the DID, first name, last name, gender, and birthday are mapped as claims to the profile scope while the required credential type is VerifiableId.

Client Registration

Clients and why we need one

To use the IDP Kits functionality, we need a client and collect client_id and client_secret. Those credentials will be used by Keycloak to make requests to the IDP Kit, which will in turn ask the user if they want to sign in and check if they are allowed to do so, based on the NFTs they hold in their wallet. After collecting the consent of the user and validating that they are allowed to log in, the IDP Kit will give Keycloak a secret with which it can request information about the authenticated the user.

Client registration

Now that we know what we need and why we need it, let's go ahead and create our first client. Depending on the situation and personal preference, there are two options available: CLI tool, API.

Register client

To register a new client, we can use the clients register command provided under the OIDC scope of the CLI tool.

Parameter description

  • -n - Name of the client

  • -r - The redirect URL which should be used in the OIDC flow

Other Options:

  • --all-redirect-uris - Redirect can go to any URL specified in the OIDC flow requests

Why we set a redirect URL?

If we set a redirect URL we can make sure that no other party will be able to use our authentication flow, even if they would get access to our secrets. For our project we set the URL http://localhost:8082/realms/NFT/broker/nft/endpoint as this is the location where Keycloak wants us to redirect the user to. Later if we were to put keycloak into production it would be something like https://{host}/realms/NFT/broker/nft/endpoint. In this case we would need to update our registerd client and reflect the new redirect URL.

Update client

To update an existing client, we can use the clients register command provided under the OIDC scope of the CLI tool and add the -u flag to note that we want to change a client with the specified id.

Parameter description

  • -n - Name of the client

  • -r - The redirect URL which should be used in the OIDC flow

  • -u - The ID of the client we would like to update

Exposing the API

In order to use the API, we need to launch it first.

Register client

Get master_token

To get the master_token we can execute the clients token command under the OIDC scope of the CLI tool.

Register client request

We need to replace master_token in the Authorization request header before executing.

Save the response somewhere, where you can later retrieve the information. Most importantly, the client_id and client_secret.

Why we set a redirect URL?

If we set a redirect URL we can make sure that no other party will be able to use our authentication flow, even if they would get access to our secrets. For our project we set the URL http://localhost:3000 as this will be the URL under which our frontend application will be hosed. Later if we were to put the application into production it would be something like https://applicationName.com. In this case we would need to update our registerd client and reflect the new redirect URL.

Update client

To update a client we make a PUT request to the /api/oidc/clients/<client_id> and provide the registration_access_token, which we got during client registration. In order for the update to go through, we need to provide the whole response we got from the client registration step in the update request body.

Make sure before executing the request, to replace the clientid in the request URL and the registration_access_token

Assuming that you already have a local instance of Keycloak running, we will continue with the configuration of our federated identity provider. In case you need to first, please have a look at their documentation on how to get started.

4. Now we scroll down to Client Authentication and choose Client secret sent as basic auth as input field value. Then we provide Client ID and Client Secret which we got during the step.

We have prepared a which we can use as a starting point. It uses NextAuth.js for handling authentication, which makes it easy for us to connect our Keycloak instance. We won't go into details of how Next.js or NextAuth.js works.

The user of the frontend application needs or another to share their blockchain address, with which the IDP Kit will be able to check if the user is holder of the required NFT collection.

We will need and or npm

Now we can log in as long as we hold an NFT of the collection we specified in the .

You made it, you've built login with NFTs with Keycloak and Next.js! Share your progress in our channel or on , then we can celebrate together 🤟

The IDP Kit uses the OIDC authentication flow, the same technology used by Sign-in with Apple, Facebook, Twitter and many more. If you want to learn more about it and how it works behind the scenes, you can have a look at our as well as how the ideas are translated when using .

- Build and run the project in your local environment

- Retrieve clientId and clientSecret from the IDP Kit, used in the frontend

- Set NFT collection required by the users to login successfully

- Setup and connect frontend to IDP Kit and enable sign in with NFTs

You can also watch the full tutorial .

It enables you to use different identity ecosystems like Europe’s emerging identity ecosystem () in anticipation of a multi-ecosystem future. (Consult the to find out which ecosystems the IDP Kit supports.)

The exchange of information between the client, which is in our case the frontend application and the authorization server which is the IDP Kit are based on the OpenID Connect standards. I won't go into more detail here, but you can learn more about it in the or watch this great from OktaDev, which gives a great overview about OpenID Connect. To understand how the base ideas are then translated to the NFT use case, you can dive into

CLI tool commands and options.

To register a new client, we can make a POST request to /api/oidc/clients/register. However, by default the , requires you to authenticate. Providing the master_token in the header of the request makes sure the registration goes through.

API endpoints and options or visit the .

If you haven't already, you may want to familiarize yourself with the basic , the and the , in the previous sections, before moving on.

Go to section for details on how to create keys and on supported signature types.

See also section for more details about registering and managing clients.

See section for details about this configuration object and the available options.

The exchange of information between the client, which is in our case Keycloak and the authorization server which is the IDP Kit are based on the OpenID Connect standards. I won't go into more detail here, but you can learn more about it in the or watch this great from OktaDev, which gives a great overview about OpenID Connect. To understand how the base ideas are then translated to the NFT use case, you can dive into

CLI tool commands and options.

To register a new client, we can make a POST request to /api/oidc/clients/register. However, by default the , requires you to authenticate. Providing the master_token in the header of the request makes sure the registration goes through.

API endpoints and options or visit the .

setup Keycloak
client registration
Next.js example project
MetaMask
compatible wallet
Node.js
yarn
NFT Collection Configuration Section
discord
Twitter
concept section
NFTs
IDP Kit Setup
Client Registration
NFT Collection Configuration
Next.js
here
concept section
illustrative video
Identity provision via NFTs
Learn more
registration of new clients via API
Learn more
swagger docs
{
  "externalUrl": "https://idp.walt-test.cloud",
[...]
}
{
  [...]
  "keyId": "715b3ebf65074f1183a48c4b7c8e311c",
  [...]
}
{
  [...]
  "openClientRegistration": true,
  [...]
}
{
  [...]
  "fallbackAuthorizationMode": "SIOP",
  [...]
}
{
  [...]
  "claimConfig": {
    "vc_mappings": [
      {
        "scope": [ "profile" ],
        "claim": "name",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.firstName $.credentialSubject.familyName"
      }
      [...]
    ],
    "nft_mappings": [
      {
        "scope": [ "profile" ],
        "claim": "name",
        "chain": "POLYGON",
        "smartContractAddress": "0x12345678901234567890",
        "trait": "name"
      }
    ],
    "default_nft_token_claim": {
      "chain": "POLYGON",
      "smartContractAddress": "0x12345678901234567890"
    },
    "default_vp_token_claim": {
      "presentation_definition": {
        "id": "1",
        "input_descriptors": [
          {
            "id": "1",
            "constraints": {
              "fields": [
                {
                  "id": "1",
                  "path": [ "$.type" ],
                  "filter": { "const":  "VerifiableId" }
                }
              ]
            }
          }
        ]
      }
    }
  }
  [...]
}
{
  "externalUrl": "https://idp.walt-test.cloud",
  "keyId": "715b3ebf65074f1183a48c4b7c8e311c",
  "openClientRegistration": false,
  "fallbackAuthorizationMode": "SIOP",
  "claimConfig": {
    "vc_mappings": [
      {
        "scope": [ "profile" ],
        "claim": "name",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.firstName $.credentialSubject.familyName"
      },
      {
        "scope": [ "profile" ],
        "claim": "family_name",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.familyName"
      },
      {
        "scope": [ "profile" ],
        "claim": "given_name",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.firstName"
      },
      {
        "scope": [ "profile" ],
        "claim": "gender",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.gender"
      },
      {
        "scope": [ "profile" ],
        "claim": "birthdate",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.dateOfBirth"
      },
      {
        "scope": [ "address" ],
        "claim": "address",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.currentAddress[0]"
      }
    ],
    "default_nft_token_claim": {
      "chain": "POLYGON",
      "smartContractAddress": "0x21dd9b1913d84ab295fdf19834b0b6824a5912ca"
    },
    "default_vp_token_claim": {
      "presentation_definition": {
        "id": "1",
        "input_descriptors": [
          {
            "id": "1",
            "constraints": {
              "fields": [
                {
                  "id": "1",
                  "path": [ "$.type" ],
                  "filter": { "const":  "VerifiableId" }
                }
              ]
            }
          }
        ]
      }
    }
  }
}
...
      {
        "scope": [ "profile" ],
        "claim": "name",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.firstName $.credentialSubject.familyName"
      },
      {
        "scope": [ "profile" ],
        "claim": "family_name",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.familyName"
      },
      {
        "scope": [ "profile" ],
        "claim": "given_name",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.firstName"
      },
      {
        "scope": [ "profile" ],
        "claim": "gender",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.gender"
      },
      {
        "scope": [ "profile" ],
        "claim": "birthdate",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.dateOfBirth"
      },   
...
idpkit config --oidc clients register -n "myFrontend" -r "http://localhost:8001/realms/NFT/broker/nft/endpoint"
idpkit config --oidc clients register -n "myFrontend" -r "https://applicationName.com" -u "client_id"
idpkit run
idpkit config --oidc clients token
curl -X POST http://localhost:8080/api/oidc/clients/register \
-H "Authorization: Bearer master_token" \
-H "Content-Type: application/json" \
-d '{"client_name": "MyApp","redirect_uris": ["http://localhost:3000/api/auth/callback/walt-id-nft"],"all_redirect_uris": false}'
curl -X PUT http://localhost:8080/api/oidc/clients/96baIcn5YUD7z2H69nPkd1KrizaixBs3IWcRS_qDCmM \
-H "Authorization: Bearer eyJraWQiOiI2YzA2M2Y3NjBjNGM0M2VlYjNkMDNmNmQzODQ1NGU1OSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI5NmJhSWNuNVlVRDd6Mkg2OW5Qa2QxS3JpemFpeEJzM0lXY1JTX3FEQ21NIn0.RgNdqkK_o2paGvJhM95jtrEqUPTiIQVB4kZFY8QIAKypAFC2Iq6WTll_nyAM_osbSluEQGlQvwpFf4xnF4aM2JxAkeTE1SCHA3EWODIn2uDzKDFkpNOdw9xJHiIstqy2WK1x8jsi1RK_iaa6gf_3Pm0xazEekkjvRGtXn9jfoyYiUVN75EJDU_pbSju9vXNIO2nd2FIBzmyd3DWohat0Lgb1m7fv8eFWXjC-PYICrv-qLP7-cVuhNnrkmCXSIwhXcXbdjyqAB6cgFVqecUaiTCi928uIxTRsAS7_vnPCiWxnPTGCTGsE05hspbnTuubxs0oYGFOZ7adURvCkgxFsHw" \
-H "Content-Type: application/json" \
-d '{"client_secret_expires_at": 0, "all_redirect_uris": false, "registration_client_uri": "http://localhost:8080/api/oidc/clients/96baIcn5YUD7z2H69nPkd1KrizaixBs3IWcRS_qDCmM", "redirect_uris": ["http://localhost:3000"], "client_id_issued_at": 1662617990, "client_secret": "hMAi7khf6cgZ2wRXlN89FQ1zB99654j8cyF4O3AAmk0", "client_name": "MyApp", "registration_access_token": "eyJraWQiOiI2YzA2M2Y3NjBjNGM0M2VlYjNkMDNmNmQzODQ1NGU1OSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI5NmJhSWNuNVlVRDd6Mkg2OW5Qa2QxS3JpemFpeEJzM0lXY1JTX3FEQ21NIn0.RgNdqkK_o2paGvJhM95jtrEqUPTiIQVB4kZFY8QIAKypAFC2Iq6WTll_nyAM_osbSluEQGlQvwpFf4xnF4aM2JxAkeTE1SCHA3EWODIn2uDzKDFkpNOdw9xJHiIstqy2WK1x8jsi1RK_iaa6gf_3Pm0xazEekkjvRGtXn9jfoyYiUVN75EJDU_pbSju9vXNIO2nd2FIBzmyd3DWohat0Lgb1m7fv8eFWXjC-PYICrv-qLP7-cVuhNnrkmCXSIwhXcXbdjyqAB6cgFVqecUaiTCi928uIxTRsAS7_vnPCiWxnPTGCTGsE05hspbnTuubxs0oYGFOZ7adURvCkgxFsHw", "client_id": "96baIcn5YUD7z2H69nPkd1KrizaixBs3IWcRS_qDCmM"}' \
Keys and signatures
Client registration
Claim mapping
Learn more about claim mapping
concept section
illustrative video
Identity provision via NFTs
Learn more
registration of new clients via API
Learn more
swagger docs

Client Registration

Clients and why we need one

To use the IDP Kits functionality, we need to register our frontend application as client and collect client_id and client_secret. Those credentials will be used by the frontend to make requests to the IDP Kit, which will in turn ask the user if they want to sign in and check if they are allowed to do so, based on the Verifiable Credential in their wallet. After collecting the consent of the user and validating that they are allowed to log in, the IDP Kit will give the frontend a secret with which it can request information about the authenticated the user.

Client registration

Now that we know what we need and why we need it, let's go ahead and create our first client. Depending on the situation and personal preference, there are two options available: CLI tool, API.

Register client

To register a new client, we can use the clients register command provided under the OIDC scope of the CLI tool.

idpkit config --oidc clients register -n "myFrontend" -r "http://localhost:3000/api/auth/callback/walt-id-ssi"

Parameter description

  • -n - Name of the client

  • -r - The redirect URL which should be used in the OIDC flow

Other Options:

  • --all-redirect-uris - Redirect can go to any URL specified in the OIDC flow requests

Why we set a redirect URL?

If we set a redirect URL we can make sure that no other party will be able to use our authentication flow, even if they would get access to our secrets. For our project we set the URL http://localhost:3000 as this will be the URL under which our frontend application will be hosed. Later if we were to put the application into production it would be something like https://applicationName.com. In this case we would need to update our registerd client and reflect the new redirect URL.

Update client

To update an existing client, we can use the clients register command provided under the OIDC scope of the CLI tool and add the -u flag to note that we want to change a client with the specified id.

idpkit config --oidc clients register -n "myFrontend" -r "https://applicationName.com" -u "client_id"

Parameter description

  • -n - Name of the client

  • -r - The redirect URL which should be used in the OIDC flow

  • -u - The ID of the client we would like to update

Exposing the API

In order to use the API, we need to launch it first.

idpkit run

Register client

Get master_token

To get the master_token we can execute the clients token command under the OIDC scope of the CLI tool.

idpkit config --oidc clients token

Register client request

We need to replace master_token in the Authorization request header before executing.

curl -X POST http://localhost:8080/api/oidc/clients/register \
-H "Authorization: Bearer master_token" \
-H "Content-Type: application/json" \
-d '{"client_name": "MyApp","redirect_uris": ["http://localhost:3000/api/auth/callback/walt-id-ssi"],"all_redirect_uris": false}'

Save the response somewhere, where you can later retrieve the information. Most importantly, the client_id and client_secret.

Why we set a redirect URL?

If we set a redirect URL we can make sure that no other party will be able to use our authentication flow, even if they would get access to our secrets. For our project we set the URL http://localhost:3000 as this will be the URL under which our frontend application will be hosed. Later if we were to put the application into production it would be something like https://applicationName.com. In this case we would need to update our registerd client and reflect the new redirect URL.

Update client

To update a client we make a PUT request to the /api/oidc/clients/<client_id> and provide the registration_access_token, which we got during client registration. In order for the update to go through, we need to provide the whole response we got from the client registration step in the update request body.

Make sure before executing the request, to replace the clientid in the request URL and the registration_access_token

curl -X PUT http://localhost:8080/api/oidc/clients/96baIcn5YUD7z2H69nPkd1KrizaixBs3IWcRS_qDCmM \
-H "Authorization: Bearer eyJraWQiOiI2YzA2M2Y3NjBjNGM0M2VlYjNkMDNmNmQzODQ1NGU1OSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI5NmJhSWNuNVlVRDd6Mkg2OW5Qa2QxS3JpemFpeEJzM0lXY1JTX3FEQ21NIn0.RgNdqkK_o2paGvJhM95jtrEqUPTiIQVB4kZFY8QIAKypAFC2Iq6WTll_nyAM_osbSluEQGlQvwpFf4xnF4aM2JxAkeTE1SCHA3EWODIn2uDzKDFkpNOdw9xJHiIstqy2WK1x8jsi1RK_iaa6gf_3Pm0xazEekkjvRGtXn9jfoyYiUVN75EJDU_pbSju9vXNIO2nd2FIBzmyd3DWohat0Lgb1m7fv8eFWXjC-PYICrv-qLP7-cVuhNnrkmCXSIwhXcXbdjyqAB6cgFVqecUaiTCi928uIxTRsAS7_vnPCiWxnPTGCTGsE05hspbnTuubxs0oYGFOZ7adURvCkgxFsHw" \
-H "Content-Type: application/json" \
-d '{"client_secret_expires_at": 0, "all_redirect_uris": false, "registration_client_uri": "http://localhost:8080/api/oidc/clients/96baIcn5YUD7z2H69nPkd1KrizaixBs3IWcRS_qDCmM", "redirect_uris": ["http://localhost:3000"], "client_id_issued_at": 1662617990, "client_secret": "hMAi7khf6cgZ2wRXlN89FQ1zB99654j8cyF4O3AAmk0", "client_name": "MyApp", "registration_access_token": "eyJraWQiOiI2YzA2M2Y3NjBjNGM0M2VlYjNkMDNmNmQzODQ1NGU1OSIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI5NmJhSWNuNVlVRDd6Mkg2OW5Qa2QxS3JpemFpeEJzM0lXY1JTX3FEQ21NIn0.RgNdqkK_o2paGvJhM95jtrEqUPTiIQVB4kZFY8QIAKypAFC2Iq6WTll_nyAM_osbSluEQGlQvwpFf4xnF4aM2JxAkeTE1SCHA3EWODIn2uDzKDFkpNOdw9xJHiIstqy2WK1x8jsi1RK_iaa6gf_3Pm0xazEekkjvRGtXn9jfoyYiUVN75EJDU_pbSju9vXNIO2nd2FIBzmyd3DWohat0Lgb1m7fv8eFWXjC-PYICrv-qLP7-cVuhNnrkmCXSIwhXcXbdjyqAB6cgFVqecUaiTCi928uIxTRsAS7_vnPCiWxnPTGCTGsE05hspbnTuubxs0oYGFOZ7adURvCkgxFsHw", "client_id": "96baIcn5YUD7z2H69nPkd1KrizaixBs3IWcRS_qDCmM"}' \

Claim configuration

In order to support mapping of SSI credential data or NFT token metadata to standard OIDC scopes and claims, you have to define which credential types or NFTs are required and which property or trait in the credential/NFT data contains the claimed information.

If the required VP token claim or NFT token claim cannot be derived from the authorization request, one can configure default claims, that will be sent to the SSI or NFT wallet in this case.

Based on the configured claim mappings and the required claims or scopes in the authorization request from the client application, the IDP will decide which credentials or NFTs need to be requested from the user wallet.

This list of claim mappings will be reflected in the well-known openid-configuration discovery document, publishing the supported claims and scopes (scopes_supported, claims_supported).

Mapping Configuration

vc_mappings

Example:

{
  [...]
  "claimConfig": {
    "vc_mappings": [
      {
        "scope": [ "profile" ],
        "claim": "name",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.firstName $.credentialSubject.familyName"
      },
      {
        "scope": [ "profile" ],
        "claim": "family_name",
        "credentialType": "VerifiableId",
        "valuePath": "$.credentialSubject.familyName"
      }
      [...]
    ]
  }
  [...]
}

Each mapping object contains the following properties:

  • scope: One or multiple OIDC scope(s), this claim belongs to. E.g. profile, address, email, etc.

  • claim: The name of the OIDC claim. E.g. name, given_name, family_name, email, etc.

  • credentialType: The type of credential from which the claim information should be read

  • valuePath: A JSON path leading to the claim value in the credential data. This supports multiple JSON paths separated by blanks, to concatenate values, like shown in the example claim name in the profile scope.

nft_mappings

Example:

{
  [...]
  "claimConfig": {
    "nft_mappings": [
      {
        "scope": [ "profile" ],
        "claim": "name",
        "chain": "POLYGON",
        "smartContractAddress": "0x12345678901234567890",
        "trait": "name"
      },
      [...]
    ]
  }
  [...]
}

Each mapping object contains the following properties:

  • scope: One or multiple OIDC scope(s), this claim belongs to. E.g. profile, address, email, etc.

  • claim: The name of the OIDC claim. E.g. name, given_name, family_name, email, etc.

  • chain: The chain on which the NFT must be held by the user

  • smartContractAddress: The address of the NFT collection, which the user must hold an NFT of

  • trait: Key of the NFT metadata, which will be used to fill this particular claim value

Default claims

If the authorization request from the client application contains only the scope vp_token or nft_token, but does not specify any further scopes or claims to derive the required nft or verifiable presentation from, the IDP Kit will fall back to the default claims configured here:

default_nft_token_claim

The default claim used to fulfill an NFT token request.

Example:

{
  [...]
  "claimConfig": {
    [...]
    "default_nft_token_claim": {
      "chain": "POLYGON",
      "smartContractAddress": "0x12345678901234567890"
    }
  }
  [...]
}

The default nft token claim defines the following properties:

  • chain: The chain on which the NFT must be held by the user

  • smartContractAddress: The address of the NFT collection, which the user must hold an NFT of

default_vp_token_claim

The default claim used to request a verifiable presentation from the SSI wallet:

Example:

{
  [...]
  "claimConfig": {
    [...]
    "default_vp_token_claim": {
      "presentation_definition": {
        "id": "1",
        "input_descriptors": [
          {
            "id": "1",
            "constraints": {
              "fields": [
                {
                  "id": "1",
                  "path": [ "$.type" ],
                  "filter": { "const":  "VerifiableId" }
                }
              ]
            }
          }
        ]
      }
    }
  }
  [...]
}

In this example, a filter for credentials with the type VerifiableId is definied.

Login with SSI | Next.js

Let your users authenticate in a Next.js app with a Verifiable Credential.

🤟 Welcome

In this tutorial, we create our own instance of the IDP Kit locally and configure it, so users can log in using their Verifiable Id Credential. We will register a client, connect our frontend and enable login with Verifiable Credentials. The frontend builds on Next.js and will use NextAuth.js as authentication library.

🗂 Modules

Keycloak (>19.0.1)

Since the IDP Kit is compliant with the well adopted OpenID Connect standard for identity provision, it can be easily integrated, as a federated identity provider on Keycloak.

Configuration

To start with the configuration, we log in to the KeyCloak administration console with our admin credentials and navigate to the realm, for which we want to apply the configuration.

New external Identity Provider

  1. In the admin console, we select under configurations the Identity providers and select the OpenID Connect v1.0 option

2. We fill out Alias and Display Name

3. Add the Discovery endpoint, which will be in the form of:

{host}/api/oidc/.well-known/openid-configuration

We need to make sure IDP Kit is running, as Keycloak will import all the information it needs from that endpoint.

Advanced Settings

After successfully creating the new identity provider, in the Advanced settings section when expanding the Advanced dropdown, we need to update Scopes and Prompt

  1. Scopes = openid nft_token

  2. Prompt = None

By updating the scopes to use nft_token, we make sure the IDP-Kit will use NFTs as a method of authentication, when the user logs in.

Check Redirect URI

Now that we've finished the setup of our Identity provider in Keycloak, we must make sure that the client we registered with the IDP-Kit has the correct redirect URL. The redirect URL should match the value found in at Redirect URI in our just created Identity Provider.

Updating IDP-Kit client

In case the redirect URL registered with our IDP-Kit client does not match, we need to make a change.

To update an existing client, we can use the clients register command provided under the OIDC scope of the CLI tool and add the -u flag to note that we want to change a client with the specified id.

idpkit config --oidc clients register -n "myFrontend" -r "http://localhost:8082/realms/NFT/broker/nft/endpoint" -u "client_id"

Parameter description

  • -n - Name of the client

  • -r - The redirect URL which should be used in the OIDC flow

  • -u - The ID of the client we would like to update

After updating the client, we can now run the IDP-Kit and connect Keycloak to an application of our choice. We will be using Next.js and NextAuth.

Client authentication

Authenticated endpoints

Endpoints affected by the client authentication are

  • token_endpoint

    • /api/oidc/token

  • pushed_authorization_request_endpoint

    • /api/oidc/par

Authentication methods

The supported client authentication methods are published in the discovery document (token_endpoint_auth_methods_supported) on the well-known openid-configuration endpoint.

Currently supported authentication methods:

  • client_secret_basic

IDP Kit Setup

Intro

Before you start with the project setup, make sure you have the following dependencies on your local machine:

Getting Started

For running the project, you have two options: Docker or Gradle.

Running the IDP-Kit Frontend The frontend with which the user will interact to authenticate by doing a connect wallet.

Change into the frontend directory

cd web/waltid-idpkit-ui/

Install dependencies using node v.16

yarn install 

or 

npm install

Running the project

yarn dev

or 

npm run dev

Configuring the SSI wallet used during authentication

In the verifier config (config/verifier-config.json), we can define the SSI wallet which should be used. For this example, we can use the hosted wallet by walt.id.

{
  "verifierUiUrl":"http://localhost:5000/sharecredential?state=",
  "verifierApiUrl":"http://localhost:5000/api/siop/default",

  "wallets": {
    "walt.id": {
      "id": "waltid",
      "url": "",
      "presentPath": "api/siop/initiatePresentation/",
      "receivePath" : "api/siop/initiateIssuance/",
      "description": "walt.id web wallet"
    },
    "local": {
      "id": "local",
      "url": "",
      "presentPath": "api/siop/initiatePresentation/",
      "receivePath" : "api/siop/initiateIssuance/",
      "description": "local wallet"
    }
  }
}

OIDC Authentication - Recap

To better understand what the IDP Kit does, let's first recap on the basics of OIDC authentication flows.

OIDC authentication flows

In a usual OIDC authentication flow, the client application makes an authentication/authorization request to an authorization server or identity provider. In this request, the client includes the scopes and/or claims, which define the pieces of information about the user required by the application.

The identity provider redirects to a login or authentication page, where the user has to authenticate and give their consent to the requested information being shared with the application.

Depending on the response type chosen by the application, the identity provider will provide an authorization code, which can be traded for an access token and ID token, or the respective tokens directly, by calling the redirection URI of the application with the respective parameters.

The application can use the access token to retrieve the user information, which was originally requested. The id token usually contains a user ID, issuer ID, expiration date, etc., which the application can use at it's own discretion.

Code flow

The application requests response_type=code in the authorization request, and receives an authorization code from the identity provider, which can be traded for access_token and id_token on the token endpoint. Using the access_token the application can retrieve the requested user information over the userInfo endpoint.

Communication with the identity provider is usually done via a backend of the client application and requires client authentication.

Implicit flow

The response_type requested by the application is id_token token, id_token or token, and the identity provider sends the requested tokens directly to the callback uri of the client application. The application can use the access_token to retrieve the requested user information over the userInfo endpoint. If only id_token was requested by the application, the user information is included in the id_token returned by the identity provider.

This flow is usually chosen if the application front-end conducts the user authorization without any backend interaction.

Hybrid flow

In a hybrid flow, the client application requests any combination of code, id_token and token response types and has the option to follow the implicit or code flow to retrieve user information according to the specific requirements.

OIDC scopes and claims

An OIDC authentication request usually contains a set of scopes and/or claims requested by the client application.

Scopes usually imply a predefined set of claims, whereas a claim is a request for a specific piece of information about the user.

Example scopes:

  • profile

    • Claims: name, family_name, given_name, middle_name, nickname, preferred_username, profile, picture, website, gender, birthdate, zoneinfo, locale, and updated_at

  • email

    • Claims: email, email_verified

  • address:

    • Claims: address

  • phone:

    • Claims: phone_number, phone_number_verified

Example request

This example request consists of the following parameters:

  • response_type: The response_type requested by the application

    • In this case an authorization code is requested.

  • scope: The requested scopes defining the information requested by the application:

    • openid: default scope, that is always included in OIDC requests

  • client_id: The ID of the client application, as it was registered with the identity provider

  • state: Arbitrary state information of the client application, that is propagated to the authentication response on the callback/redirection URI.

  • redirect_uri: Redirection or callback URI of the client application, which will be called with the authentication response (in this case: the authorization code) in the URI parameters

IDP Kit configuration and setup

To setup the IDP Kit a few things may need to be considered and some configuration may be required, depending on your situation.

Data root

Configuration and data are kept in sub folders of the data root (by default the current working directory):

  • config/

  • data/

To override the data root, one can set the environment variable:

WALTID_DATA_ROOT

Command line interface - CLI

In the following sections you will find examples using the command line interface.

Submodule configuration

The IDP Kit consists of multiple submodules, which need to be configured according to your requirements:

    • Provides standard OIDC API endpoints, for communication with client applications

    • Provides presentation exchange and verification with SSI wallets via the OIDC/SIOP protocol

    • Provides communication with NFT wallets and verification of NFT collections and traits

Binding address and port

By default, the IDP Kit exposes its API endpoints bound to localhost on port 8080.

To override the default bindings, set the following environment variables:

WALTID_WALLET_BACKEND_BIND_ADDRESS

WALTID_WALLET_BACKEND_PORT

Note: these variables are inherited from Wallet Kit, which is why they have the term WALLET in it.

Command arguments

To set binding address and port, you can also use the command arguments of the run command like so:

To set the bind address to "192.168.0.1" and the port to 8081:

To bind to all interfaces (on the default port):

NFT Kit JS

The IDP Kit needs to communicate with the NFT Kit JS to process the NFT authorization request. You need to run an NFT Kit JS instance and specify which URL is accessible.

API Keys for NFT verification

The underlying NFT Kit needs a configuration file to be able to verify NFTs for the IDP Kit. Therefore, you need to create a walt.yaml file in the root folder of the IDP Kit.

Only two values must be updated. One of the providers, depending on the network, where the NFT collection is lying and alchemy under the apiKeys section. The privateKey just holds a placeholder value and can stay as it is.

Examples:

  • https://rinkeby.infura.io/v3/0184192d0fd9423b52322d79eca162b2

  • https://polygon-mumbai.g.alchemy.com/v2/yjbYhlaH3U_vfnTiRQ3miGQS0cKwQMGh

EBSI, ESSIF
IDP Kit Configuration
Command Line Interface

The exchange of information between the client, which is in our case the frontend application and the authorization server which is the IDP Kit are based on the OpenID Connect standards. I won't go into more detail here, but you can learn more about it in the or watch this great from OktaDev, which gives a great overview about OpenID Connect. To understand how the base ideas are then translated to the Verifiable Credential use case, you can dive into .

CLI tool commands and options.

To register a new client, we can make a POST request to /api/oidc/clients/register. However, by default the , requires you to authenticate. Providing the master_token in the header of the request makes sure the registration goes through.

API endpoints and options or visit the .

In general, we can configure the claim mappings in the IDP , in the claimConfig property, which contains an array of mapping objects for verifiable credentials: vc_mappings and NFT tokens: nft_mappings.

The default vp token claim contains a presentation_definition object as specified by the DIF specification: .

The IDP Kit uses the OIDC authentication flow, the same technology used by Sign-in with Apple, Facebook, Twitter and many more. If you want to learn more about it and how it works behind the scenes, you can have a look at our as well as how the ideas are translated when using .

- Build and run the project in your local environment

- Retrieve clientId and clientSecret from the IDP Kit, used in the frontend

- Configure scopes and claims for client

- Setup and connect frontend to IDP Kit and enable sign in with Verifiable Credentials

Assuming that you already have a local instance of Keycloak running, we will continue with the configuration of our federated identity provider. In case you need to first, please have a look at their documentation on how to get started.

Important: There are currenlty some issues with the versions >19.0.1 of Keycloak. Please use or Keycloak 20 for a smooth experience.

4. Provide Client ID and Client Secret which we got during the step

To connect to the OIDC APIs, a client application needs to be and has to authenticate itself using its client_id and client_secret.

See section , for details on how to register a client and obtain the client_id and client_secret values.

the client needs to add the client_id and client_secret as header, when calling the pushed authorization request or token endpoints.

  1. Cloning the project

git clone https://github.com/walt-id/waltid-idpkit.git

2. Changing directory

cd waltid-idpkit

3. Open the project in your feavourite IDEA

4. Create a walt.yaml file in the root directory of the project. Values needed are described in the .

5. Building the project

./gradlew build install

6. Creating an alias (optional)

alias idpkit="build/install/waltid-idpkit/bin/waltid-idpkit"
  1. Cloning the project

git clone https://github.com/walt-id/waltid-idpkit.git

2. Changing directory

cd waltid-idpkit

3. Open the project in your feavourite IDEA

4. Create a walt.yaml file in the root directory of the project. Values needed are described in the .

4. Building the project

docker build --rm -t waltid/idpkit .

5. Creating an alias (optional)

alias idpkit="docker run -p 8080:8080 -e WALTID_DATA_ROOT=/data -v $PWD:/data waltid/idpkit"

For more details, visit the .

For a full list of standard claims and scopes, please take a look at the .

The following non-normative example authentication request is taken from the .

profile: request user profile information (see )

email: request user's email address and whether the email address had been verified (see )

Refer to for basic instructions of using the command line interface.

providers: a list of URLs to RPC node provider for every network. You can get them either from or .

alchemy:an API key from .

concept section
illustrative video
Identity provision via SSI
Learn more
registration of new clients via API
Learn more
swagger docs
Presentation Definition
concept section
Verifiable Credentials
IDP Kit Setup
Client Registration
Verifiable Credential Configuration
Next.js
setup Keycloak
Keycloak 18.0.2
client registration
registered
Client registration
Basic HTTP Authorization
JDK 16 build environment
Gradle
Node v.16
configuration section
configuration section
configuration file
https://server.example.com/authorize?
    response_type=code
    &scope=openid%20profile%20email
    &client_id=s6BhdRkqt3
    &state=af0ifjsldkj
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
waltid-idpkit run -b "192.168.0.1" -p 8081
waltid-idpkit run --bind-all
"jsProjectExternalUrl":"http://localhost:4000",
hikariDataSource:
  jdbcUrl: jdbc:sqlite:data/walt.db
  maximumPoolSize: 5
  autoCommit: false
  dataSource:
    journalMode: WAL
    fullColumnNames: false

azureKeyVaultConfig:
  baseURL:
  id:
  secret:

providers:
  ethereum: "ethereum"
  goerli: "goerli"
  polygon: "polygon"
  mumbai: "mumbai"

privateKey: "bd4cb3e507f342ee3a710370cef39dda48f17b0a158b0b8dddf000fbd5b2c2d9"


apiKeys:
  ethereumBlockExplorer: ""
  polygonBlockExplorer: ""
  alchemy: "alchemy_api_key"
  nftstorage: ""

Data Root
OIDC specification
OIDC specification
OIDC specification
CLI | Command line interface
OIDC Manager
SIOP Manager
NFT Manager
Infura
Alchemy
Alchemy
above
above

Next.js

Intro

Create the frontend app

  1. Clone the project

git clone https://github.com/walt-id/waltid-nft-auth-nextjs.git

2. Install the dependencies by running yarn install or npm install

4. Rename .env.example to .env

5. In pages/api/auth/[...nextauth].ts we update the identityProviderURL parameter of the SSIProvider. We can leave the third parameter in the SSIProvider as is, if you have not changed the port on which the IDP Kit is running locally. When you switch the port or use a hosted version of the IDP Kit, you need to update the parameter to reflect the new endpoint of the IDP Kit.

6. Now the project is set up and can be run

yarn dev

//  or 

npm run dev

Keys and signatures

By default, the OIDC Manager creates an RSA key for RS256 token signatures on first startup. On subsequent startups, the same key will be used again.

If you want to enforce a certain key or key type for token signatures, you may use the config command, providing the key management functions of the SSI Kit to create a key.

The following key and token signature types are currently supported:

Signature
Key
Hash

RS256

RSA 2048

SHA256

EdDSA

EdDSA_Ed25519

SHA256

ES256K

ECDSA_Secp256k1

SHA256

The chosen key type implicitely defines the signature and hash type, according to the table above.

Generate key

In the following example, I will show how to manually create an RSA key for the OIDC manager using the config command of the IDP Kit:

waltid-idpkit config --oidc key gen -a RSA

This command will generate an RSA key, save it in the key store, in the context of the OIDC manager, and prints the key ID:

Output:

[...]
[main] INFO id.walt.idp.cli.ConfigCmd - Running in context of: OIDCContext
Generating RSA key pair...
[main] DEBUG id.walt.services.keystore.HKVKeyStoreService - Storing key "715b3ebf65074f1183a48c4b7c8e311c".
Key "715b3ebf65074f1183a48c4b7c8e311c" generated.

List available keys

To list all the available keys in the OIDC Manager context, you can type:

waltid-idpkit config --oidc key list

Output:

[...]
Listing keys ...

Results:
[...]
- 1: "e8392ed7e8524b34bc4ab7609c2f6d99" (Algorithm: "RSA", provided by "SUN")
- 2: "715b3ebf65074f1183a48c4b7c8e311c" (Algorithm: "RSA", provided by "SUN")

Configure key

{
  [...]
  "keyId": "715b3ebf65074f1183a48c4b7c8e311c",
  [...]
}

SIOP Manager configuration

In this section we look at the configuration of the SIOP Manager sub module.

Verifier backend configuration

Therefore, we require the same configuration of the verifier component as documented in the Wallet Kit documentation, in the file

config/verifier-config.json

In order to avoid duplication, please refer to the Wallet Kit documentation for details on how to configure:

Config command

In order to execute the config command in the SIOP Manager context, use the following command:

waltid-idpkit config --siop

Verification policies

Note, that the IDP Kit requires a different config command flag than the Wallet Kit for configuring the SIOP manager:

waltid-idpkit config --siop vc policies --help

Configuration example

Here's a complete example for the verifier-config.json:

{
  "verifierUiUrl": "https://verifier.waltid.org",
  "verifierApiUrl": "https://verifier.waltid.org/verifier-api",
  "additionalPolicies": [
    {
      "policy": "JsonSchemaPolicy"
    }
  ],
  "wallets": {
    "walt.id": {
      "id": "walt.id",
      "url": "https://wallet.waltid.org",
      "presentPath": "api/wallet/siopv2/initPresentation/",
      "receivePath" : "api/wallet/siopv2/initPassiveIssuance/",
      "description": "walt.id web wallet"
    }
  }
}

Client registration

The IDP Kit provides a command line interface (CLI) to register and manage clients. Furthermore, the dynamic client registration and management APIs are provided, according to the specifications in:

Authentication for dynamic client registration API

To register a new client via the dynamic client registration API, authentication using the registration access token is required by default. The IDP Kit can be configured to allow unauthenticated client registration.

Registration access token

To get this registration access token use the command:

waltid-idpkit config --oidc clients token

Output

[...]
Client registration master token:
eyJraWQiOiJhNGFhM2U4MT[...]nE3jfPqMQlgEhh6l0VbwhbsDjy7Q

Open client registration

{
  [...]
  "openClientRegistration": true,
  [...]
}

Authentication for existing client management

Register new client

CLI

To register a new client use the register command, like e.g.:

waltid-idpkit config --oidc clients register -n "MyApp" -r "https://myapp.com/redirect_uri"

To specify multiple redirect_uris, repeat the -r ... flag for each URI.

Use --all-redirect-uris and omit the -r ... flags, to allow all redirect URIs for this client.

Use -u <client_id> to update an existing client by its ID, instead of creating a new registration.

REST API

[POST] /api/oidc/clients/register

POST /api/oidc/clients/register HTTP/1.1
[...]
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJ[...]

{
  "client_name": "MyApp",
  "redirect_uris": [
    "https://myapp.com/redirect_uri"
  ],
  "all_redirect_uris": false
}

Result

Example:

{
    "client_secret_expires_at":0,
    "all_redirect_uris":false,
    "registration_client_uri":"https://[...]/api/oidc/clients/EI_9T[...]",
    "client_id_issued_at":1658239641,
    "client_secret":"884DUlIj4[...]",
    "redirect_uris":[
        "https://myapp.com/redirect_uri"
    ],
    "registration_access_token":"eyJraWQi[...]",
    "client_id":"EI_9TT[...]"
}

This example response has the following properties:

  • client_secret_expires_at: Expiration timestamp of client secret, or 0 if no expiration

  • all_redirect_uris: Specific to IDP Kit: allow all redirect URIs for this client if redirect_uris is empty or not set

  • registration_client_uri: URI of API to get, update or delete this client information

  • registration_access_token: access token for using registration_client_uri API to get, update or delete this client information

  • client_id_issued_at: Timestamp of first registration of this client

  • client_secret: Client secret to use for token endpoint authentication method

  • client_id: Client id to use for token endpoint authentication method

  • redirect_uris: Array of redirect URIs that are allowed for this client

List registered clients

To list all registered clients, type

waltid-idpkit config --oidc clients list

This will output a list of keys and client information objects for all registered clients:

Output

[...]
* EI_9TTRXw0C7gzKNLNfwNEMH1jChqzj-l0n4LUWxYm4:
{
    "client_secret_expires_at":0,
    [...]
    "client_id":"EI_9TTRXw0C7gzKNLNfwNEMH1jChqzj-l0n4LUWxYm4"
}
--------------------
* [...]

Get client information by ID

CLI

To get a client information by the client ID, use this command, specifying the ID via the -i ... command argument:

waltid-idpkit config --oidc clients get -i 6s5YcV84Tg7cZ8BM2-b6qcJiHKDTZD8YdQt-cf4eDbM

REST API

[GET] /api/oidc/clients/<client_id>

Result

Update client registration

CLI

waltid-idpkit config --oidc clients register -n "MyApp" -r "https://myapp.com/UPDATED_URI" -u EI_9TTRXw0C7gzKNLNfwNEMH1jChqzj-l0n4LUWxYm4

All required parameters MUST be specified in the update command, as the existing registration will be replaced but not merged with parameters given in this command!

REST API

[PUT] /api/oidc/clients/<client_id>

All required parameters MUST be included in the update request body, as the existing registration will be replaced but not merged with object given in the update request!

Result

Remove client registration

CLI

Use the remove command to unregister an existing client registration:

waltid-idpkit config --oidc clients remove -i EI_9TTRXw0C7gzKNLNfwNEMH1jChqzj-l0n4LUWxYm4

Example output

[...]
[main] INFO id.walt.idp.oidc.OIDCClientRegistry - Unregistering client EI_9TTRXw0C7gzKNLNfwNEMH1jChqzj-l0n4LUWxYm4
Client removed

REST API

[DELETE] /api/oidc/clients/<client_id>

The result of a successful delete request, is an empty response with the HTTP response code 204 No Content.

Tezos | Identity provision via NFTs

The IDP Kit supports retrieval and verification of NFTs from Tezos ledger.

This section will explain the principles of how OIDC authentication requests are translated into NFT requests and the options available to craft such requests.

The IDP Kit transforms the ownership of NFT on the Tezos ledger into an identity access management solution. The implementation is based on three main aspects: OIDC, SIWT, NFT, and their metadata.

Any client application can use the IDP Kit to grant access to a service via the ownership of an NFT on the Tezos ledger. The IDK Kit extends the verification of the NFT ownership by applying policies to the NFT metadata via an open policy agent(OPA).

How it works

OIDC via NFTs

The whole verification process has seven main steps:

  1. The client application redirects the user to the IDP Kit. It is a verification request based on the OIDC standard.

  2. The IDP Kit processes the verification request. If it is an NFT Tezos verification, the IDP Kit redirects the user to his user interface.

  3. Then, the user must connect to his wallet. He shares his address with the IDP Kit and signs a message based on the SIWT process.

  4. The SIWT process continues within the IDP Kit by verifying the user address and the message signature.

  5. After that, the IDP Kit will verify that the user has an NFT in a specified collection within the Tezos ledger. The NFT collection information is defined in the IDP Kit configuration file.

  6. If the NFT metadata policy verification is activated, The IDP Kit will load the NFT metadata and run an OPA policy with the NFT metadata. The OPA policy is specified in the configuration file.

  7. In the last step, the IDP Kit redirects the user to the client application with a response of the whole verification with extra information like the account address. This is based on the OIDC standard.

The authorization flow visualized

  • OpenID Connect(OIDC) is used as the protocol between any client application and the IDP Kit. It is used by the client application to make an NFT ownership verification request. The IDP Kit will well interpret the request. It is also used within the verification response by the IDP Kit to the client application.

  • SIWT is used to verify that the user controls and owns the private key of a Tezos account.

  • We can apply policies to the NFT metadata based on the Open policy agent(OPA).

Claiming nft_token

In this scenario, the client application requests the raw NFT data, without mapping to standard OIDC claims, by specifying the custom nft_token claim or defining the nft_token scope in the authorization request.

nft_token Scope

By specifying the nft_token scope in the authorization request, the client application requests the validation of the user being a holder of an NFT in the required NFT collection and the user info to be included in the response. The IDP Kit will determine the NFT request, which is sent to the NFT wallet, by the following sources in this order:

  1. nft_token claim, specified by the client application as a custom claim object in the authorization request

nft_token Claim

The nft_token claim should be constructed as follows:

Authorization POST request:

When making the authorization post request, the client can specify a claim field in the body, with a value describing the NFT collection. The format will be as follows:

Authorization GET request:

When making the authorization get request, the client can specify a claim field, as shown in the example above, in a JSON object. This object will then be sent URL encoded via the query parameters.

Standard OIDC scopes, claims and claim mapping

In this scenario, the client application simply makes a standard OIDC authorization request, like any other OIDC compliant identity provider would expect it. E.g. the application could request the profile scope, to receive name, given name, family name, gender, date of birth, etc. of the user from the IDP Kit.

The IDP Kit maps the required claims to suitable traits in the NFT metadata that contain the requested information, by getting access to the NFT through the shared address of the user. The gathering of the user address will be handled by a separate wallet connect page (web application), without the client taking any notice.

Once the IDP Kit has received the address of the user from the wallet connect page, got the information from the NFTs metadata and verified all of it. The IDP Kit translates the received data into the standard user info claims requested by the application and provides it on the standard user info endpoint.

To use this flow, the client application needs no additional knowledge about the underlying protocol. In most cases, a simple configuration change would suffice to make an application connect to the IDP Kit and accept NFT data for user authentication, given that OIDC is already used as an authentication layer.

Identity provision via SSI

The IDP Kit supports retrieval of identity data from SSI wallets and verifiable credentials.

In this section I'm going to outline the principles of how OIDC authentication requests are translated to SSI/SIOP requests and the various options a user has to make such a request.

How it works

OIDC via SSI

When using SSI and verifiable credentials as information source, the IDP Kit will derive the required credentials from the authentication request and redirect to the SSI wallet, requesting a presentation of the required credentials, via the OIDC/SIOPv2 presentation exchange protocol.

Once the SSI wallet responds with the requested presentation, the IDP Kit will verify the signature, challenge and compliance of the response with the requirements and optionally apply other verification policies, as defined in the IDP Kit configuration.

The verified credential data is then transformed into the response format requested by the application, which can be standard claims (name, email, etc.) or the verifiable presentation containing the raw credential data shared by the SSI wallet of the user.

This sequence diagram shows the OIDC code flow, leveraging identity provision via SSI using the OIDC/SIOPv2 protocol to obtain a credential presentation from an SSI wallet:

Claiming vp_token

In this scenario, the client application requests the raw credential data, without mapping to standard OIDC claims, by specifying the custom vp_token claim or defining the vp_token scope in the authorization request.

vp_token Scope

By specifying the vp_token scope in the authorization request, the client application requests a verifiable presentation to be requested from the user and included in the user info response. The IDP Kit will determine the verifiable presentation request, which is sent to the SSI wallet, by the following sources in this order:

  1. Empty verifable presentation, if none of the above applies. In this case only the user DID is verified (DID proof) and propagated into the user info as user ID.

vp_token Claim

To use this authentication flow, the client application needs to construct the special vp_token claim and be able to interpret the presentation response. Verification of signatures, and compliance with the request is provided by the IDP Kit, such that the application can rely on the data received.

The following flow diagram outlines an OIDC code flow with vp_token claim:

Standard OIDC scopes, claims and claim mapping

In this scenario, the client application simply makes a standard OIDC authorization request, like any other OIDC compliant identity provider would expect it. E.g. the application could request the profile scope, to receive name, given name, family name, gender, date of birth, etc. of the user from the IDP Kit.

The IDP Kit maps the required claims to suitable credential types that contain the requested information and generates a SIOP request for the SSI wallet transparently, without the client application taking any notice.

Once the IDP Kit and the SSI Wallet have completed the presentation exchange and the presented credentials have been verified, the IDP Kit translates the received credential data into the standard user info claims requested by the application and provides it on the standard user info endpoint.

To use this flow, the client application needs no additional knowledge about the underlying protocol. In most cases, a simple configuration change would suffice to make an application connect to the IDP Kit and accept SSI identity data for user authentication, given that OIDC is already used as an authentication layer.

This flow diagram outlines an OIDC code flow with standard claim mapping using identity provision via SSI:

We have prepared a which we can use as a starting point. It uses NextAuth.js for handling authentication and a custom provider build by to connect the IDP Kit easily with NextAuths functionality. We won't go into details of how Next.js or NextAuth.js works.

We will need and or npm

3. Update CLIENT_ID and CLIENT_SECRET based on the response returned by the in the .env.example file.

Now, to configure the key generated above, copy the key ID printed by the command, and paste it into the , like so:

If you haven't already, you may want to familiarize yourself with the basic , the and the , in the previous sections, before moving on.

The SIOP Manager is derived from the Verifer Manager in the Verifier backend component of the .

Refer to , in the Wallet Kit documentation, to understand how to manage SSI verification policies.

This will output a valid JWT token to use with the API endpoint, like this:

To allow unauthenticated client registration requests via the REST API, set the following in the idp-config.json:

For managing registered clients, i.e. get, update or removal of client information, via the dynamic client management API, you have to use the registration_client_uri and registration_access_token as returned by the response for the specific client.

The , for registering new clients, does NOT grant permission to manage existing client registrations!

Post a object to this endpoint, using the described above, like shown in this simple example:

If is enabled, the registration access token in the Authorization header can be omitted in this request.

In case of success, the CLI and REST API will output a client information object, corresponding to the client registration response from the OIDC spec: .

Each listed object corresponds to the client registration response, described in the section .

To get the client info via the dynamic client management API, make a GET call to the registration_client_uri using the registration_access_token given in the client information obtained from the initial or the latest .

Clients use the registration_client_uri as returned by the server in the registration response object, and MUST NOT construct the URL from component pieces, such as API endpoint and client ID.

The output is a client information object, that corresponds to the client registration response, described in the section .

To update an existing client registration use the -u ... command flag of the , like so:

Post the updated client information, including all required parameters, to the registration_client_uri using the HTTP PUT method and the registration_access_token given in the client information obtained from the initial or the latest .

Clients use the registration_client_uri as returned by the server in the registration response object, and MUST NOT construct the URL from component pieces, such as API endpoint and client ID.

The output is a client information object, with the updated registration information, that corresponds to the client registration response, described in the section .

To unregister the client via the dynamic client management API, make a DELETE request to the registration_client_uri using the registration_access_token given in the client information obtained from the initial or the latest .

Clients use the registration_client_uri as returned by the server in the registration response object, and MUST NOT construct the URL from component pieces, such as API endpoint and client ID.

To understand how identity provision via NFTs can be leveraged in an OIDC authentication flow, you may first want to recap on the basic principles of .

Derived from nft_mappings defined in the IDP Kit , based on the scopes and claims requested in the authorization request

NFT token claim, configured in thedefault_nft_token_claim in the IDP Kit

To understand how identity provision via SSI can be leveraged in an OIDC authentication flow, you may first want to recap on the basic principles of .

, specified by the client application as a custom claim object in the authorization request

Derived from vc_mappings defined in the IDP Kit , based on the scopes and claims requested in the authorization request

VP token claim, configured in the default_vp_token_claim in the IDP Kit

The vp_token claim should be a presentation definition object, as defined in the .

The IDP simply forwards the presentation definition via the SIOPv2 protocol to a compatible SSI wallet. When the is received, the presentation is verified and provided to the client application in the user info's vp_token property.

Next.js example project
walt.id
Node.js
yarn
client registration step
Wallet Kit
External URLs
Known SSI wallets
Verification Policies
Verification Policies
OpenID Connect Dynamic Client Registration
OAuth 2.0 Dynamic Client Registration Management Protocol [RFC7592]
Client Registration Response
MUST
MUST
MUST
configuration file
configuration option
IDP Kit Configuration
Command Line Interface
Data Root
register
client registration
registration access token
client registration request
registration access token
open client registration
Register new client
client registration
client update
Register new client
register command
client registration
client update
Register new client
client registration
client update
"claim": {
  "nft_token": {
    // blockain identifier
    "chain":"GHOSTNET",
    // the smart contract representing the NFT collection
    "smartContractAddress":"KT1Ennr99qgqzKEUCEqypXEexH4wWzVL5a9m"
  }
}
OIDC authentication
claim configuration
claim configuration
OIDC authentication
claim configuration
claim configuration
specification of OIDC/SIOPv2
SIOP response
vp_token claim

Sign-in with Near Protocol (SIWN)

Sign-In with Near Protocol describes how Near accounts authenticate with off-chain services by signing a message parameterized by scope, nonce, etc. It is an alternative to centralized identity providers. It is based on the self-custody of your identity. It leverages the on-chain authentication model to off-chain services.

The reason behind implementing the concept Sign-In with Near is that it is a critical step in the Login with NFTs concept. Before granting access to some services based on the ownership of some NFTs, we need to check two main aspects:

  • You own an account via Sign with Near.

  • Verify that the account has an NFT in a specified collection.

An account in Near is linked to the ownership of a private key which is then mapped to his public key. The hash of the public key outputs an address.

The IDP Kit implements SIWN based on seven main steps:

  1. Nonce generation.

  2. Redirection to the IDK Kit wallet user interface.

  3. Connect to your Near wallet.

  4. A popup appears for signing the message. It is based on multiple factors like the nonce generated by the IDP Kit, account address, etc.

  5. Click the “Sign” button.

  6. Redirection to the IDK Kit verification service.

  7. The IDP Kit verifies the message signature based on the account address.

The message will be in the form of:

{domain} wants you to sign in with your Near account: {address}. Public Key: {publicKey}.Date: {ISO8601formatedTimestamp}. {description} URI: {origin}. Version: {versionNumber}. Nonce: {nonce}

  • domain: is the RFC 3986 authority that is requesting the signing.

  • Permissions.address: account address.

  • Public Key : account public key.

  • Date: is the ISO 8601 datetime string of the current time.

  • Nonce:security parameter generated by the IDP Kit.

Identity provision via NFTs

Choose Ecosystem

Sign in With Ethereum (SIWE)

The IDP Kit supports Sign In With Ethereum (SIWE).

This section will explain the principles of how OIDC authentication requests are translated into SIWE requests and the options available to craft such requests.

How it works

OIDC via SIWE

When using SIWE as information source, the client application needs to specify the custom siwe claim in the authorization request.

The IDP Kit then takes the request and opens a wallet connect page, where the user is prompted to connect their wallet to the page and share their address. The shared address will then be sent back to the IDP Kit, which verifies that the user is the rightful owner.

After verification, the IDP Kit sends the account address back to the client application in the siwe property of the user info.

The application can rely on the received data, as the IDP Kit is verifying the ownership of the address.

EVM | Identity Provision

The IDP Kit supports retrieval and verification of NFTs from wallets.

This section will explain the principles of how OIDC authentication requests are translated into NFT requests and the options available to craft such requests.

How it works

OIDC via NFTs

When using NFTs as information source, the IDP Kit will derive the required NFT collection from the authentication request and redirect to an application, where the user can connect his wallet and share their address.

The verified data is then transformed into the response format requested by the application, which by default will include the account address and optionally specified metadata of the NFT.

The authorization flow visualized

Claiming nft_token

In this scenario, the client application requests the raw NFT data, without mapping to standard OIDC claims, by specifying the custom nft_token claim or defining the nft_token scope in the authorization request.

nft_token Scope

By specifying the nft_token scope in the authorization request, the client application requests the validation of the user being a holder of an NFT in the required NFT collection and the user info to be included in the response. The IDP Kit will determine the NFT request, which is sent to the NFT wallet, by the following sources in this order:

  1. nft_token claim, specified by the client application as a custom claim object in the authorization request

nft_token Claim

The nft_token claim should be constructed as follows:

Authorization POST request:

When making the authorization post request, the client can specify a claim field in the body, with a value describing the NFT collection. The format will be as follows:

"claim": {
  "nft_token": {
    // blockain identifier
    "chain":"MUMBAI",
    // the smart contract representing the NFT collection
    "smartContractAddress":"0xf277BE034881eE38A9b270E5b6C5c6f333Af2517"
  }
}

Authorization GET request:

When making the authorization get request, the client can specify a claim field, as shown in the example above, in a JSON object. This object will then be sent URL encoded via the query parameters.

IDP Kit receiving the request

The IDP Kit takes the request and opens a wallet connect page, where the user is prompted to connect their wallet to the page and share their address. The shared address will then be sent back to the IDP Kit, which verifies that the user is the rightful owner and holder of an NFT of the required NFT collection. After verification, the IDP Kit sends the information (account address/nft metadata) back to the client application in the nft_token property of the user info.

The application can rely on the received data, as the IDP Kit is verifying the ownership of NFT and address.

Standard OIDC scopes, claims and claim mapping

In this scenario, the client application simply makes a standard OIDC authorization request, like any other OIDC compliant identity provider would expect it. E.g. the application could request the profile scope, to receive name, given name, family name, gender, date of birth, etc. of the user from the IDP Kit.

The IDP Kit maps the required claims to suitable traits in the NFT metadata that contain the requested information, by getting access to the NFT through the shared address of the user. The gathering of the user address will be handled by a separate wallet connect page (web application), without the client taking any notice.

Once the IDP Kit has received the address of the user from the wallet connect page, got the information from the NFTs metadata and verified all of it. The IDP Kit translates the received data into the standard user info claims requested by the application and provides it on the standard user info endpoint.

To use this flow, the client application needs no additional knowledge about the underlying protocol. In most cases, a simple configuration change would suffice to make an application connect to the IDP Kit and accept NFT data for user authentication, given that OIDC is already used as an authentication layer.

Sign-in with Polkadot (SIWP)

Sign-In with Polkadot Blockchain describes how polkadot accounts authenticate with off-chain services by signing a message parameterized by scope, nonce, etc. It is an alternative to centralized identity providers. It is based on the self-custody of your identity. It leverages the on-chain authentication model to off-chain services.

The reason behind implementing the concept Sign-In with Polkadot is that it is a critical step in the Login with NFTs concept. Before granting access to some services based on the ownership of some NFTs, we need to check two main aspects:

  • You own an account via Sign with Polkadot.

  • Verify that the account has an NFT in a specified collection.

An account in Polkadot is linked to the ownership of a private key which is then mapped to his public key. The hash of the public key outputs an address.

The IDP Kit implements SIWP based on seven main steps:

  1. Nonce generation.

  2. Redirection to the IDK Kit wallet user interface.

  3. Connect to your polkadot wallet.

  4. A popup appears for signing the message. It is based on multiple factors like the nonce generated by the IDP Kit, account address, etc.

  5. Click the “Sign” button.

  6. Redirection to the IDK Kit verification service.

  7. The IDP Kit verifies the message signature based on the account address.

The message will be in the form of:

{domain} wants you to sign in with your Polkadot account: {address}. Public Key: {publicKey}.Date: {ISO8601formatedTimestamp}. {description} URI: {origin}. Version: {versionNumber}. Nonce: {nonce}

  • domain: is the RFC 3986 authority that is requesting the signing.

  • Permissions.address: account address.

  • Public Key : account public key.

  • Date: is the ISO 8601 datetime string of the current time.

  • Nonce: security parameter generated by the IDP Kit.

Near | Identity provision via NFTs

This section will explain the principles of how OIDC authentication requests are translated into NFT requests and the options available to craft such requests.

The IDP Kit transforms the ownership of NFT on the Near Protocol into an identity access management solution. The implementation is based on three main aspects: OIDC, SIWN, NFT, and their metadata.

Any client application can use the IDP Kit to grant access to a service via the ownership of an NFT on the Near Protocol. The IDK Kit extends the verification of the NFT ownership by applying policies to the NFT metadata via an open policy agent(OPA).

How it works

OIDC via NFTs

The whole verification process has seven main steps:

  1. The client application redirects the user to the IDP Kit. It is a verification request based on the OIDC standard.

  2. The IDP Kit processes the verification request. If it is an NFT Near Protocol verification, the IDP Kit redirects the user to his user interface.

  3. Then, the user must connect to his wallet. He shares his address with the IDP Kit and signs a message based on the SIWN process.

  4. The SIWN process continues within the IDP Kit by verifying the user address and the message signature.

  5. After that, the IDP Kit will verify that the user has an NFT in a specified collection within the Near Protocol Blockchain. The NFT collection information is defined in the IDP Kit configuration file.

  6. If the NFT metadata policy verification is activated, The IDP Kit will load the NFT metadata and run an OPA policy with the NFT metadata. The OPA policy is specified in the configuration file.

  7. In the last step, the IDP Kit redirects the user to the client application with a response of the whole verification with extra information like the account address. This is based on the OIDC standard.

The authorization flow visualized

  • OpenID Connect(OIDC) is used as the protocol between any client application and the IDP Kit. It is used by the client application to make an NFT ownership verification request. The IDP Kit will well interpret the request. It is also used within the verification response by the IDP Kit to the client application.

  • SIWN is used to verify that the user controls and owns the private key of a Near account.

  • We can apply policies to the NFT metadata based on the Open policy agent(OPA).

Claiming nft_token

In this scenario, the client application requests the raw NFT data, without mapping to standard OIDC claims, by specifying the custom nft_token claim or defining the nft_token scope in the authorization request.

nft_token Scope

By specifying the nft_token scope in the authorization request, the client application requests the validation of the user being a holder of an NFT in the required NFT collection and the user info to be included in the response. The IDP Kit will determine the NFT request, which is sent to the NFT wallet, by the following sources in this order:

  1. nft_token claim, specified by the client application as a custom claim object in the authorization request

nft_token Claim

The nft_token claim should be constructed as follows:

Authorization POST request:

When making the authorization post request, the client can specify a claim field in the body, with a value describing the NFT collection. The format will be as follows:

Authorization GET request:

When making the authorization get request, the client can specify a claim field, as shown in the example above, in a JSON object. This object will then be sent URL encoded via the query parameters.

Standard OIDC scopes, claims and claim mapping

In this scenario, the client application simply makes a standard OIDC authorization request, like any other OIDC compliant identity provider would expect it. E.g. the application could request the profile scope, to receive name, given name, family name, gender, date of birth, etc. of the user from the IDP Kit.

The IDP Kit maps the required claims to suitable traits in the NFT metadata that contain the requested information, by getting access to the NFT through the shared address of the user. The gathering of the user address will be handled by a separate wallet connect page (web application), without the client taking any notice.

Once the IDP Kit has received the address of the user from the wallet connect page, got the information from the NFTs metadata and verified all of it. The IDP Kit translates the received data into the standard user info claims requested by the application and provides it on the standard user info endpoint.

To use this flow, the client application needs no additional knowledge about the underlying protocol. In most cases, a simple configuration change would suffice to make an application connect to the IDP Kit and accept NFT data for user authentication, given that OIDC is already used as an authentication layer.

This documentation section will dive deep into implementing the Sign-in with Near Protocol(SIWN). For more details about the concept Sign in With X (SIWx), .

To understand how identity provision via SIWE can be leveraged in an OIDC authentication flow, you may first want to recap on the basic principles of .

To understand how identity provision via NFTs can be leveraged in an OIDC authentication flow, you may first want to recap on the basic principles of .

After the user has shared their address, the application will send it back to the IDP Kit, where the NFT Manager will make sure that the user is the rightful owner of that shared address, by utilizing the concepts described in, and that the shared address is associated with the required NFT collection sent in the authentication request. Have a look at the page to see how this can be configured and which defaults can be set.

Derived from nft_mappings defined in the IDP Kit , based on the scopes and claims requested in the authorization request

NFT token claim, configured in thedefault_nft_token_claim in the IDP Kit

This documentation section will dive deep into implementing the Sign-in with Polkadot(SIWP). For more details about the concept Sign in With X (SIWx), .

To understand how identity provision via NFTs can be leveraged in an OIDC authentication flow, you may first want to recap on the basic principles of .

Derived from nft_mappings defined in the IDP Kit , based on the scopes and claims requested in the authorization request

NFT token claim, configured in thedefault_nft_token_claim in the IDP Kit

CAIP-122

Algorand

Ethereum / Polygone

Tezos

Near

Polkadot

Flow

OIDC authentication
OIDC authentication
EIP-4361: Sign-In with Ethereum
NFT Manager configuration
claim configuration
claim configuration
"claim": {
  "nft_token": {
    // blockain identifier
    "chain":"TESTNET",
    // the smart contract representing the NFT collection
    "smartContractAddress":"nft.waltid.testnet"
  }
}
CAIP-122
OIDC authentication
claim configuration
claim configuration
SSI Kit documentation

Sign-In with Tezos (SIWT)

Sign-In with Tezos describes how Tezos accounts authenticate with off-chain services by signing a message parameterized by scope, nonce, etc. It is an alternative to centralized identity providers. It is based on the self-custody of your identity. It leverages the on-chain authentication model to off-chain services.

The reason behind implementing the concept Sign-In with Tezos is that it is a critical step in the Login with NFTs concept. Before granting access to some services based on the ownership of some NFTs, we need to check two main aspects:

  • You own an account via Sign with Tezos.

  • Verify that the account has an NFT in a specified collection.

An account in Tezos is linked to the ownership of a private key which is then mapped to his public key. The hash of the public key outputs an address. Depending on the chosen Digital Signature Algorithm's elliptic curve (see ECDSA), the latter starts with "tz1" (Ed25519 curve), "tz2" (Secp256k1 curve), or "tz3" (P256 curve).

The IDP Kit implements SIWT based on seven main steps:

  1. Nonce generation.

  2. Redirection to the IDK Kit wallet user interface.

  3. Connect to your Temple wallet.

  4. A popup appears for signing the message. It is based on multiple factors like the nonce generated by the IDP Kit, account address, etc.

  5. Click the “Sign” button.

  6. Redirection to the IDK Kit verification service.

  7. The IDP Kit verifies the message signature based on the account address.

The message will be in the form of:

{domain} wants you to sign in with your Tezos account: {address}. Public Key: {publicKey}.Date: {ISO8601formatedTimestamp}. {description} URI: {origin}. Version: {versionNumber}. Nonce: {nonce}

  • domain: is the RFC 3986 authority that is requesting the signing.

  • Permissions.address: account address.

  • Public Key : account public key.

  • Date: is the ISO 8601 datetime string of the current time.

  • Nonce:security parameter generated by the IDP Kit.

Algorand | Identity provision via NFTs

This section will explain the principles of how OIDC authentication requests are translated into NFT requests and the options available to craft such requests.

The IDP Kit transforms the ownership of NFT on Polkadot into an identity access management solution. The implementation is based on three main aspects: OIDC, SIWA, NFT, and their metadata.

Any client application can use the IDP Kit to grant access to a service via the ownership of an NFT on the Algorand Blockchain. The IDK Kit extends the verification of the NFT ownership by applying policies to the NFT metadata via an open policy agent(OPA).

How it works

OIDC via NFTs

The whole verification process has seven main steps:

  1. The client application redirects the user to the IDP Kit. It is a verification request based on the OIDC standard.

  2. The IDP Kit processes the verification request. If it is an NFT Flow verification, the IDP Kit redirects the user to his user interface.

  3. Then, the user must connect to his wallet. He shares his address with the IDP Kit and signs a message based on the SIWA process.

  4. The SIWA process continues within the IDP Kit by verifying the user address and the message signature.

  5. After that, the IDP Kit will verify that the user has an NFT in a specified collection within the Algorand Blockchain. The NFT collection information is defined in the IDP Kit configuration file.

  6. If the NFT metadata policy verification is activated, The IDP Kit will load the NFT metadata and run an OPA policy with the NFT metadata. The OPA policy is specified in the configuration file.

  7. In the last step, the IDP Kit redirects the user to the client application with a response of the whole verification with extra information like the account address. This is based on the OIDC standard.

The authorization flow visualized

  • OpenID Connect(OIDC) is used as the protocol between any client application and the IDP Kit. It is used by the client application to make an NFT ownership verification request. The IDP Kit will well interpret the request. It is also used within the verification response by the IDP Kit to the client application.

  • SIWA is used to verify that the user controls and owns the private key of an Algorand account.

  • We can apply policies to the NFT metadata based on the Open policy agent(OPA).

Claiming nft_token

In this scenario, the client application requests the raw NFT data, without mapping to standard OIDC claims, by specifying the custom nft_token claim or defining the nft_token scope in the authorization request.

nft_token Scope

By specifying the nft_token scope in the authorization request, the client application requests the validation of the user being a holder of an NFT in the required NFT collection and the user info to be included in the response. The IDP Kit will determine the NFT request, which is sent to the NFT wallet, by the following sources in this order:

  1. nft_token claim, specified by the client application as a custom claim object in the authorization request

nft_token Claim

The nft_token claim should be constructed as follows:

Authorization POST request:

When making the authorization post request, the client can specify a claim field in the body, with a value describing the NFT collection. The format will be as follows:

"claim": {
  "nft_token": {
    // blockain identifier
    "chain":"",
    // the smart contract representing the NFT collection
    "smartContractAddress": "",
    // the path where nft is stored
    "collectionPath": ""
  }
}

Authorization GET request:

When making the authorization get request, the client can specify a claim field, as shown in the example above, in a JSON object. This object will then be sent URL encoded via the query parameters.

Standard OIDC scopes, claims and claim mapping

In this scenario, the client application simply makes a standard OIDC authorization request, like any other OIDC compliant identity provider would expect it. E.g. the application could request the profile scope, to receive name, given name, family name, gender, date of birth, etc. of the user from the IDP Kit.

The IDP Kit maps the required claims to suitable traits in the NFT metadata that contain the requested information, by getting access to the NFT through the shared address of the user. The gathering of the user address will be handled by a separate wallet connect page (web application), without the client taking any notice.

Once the IDP Kit has received the address of the user from the wallet connect page, got the information from the NFTs metadata and verified all of it. The IDP Kit translates the received data into the standard user info claims requested by the application and provides it on the standard user info endpoint.

To use this flow, the client application needs no additional knowledge about the underlying protocol. In most cases, a simple configuration change would suffice to make an application connect to the IDP Kit and accept NFT data for user authentication, given that OIDC is already used as an authentication layer.

Sign-in with Algorand (SIWA)

Sign-In with Algorand Blockchain describes how Algorand accounts authenticate with off-chain services by signing a message parameterized by scope, nonce, etc. It is an alternative to centralized identity providers. It is based on the self-custody of your identity. It leverages the on-chain authentication model to off-chain services.

The reason behind implementing the concept Sign-In with Algorand is that it is a critical step in the Login with NFTs concept. Before granting access to some services based on the ownership of some NFTs, we need to check two main aspects:

  • You own an account via Sign with Algorand.

  • Verify that the account has an NFT in a specified collection.

An account in Algorand is linked to the ownership of a private key which is then mapped to his public key. The hash of the public key outputs an address.

The IDP Kit implements SIWA based on seven main steps:

  1. Nonce generation.

  2. Redirection to the IDK Kit wallet user interface.

    1. Connect to your Algorand wallet.

  3. A popup appears for signing the message. It is based on multiple factors like the nonce generated by the IDP Kit, account address, etc.

  4. Click the “Sign” button.

  5. Redirection to the IDK Kit verification service.

  6. The IDP Kit verifies the message signature based on the account address.

The message will be in the form of:

{domain} wants you to sign in with your Algorand account: {address}. Public Key: {publicKey}.Date: {ISO8601formatedTimestamp}. {description} URI: {origin}. Version: {versionNumber}. Nonce: {nonce}

  • domain: is the RFC 3986 authority that is requesting the signing.

  • Permissions.address: account address.

  • Public Key : account public key.

  • Date: is the ISO 8601 datetime string of the current time.

  • Nonce: security parameter generated by the IDP Kit.

Polkadot | Identity provision via NFTs

This section will explain the principles of how OIDC authentication requests are translated into NFT requests and the options available to craft such requests.

The IDP Kit transforms the ownership of NFT on Polkadot into an identity access management solution. The implementation is based on three main aspects: OIDC, SIWP, NFT, and their metadata.

Any client application can use the IDP Kit to grant access to a service via the ownership of an NFT on the Polkadot Blockchain. The IDK Kit extends the verification of the NFT ownership by applying policies to the NFT metadata via an open policy agent(OPA).

How it works

OIDC via NFTs

The whole verification process has seven main steps:

  1. The client application redirects the user to the IDP Kit. It is a verification request based on the OIDC standard.

  2. The IDP Kit processes the verification request. If it is an NFT Polkadot verification, the IDP Kit redirects the user to his user interface.

  3. Then, the user must connect to his wallet. He shares his address with the IDP Kit and signs a message based on the SIWP process.

  4. The SIWP process continues within the IDP Kit by verifying the user address and the message signature.

  5. After that, the IDP Kit will verify that the user has an NFT in a specified collection within the Polkadot Blockchain. The NFT collection information is defined in the IDP Kit configuration file.

  6. If the NFT metadata policy verification is activated, The IDP Kit will load the NFT metadata and run an OPA policy with the NFT metadata. The OPA policy is specified in the configuration file.

  7. In the last step, the IDP Kit redirects the user to the client application with a response of the whole verification with extra information like the account address. This is based on the OIDC standard.

The authorization flow visualized

  • OpenID Connect(OIDC) is used as the protocol between any client application and the IDP Kit. It is used by the client application to make an NFT ownership verification request. The IDP Kit will well interpret the request. It is also used within the verification response by the IDP Kit to the client application.

  • SIWP is used to verify that the user controls and owns the private key of a Polkadot account.

  • We can apply policies to the NFT metadata based on the Open policy agent(OPA).

Claiming nft_token

In this scenario, the client application requests the raw NFT data, without mapping to standard OIDC claims, by specifying the custom nft_token claim or defining the nft_token scope in the authorization request.

nft_token Scope

By specifying the nft_token scope in the authorization request, the client application requests the validation of the user being a holder of an NFT in the required NFT collection and the user info to be included in the response. The IDP Kit will determine the NFT request, which is sent to the NFT wallet, by the following sources in this order:

  1. nft_token claim, specified by the client application as a custom claim object in the authorization request

nft_token Claim

The nft_token claim should be constructed as follows:

Authorization POST request:

When making the authorization post request, the client can specify a claim field in the body, with a value describing the NFT collection. The format will be as follows:

"claim": {
  "nft_token": {
    // blockain identifier
    "chain":"OPAL",
    // the smart contract representing the NFT collection
    "smartContractAddress":"5GTmz6Vc7tXsbiD6ujxyt8Yf17FnygJLcrBqvduU3c8NwmHP"
  }
}

Authorization GET request:

When making the authorization get request, the client can specify a claim field, as shown in the example above, in a JSON object. This object will then be sent URL encoded via the query parameters.

Standard OIDC scopes, claims and claim mapping

In this scenario, the client application simply makes a standard OIDC authorization request, like any other OIDC compliant identity provider would expect it. E.g. the application could request the profile scope, to receive name, given name, family name, gender, date of birth, etc. of the user from the IDP Kit.

The IDP Kit maps the required claims to suitable traits in the NFT metadata that contain the requested information, by getting access to the NFT through the shared address of the user. The gathering of the user address will be handled by a separate wallet connect page (web application), without the client taking any notice.

Once the IDP Kit has received the address of the user from the wallet connect page, got the information from the NFTs metadata and verified all of it. The IDP Kit translates the received data into the standard user info claims requested by the application and provides it on the standard user info endpoint.

To use this flow, the client application needs no additional knowledge about the underlying protocol. In most cases, a simple configuration change would suffice to make an application connect to the IDP Kit and accept NFT data for user authentication, given that OIDC is already used as an authentication layer.

Flow | Identity provision via NFTs

This section will explain the principles of how OIDC authentication requests are translated into NFT requests and the options available to craft such requests.

The IDP Kit transforms the ownership of NFT on Polkadot into an identity access management solution. The implementation is based on three main aspects: OIDC, SIWF, NFT, and their metadata.

Any client application can use the IDP Kit to grant access to a service via the ownership of an NFT on the Flow Blockchain. The IDK Kit extends the verification of the NFT ownership by applying policies to the NFT metadata via an open policy agent(OPA).

How it works

OIDC via NFTs

The whole verification process has seven main steps:

  1. The client application redirects the user to the IDP Kit. It is a verification request based on the OIDC standard.

  2. The IDP Kit processes the verification request. If it is an NFT Flow verification, the IDP Kit redirects the user to his user interface.

  3. Then, the user must connect to his wallet. He shares his address with the IDP Kit and signs a message based on the SIWF process.

  4. The SIWF process continues within the IDP Kit by verifying the user address and the message signature.

  5. After that, the IDP Kit will verify that the user has an NFT in a specified collection within the Flow Blockchain. The NFT collection information is defined in the IDP Kit configuration file.

  6. If the NFT metadata policy verification is activated, The IDP Kit will load the NFT metadata and run an OPA policy with the NFT metadata. The OPA policy is specified in the configuration file.

  7. In the last step, the IDP Kit redirects the user to the client application with a response of the whole verification with extra information like the account address. This is based on the OIDC standard.

The authorization flow visualized

  • OpenID Connect(OIDC) is used as the protocol between any client application and the IDP Kit. It is used by the client application to make an NFT ownership verification request. The IDP Kit will well interpret the request. It is also used within the verification response by the IDP Kit to the client application.

  • SIWF is used to verify that the user controls and owns the private key of a Flow account.

  • We can apply policies to the NFT metadata based on the Open policy agent(OPA).

Claiming nft_token

In this scenario, the client application requests the raw NFT data, without mapping to standard OIDC claims, by specifying the custom nft_token claim or defining the nft_token scope in the authorization request.

nft_token Scope

By specifying the nft_token scope in the authorization request, the client application requests the validation of the user being a holder of an NFT in the required NFT collection and the user info to be included in the response. The IDP Kit will determine the NFT request, which is sent to the NFT wallet, by the following sources in this order:

  1. nft_token claim, specified by the client application as a custom claim object in the authorization request

nft_token Claim

The nft_token claim should be constructed as follows:

Authorization POST request:

When making the authorization post request, the client can specify a claim field in the body, with a value describing the NFT collection. The format will be as follows:

"claim": {
  "nft_token": {
    // blockain identifier
    "chain":"TESTNET",
    // the smart contract representing the NFT collection
    "smartContractAddress": "0xa9ccb9756a0ee7eb",
    // the path where nft is stored
    "collectionPath": "/public/exampleNFTCollection"
  }
}

Authorization GET request:

When making the authorization get request, the client can specify a claim field, as shown in the example above, in a JSON object. This object will then be sent URL encoded via the query parameters.

Standard OIDC scopes, claims and claim mapping

In this scenario, the client application simply makes a standard OIDC authorization request, like any other OIDC compliant identity provider would expect it. E.g. the application could request the profile scope, to receive name, given name, family name, gender, date of birth, etc. of the user from the IDP Kit.

The IDP Kit maps the required claims to suitable traits in the NFT metadata that contain the requested information, by getting access to the NFT through the shared address of the user. The gathering of the user address will be handled by a separate wallet connect page (web application), without the client taking any notice.

Once the IDP Kit has received the address of the user from the wallet connect page, got the information from the NFTs metadata and verified all of it. The IDP Kit translates the received data into the standard user info claims requested by the application and provides it on the standard user info endpoint.

To use this flow, the client application needs no additional knowledge about the underlying protocol. In most cases, a simple configuration change would suffice to make an application connect to the IDP Kit and accept NFT data for user authentication, given that OIDC is already used as an authentication layer.

Open Source | Always Free

  • You can use, modify and distribute our products for free and without strings attached.

  • You can use our products to build pilots or even production systems.

  • You can deploy, run and manage our products on-premise or in your own cloud environments.

Enterprise

Run our products with the support of our experts.

  • You can use, modify and distribute our products for free and without strings attached.

  • You can use our products to build pilots or even production systems.

  • You can deploy, run and manage our products on-premise or in your own cloud environments.

To complement our free products, we offer services for clients who want to manage our products by themselves:

  • Consulting

  • Custom development and integration

  • Support / SLAs

Sign-in with Flow (SIWF)

Sign-In with Flow Blockchain describes how flow accounts authenticate with off-chain services by signing a message parameterized by scope, nonce, etc. It is an alternative to centralized identity providers. It is based on the self-custody of your identity. It leverages the on-chain authentication model to off-chain services.

The reason behind implementing the concept Sign-In with Flow is that it is a critical step in the Login with NFTs concept. Before granting access to some services based on the ownership of some NFTs, we need to check two main aspects:

  • You own an account via Sign with Flow.

  • Verify that the account has an NFT in a specified collection.

An account in Flow is linked to the ownership of a private key which is then mapped to his public key. The hash of the public key outputs an address.

The IDP Kit implements SIWF based on seven main steps:

  1. Nonce generation.

  2. Redirection to the IDK Kit wallet user interface.

  3. Connect to your flow wallet.

  4. A popup appears for signing the message. It is based on multiple factors like the nonce generated by the IDP Kit, account address, etc.

  5. Click the “Sign” button.

  6. Redirection to the IDK Kit verification service.

  7. The IDP Kit verifies the message signature based on the account address.

The message will be in the form of:

{domain} wants you to sign in with your Flow account: {address}. Public Key: {publicKey}.Date: {ISO8601formatedTimestamp}. {description} URI: {origin}. Version: {versionNumber}. Nonce: {nonce}

  • domain: is the RFC 3986 authority that is requesting the signing.

  • Permissions.address: account address.

  • Public Key : account public key.

  • Date: is the ISO 8601 datetime string of the current time.

  • Nonce: security parameter generated by the IDP Kit.

This documentation section will dive deep into implementing the Sign-in with Tezos(SIWT). For more details about the concept Sign in With X (SIWx), .

To understand how identity provision via NFTs can be leveraged in an OIDC authentication flow, you may first want to recap on the basic principles of .

Derived from nft_mappings defined in the IDP Kit , based on the scopes and claims requested in the authorization request

NFT token claim, configured in thedefault_nft_token_claim in the IDP Kit

This documentation section will dive deep into implementing the Sign-in with Algorand(SIWA). For more details about the concept Sign in With X (SIWx), .

To understand how identity provision via NFTs can be leveraged in an OIDC authentication flow, you may first want to recap on the basic principles of .

Derived from nft_mappings defined in the IDP Kit , based on the scopes and claims requested in the authorization request

NFT token claim, configured in thedefault_nft_token_claim in the IDP Kit

To understand how identity provision via NFTs can be leveraged in an OIDC authentication flow, you may first want to recap on the basic principles of .

Derived from nft_mappings defined in the IDP Kit , based on the scopes and claims requested in the authorization request

NFT token claim, configured in thedefault_nft_token_claim in the IDP Kit

All our products are open source under the permissive **** license. This means:

if you are using our products. We are curious to learn about your experience and happy to spread the word about your project via our newsletter or case studies.

All our products are open source under the permissive **** license. This means:

if you want to learn more.

This documentation section will dive deep into implementing the Sign-in with Flow(SIWF). For more details about the concept Sign in With X (SIWx), .

CAIP-122
OIDC authentication
claim configuration
claim configuration
CAIP-122
OIDC authentication
claim configuration
claim configuration
OIDC authentication
claim configuration
claim configuration
Apache 2
Get in touch
Apache 2
Get in touch
CAIP-122

IAM / KeyCloak integration

In this section I will demonstrate how to configure KeyCloak to use the IDP Kit as an external identity provider and thus enable authentication via SSI with just a few configuration changes.

Client registration

Next, we need to register the KeyCloak server with the IDP Kit as an OIDC client.

waltid-idpkit config --oidc clients register -r https://keycloak.walt-test.cloud/realms/master/broker/waltid-idpkit/endpoint

The command prints the client registration information, from which I need to copy the client_id and client_secret:

{
    [...]
    "redirect_uris":[
        "https:\/\/keycloak.walt-test.cloud\/realms\/master\/broker\/waltid-idpkit\/endpoint"
    ],
    "client_secret":"T38g9qLmw3PboO0zbesyDFNXATrC6R6u-cMQ62g-lWE",
    [...]
    "client_id":"4RxVuuOJOiunktpehKdrT28sA4vbLFQc40eY5DlC_SE"
}

Refer to the KeyCloak documentation, to find out the proper values for the redirection URIs in your setup.

KeyCloak configuration

Now we can configure KeyCloak to connect to the IDP Kit.

To do so, login to the KeyCloak administration console with your admin credentials and navigate to the realm, for which you want to apply the configuration.

External identity provider

  • Navigate to the Identity Providers section in the left menu bar, open the "Add provider..." drop-down menu and choose "OpenID Connect v1.0":

  • Fill in Alias and Display Name according to how you want the IDP Kit to be referred to in the Login UI:

  • Scroll down to Import External IDP Config and enter the URL of the well-known OIDC discovery document of the IDP Kit and click import. For our IDP Kit test deployment, the URL would be:

https://idp.walt-test.cloud/api/oidc/.well-known/openid-configuration

  • On import, the required endpoints are automatically filled in.

  • Next we need to provide the client authentication details.

    • Scroll to the Client Authentication input field and choose Client secret sent as basic auth.

  • In order to get properly mapped user data from the IDP Kit, we need to define the OIDC scopes to be used for the authorization request.

    • Choose: openid profile

  • Save the IDP configuration

  • Now continue with configuring your client application to connect to KeyCloak as authorization server, like usual.

Since the IDP Kit is compliant with the well adopted OpenID Connect standard for identity provision, it can be easily integrated, as a federated identity provider, with third party Identity and Access Management systems (IAM), such as .

For simplicity I assume that all basic configuration aspects regarding and and general have already been configured according to the requirements.

In this example I will use the command line interface to like so:

To register the client at runtime, you can also make use of the .

Then fill in Client ID and Client Secret with the values obtained from the .

KeyCloak
OIDC Manager
SIOP Manager
IDP Kit configuration
register a new client
dynamic client registration API
client registration
KeyCloak Identity Providers
KeyCloak IDP Name and Alias
KeyCloak IDP import
KeyCloak client authentication
KeyCloak client authentication
Identity providers section in Keycloak admin console
Code flow
Code flow
IDP Kit - Tezos
OIDC/SIOP code flow
Code flow with vp_token claim
Code flow with standard claim mapping
Sign-in with Near Protocol
Sign-in with Polkadot
IDP Kit - Near Protocol
SIgn-in with Tezos message
IDP Kit - Algorand
Sign-in with Algorand
IDP Kit - Polkadot
IDP Kit - Flow
Sign-in with Flow

NFT Manager configuration

To configure the NFT manager, a few things may need to be considered, and some configuration may be required, depending on your situation.

Ways to specify the NFT collection

"default_nft_token_claim": {
    "chain": "POLYGON",
    "factorySmartContractAddress": "",
    "smartContractAddress": "0x21dd9b1913d84ab295fdf19834b0b6824a5912ca",
    "collectionPath": ""
}

Possible values for the chain key in both configurations: ETHEREUM, POLYGON, TEZOS, GOERLI, MUMBAI, GHOSTNET.

Activate and specify the OPA policy verification

To activate the OPA policy verification, you may provide some configuration.

"default_nft_policy":{
    "withPolicyVerification": true,
    "policy": "idpkit/opa/nft_tezos.rego",
    "query": "data.app.nft.allow",
    "inputs": {
        "Backgrounds": "Green",
        "symbol": "RMB",
        "reference": "RCS1"
    }
}

Configuration of the wallet connect page

If you don't want to use the default built-in wallet connect page, you can create a nft-config.json file and provide a custom connect page.

{
  "nftWallet": {
    "id": "idpkit-connect-wallet",
    "url": "/connect-wallet",
    "presentPath": "",
    "receivePath" : "",
    "description": "IDP Kit connect wallet"
  }
}

Cloud Platform

We offer our products as a managed cloud service for clients who do not want to deploy, manage and run our products by themselves.

The Cloud Platform includes:

  • All products

  • Enterprise use cases

  • Fully managed cluster

  • Cloud SLA / support

The default configuration, which will be used if no claim value is present in the authorization request. It can be set in config/idp-config.json. A more detailed overview of all possible claim configurations, can be found in the section.

if you want to learn more.

claim configuration
Get in touch