Set up an OpenID Provider


VII Extensions including the OIDC Bridge allow customers to augment their existing identity management infrastructure. Using the OIDC Bridge, an OIDC Credential Issuer can be configured to leverage an existing OIDC Provider in order to authenticate users and provide the information needed to generate verifiable credentials and make them available to an end-user's digital wallet. If you are unfamiliar with OpenID Connect (OIDC), there are many excellent guides available online.

In order to issue your first custom Verifiable Credential, you will first need to configure a standard OpenID Provider (OP) that will become a federated provider for the OIDC Bridge.

OpenID Providers

You are free to use any OpenID Provider as long is it supports the following capabilities specified by OpenID Connect Core and OpenID Connect Discovery:

  • Must publish the OpenID Provider configuration at /.well-known/openid-configuration

  • Must support Authorization Code flow

  • Must support the state parameter

These are required to allow the OIDC Bridge to federate out to your OP and accept an ID Token containing the end-users claims.

This guide will step you through:

Using an existing OpenID Provider

Follow a few steps to make sure your OpenID Provider is setup:

  1. Make sure your OpenID configuration is discoverable. Browse to https://<your-host-domain>/.well-known/openid-configuration and check the following values exist (other options may validly sit alongside):

Copy to clipboard.
1"authorization_endpoint": "https://your-auth-endpoint/auth",
3"token_endpoint": "https://your-token-endpoint/token",
5"jwks_uri": "https://your-jwks-endpoint/jwks",
7"response_types_supported": ["code"],
9"grant_types_supported": ["authorization_code"],

This is an example OpenID configuration from Google.

2. Setup a client on your OP. At this stage you have to use an example callback URL (also known as the redirect_uri) e.g. also make note of client_id and client_secret.

The callback URL will need to be updated once the OIDC Bridge Issuer has been configured.

3. If you intend to use any additional scopes, make note which scopes are required to invoke Claims you want to retrieve from your user profile system. Common ones include openid, profile and email.

4. Try it out by running a manual test against your OP and inspecting the resulting ID token.


Set up a new OpenID Provider

For the purpose of this tutorial, we will utilize a cloud-based identity management solution, Auth0.

We'll cover the basics of OpenID Provider configuration, show how Auth0 expose the underlying user profile store, and demonstrate how data can be added to their ID token.


First sign up with Auth0 or login if you are already have an account.

Configure Auth0

For this exercise, skip the Auth0 onboarding tutorials and go straight to your dashboard.

Create a new application

1. Name it something meaningful

We will be connecting to a 'regular web application'.

2. Skip the 'Quick Start' and navigate to the 'Settings' tab.

Make note of the:

- Domain

- Client ID

- Client Secret

Edit these fields:

  • Add a simple description

  • In the 'Allowed Callback URLs' section add in This will be used later during the manual testing.

The callback URL will need to be updated once the OIDC Bridge Issuer has been configured.

All other fields can be left at their default values.

3. Make sure your OpenID Configuration is discoverable by browsing to https://<your-auth0-domain> and checking that the following values exist (other options may sit alongside):

Copy to clipboard.
1"authorization_endpoint": "https://your-auth-endpoint/authorize",
2"token_endpoint": "https://your-token-endpoint/token",
3"jwks_uri": "https://your-jwks-endpoint/jwks.json",
4"response_types_supported": ["code"],
5"grant_types_supported": ["authorization_code"],

Set up a connection and add users

This is where Auth0 is used to store and hold user information, including PII. Before you add details about users, make sure you understand Auth0's policies around storing this information.

In 'Connections'

  • Leave Database and Username-Password-Authentication Enabled

  • Disable the Social login

In 'Users & Roles'

Create user:

  • Provide an email address that is different to the Admin account used to sign up with Auth0

  • Add a password

  • Leave Connection as 'Username-Password-Authentication'

  • Optional: you may want to update the default `Name` field from just being the email address to something more meaningful.

In details for the new user:

This is where we can add in additional information about a user to appear in the ID token that will ultimately will appear in the issued Verifiable Credential.

  • Scroll down to user_metadata

  • Add claims about the user that you want to see represented in the ID token.

For example:

Copy to clipboard.
2    "educationalCredentialAwarded": "Certificate Name"

In 'Rules'

Create a new rule:

  • Start with an empty rule

  • Give it a meaningful name

  • For each attribute in the user_metadata add a mapping to an ID token claim

N.B. Auth0 enforces a namespace for custom claims. Use the full domain of your MATTR tenant.

Example code:

