Set up an OpenID Provider
Introduction
The OpenID Credential Provisioning capabilities allow customers to augment their existing identity management infrastructure. Using OpenID, we can leverage an existing authentication provider 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, the identity protocol underpinning the OpenID provisioning capability, there are many excellent guides available online such as this guide from Google, or this guide from Mozilla.
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 OpenID Credential Provisioning flow.
OpenID Providers
You are free to use any OpenID Provider as long as 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 OpenID Credential Provisioning capability 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:
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):
1
2{
3 "authorization_endpoint": "https://your-auth-endpoint/auth",
4 "token_endpoint": "https://your-token-endpoint/token",
5 "jwks_uri": "https://your-jwks-endpoint/jwks",
6 "response_types_supported": ["code"],
7 "grant_types_supported": ["authorization_code"],
8 "token_endpoint_auth_methods_supported":["client_secret_basic"],
9}
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. https://example.com/callback
also make note of client_id
and client_secret
.
3. 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. You can also find the guidelines for setting up:
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.
Prerequisites
First sign up with Auth0 or login if you 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
https://example.com/callback
. This will be used later during the manual testing.
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>.auth0.com/.well-known/openid-configuration
and checking that the following values exist (other options may sit alongside):
1{
2 "authorization_endpoint": "https://your-auth-endpoint/authorize",
3 "token_endpoint": "https://your-token-endpoint/token",
4 "jwks_uri": "https://your-jwks-endpoint/jwks.json",
5 "response_types_supported": ["code"],
6 "grant_types_supported": ["authorization_code"],
7}
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.
⚠️ Warning
Auth0 restricts the size of the ID Token to 100Kb. Ensure that the data you inject into your token is below this limit or credential issuance will fail. Also, it is NOT recommended to use authentication provider as a source of claims for the issuance of credentials.
Try it out
Before we connect to the OpenID Credential Provisioning capability, 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 theclient_secret
later)Use the value you added in the allowed callback URLs
https://example.com/callback
and theredirect_uri
The values in
scope
,response_type
,state
,nonce
,prompt
are all required and can be used as per the example
1https://auth0-tenant.au.auth0.com/authorize
2?scope=openid%20profile
3&response_type=code
4&client_id=<your_client_id>
5&state=xqw2Lcafhx0NIoX0
6&nonce=kjfhuo34hPxksklj
7&prompt=login
8&redirect_uri=https://example.com/callback
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:
1https://example.com/callback?code=oLxCRk2oPgfR8QU3&state=xqw2Lcafhx0NIoX0https://example.com/callback?code=oLxCRk2oPgfR8QU3&state=xqw2Lcafhx0NIoX0
Token request
Construct a request to the /token
endpoint of your Auth0 tenant:
Use your
client_id
andclient_secret
from the Auth0 account to create anauthorization
header encoded with Base64 -- the string should be formatted asclient_id
:client_secret
prior to being encoded.grant_type
isauthorization_code
Use the
code
value captured from the above redirect -- this is time sensitive, you have about 5 mins!Use the same
redirect_uri
as used in the request
1curl --request POST \
2 --url https://auth0-tenant.au.auth0.com/oauth/token \
3 --header 'Content-Type: application/json' \
4 --header 'Authorization: Basic dkowU0NLY2hyNFhqQzB4SE5FOERrSDZQbWxnMmxrQ046UU53ZmE0WWk0SW05enkxdV8xNW43U3pXS3QtOUc1Y2RIMHIxYk9OUnBVUGZOLVVJUmFhWHZfOTB6OFY2LU9qSA==' \
5 --data-raw '{
6 "grant_type": "authorization_code",
7 "code": "oLxCRk2oPgfR8QU3",
8 "redirect_uri" : "https://example.com/callback"
9}'
Response
The response from /token
includes the id_token
.
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"
7}
Copy the id_token
value and paste it into a tool like jwt.io to inspect the payload of the ID token.
You should see;
The
sub
value is also an important field that will be used in credential issuanceThe
nonce
value provided in the original request
1{
2 "https://YOUR_TENANT_SUBDOMAIN.vii.mattr.global/educationalCredentialAwarded": "Certificate Name",
3 "updated_at": "2020-04-30T07:51:08.942Z",
4 "iss": "https://dev-rol4woao.au.auth0.com/",
5 "sub": "auth0|5e66ecf6e5ccf50cd003ff20",
6 "aud": "vJ0SCKchr4XjC0xHNE8DkH6Pmlg2lkCN",
7 "iat": 1588234071,
8 "exp": 1588270071,
9 "auth_time": 1606723358,
10 "nonce": "kjfhuo34hPxksklj"
11}