Copy to clipboard.
1function (user, context, callback) {
2  const namespace = '';
3  context.idToken[namespace + 'educationalCredentialAwarded'] = user.user_metadata.educationalCredentialAwarded;
4  callback(null, user, context);

Try it out

Before we connect to the OIDC Bridge, let's test the OpenID Provider configuration.

In a new browser window, navigate to the /authorize endpoint for your OpenID Provider instance with the standard OIDC query parameters:

  • Use the URL of the authorization endpoint defined in the /.well-known/openid-configuration

  • The client_id which will relate to the client application setup on your OP (you will need the client_secret later)

  • Use the value you added in the allowed callback URLs and the redirect_uri

  • The values in scope, response_type, state, nonce, prompt are all required and can be used as per the example

Copy to clipboard.

Authenticate with the OP using a user that you have set up.

Example Auth0 login page

The redirect will terminate, however you can still retrieve the code from the query parameter:

Copy to clipboard.

Token request

Construct a request to the /token endpoint of your Auth0 tenant:

  • Use your client_id and client_secret from the Auth0 account to create an authorization header encoded with Base64

  • grant_type is authorization_code

  • Use the code value captured from the above redirect -- this is time sensitive, you have about 5 mins!

  • Use the same redirect_url as used in the request

Copy to clipboard.
1curl --request POST \
2  --url \
3  --header 'Content-Type: application/json' \
4  --header 'Authorization: Basic dkowU0NLY2hyNFhqQzB4SE5FOERrSDZQbWxnMmxrQ046UU53ZmE0WWk0SW05enkxdV8xNW43U3pXS3QtOUc1Y2RIMHIxYk9OUnBVUGZOLVVJUmFhWHZfOTB6OFY2LU9qSA==' \
5  --data-raw '{
6    "grant_type": "authorization_code",
7    "code": "oLxCRk2oPgfR8QU3",
8    "redirect_url" : ""


The response from /token includes the id_token.

Copy to clipboard.
1 {
2    "access_token": "-vtm3ahlh9k_V2uDjnZ5r2MPbKRaHpA1",
3    "id_token":  "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlJUVXdOVEpCTXpJNFJUTTNNVGt4TURnNU5EVTJRamRETlRVNVJrWTNNamMyTTBWRU1FVkJPUSJ9.eyJodHRwczovL215dGVuYW50Lm1hdHRyLmdsb2JhbC90cmFpbmluZ0NlcnQiOiJQYXNzZWQgQSsiLCJuaWNrbmFtZSI6Im1lIiwibmFtZSI6Im1lQGVtYWlsLmNvbSIsInBpY3R1cmUiOiJodHRwczovL3MuZ3JhdmF0YXIuY29tL2F2YXRhci84ZjlkYzA0ZTZhYmRjYzlmZWE1M2U4MTk0NWM3Mjk0Yj9zPTQ4MCZyPXBnJmQ9aHR0cHMlM0ElMkYlMkZjZG4uYXV0aDAuY29tJTJGYXZhdGFycyUyRm1lLnBuZyIsInVwZGF0ZWRfYXQiOiIyMDIwLTA0LTMwVDA3OjUxOjA4Ljk0MloiLCJpc3MiOiJodHRwczovL2Rldi1yb2w0d29hby5hdS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NWU2NmVjZjZlNWNjZjUwY2QwMDNmZjIwIiwiYXVkIjoidkowU0NLY2hyNFhqQzB4SE5FOERrSDZQbWxnMmxrQ04iLCJpYXQiOjE1ODgyMzQwNzEsImV4cCI6MTU4ODI3MDA3MX0.KLrMUoqz5mrvNQQ3K09eFijVg3qkmT17R_zOUvVhtfC8LvUWaBYpszQ7j3x3zCZ1TsS4ATS68kcxLfSbq7A71atYVzwjKvGwGce9IjH7cRKyIO8Z1RAcSCw7ncXBOzT_O20sH3BV_ZgPHEJA2PreKQERKjcKSCHJeRaPyqVbh2v2lSHYCm6e8HdB8v_Zq0looLvxS5afQ8PMn3k36COo13F4zvLuUn9is--B-SRUqUjSX6-KOvULa1HXbQVnO6RUNiijQSbN-ZLA_6TRQC8BKoT3-8v1cLSb49sZOXGSBHkkNHGBhMXeJuw4iD8IjYQWpcXlVRQHuCQwFgSHxdez9w",
4    "scope": "openid profile",
5    "expires_in": 86400,
6    "token_type": "Bearer"

Copy the id_token value and paste it into a tool like to inspect the payload of the ID token.

You should see;

  • Any default claims associated with the scopes provided and any fully name-spaced claims -- these will be important when setting up your claim mappings

  • The sub value is also an important field that will be used in credential issuance

  • The nonce value provided in the original request

Copy to clipboard.
2    "": "Certificate Name",
3    "nickname": "me",
4    "name": "My Full Name",
5    "updated_at": "2020-04-30T07:51:08.942Z",
6    "iss": "",
7    "sub": "auth0|5e66ecf6e5ccf50cd003ff20",
8    "aud": "vJ0SCKchr4XjC0xHNE8DkH6Pmlg2lkCN",
9    "iat": 1588234071,
10    "exp": 1588270071,
11    "auth_time": 1606723358,
12    "nonce": "kjfhuo34hPxksklj"