Skip to main content

Issue a credential using OIDC Bridge

Introduction

This guide will step through how to issue a credential to the Sovrin Wallet once the Sovrin tenant has been configured for Verifiable Credential issuance using an OpenID Connect Provider.

Prerequisites

You need the following in order to proceed with this tutorial:

  • Access to Sovrin APIs. If you’re experiencing difficulty, contact us.

  • The DID (Decentralized ID) to use for issuing credentials. Take a look at Tenant Setup for more information.

  • A correctly-configured OpenID Provider (OP). Have the client_id and client_secret close at hand.

  • Set up an OIDC Credential Issuer and have the id.

  • Download the Sovrin Wallet and have it set up with a PIN.

If you’re experiencing any difficulties please contact us.

Configure Auth0 OIDC Provider

Open your Auth0 application and navigate to the ‘Settings’ tab.

Update the ‘Allowed Callback URLs’ to include the callbackUrl from the OIDC Credential Issuer you have created.

https://api.sovrin.one/ext/oidc/v1/issuers/983c0a86-204f-4431-9371-f5a22e506599/federated/callback

Embed in a QR Code

A common way to allow a mobile wallet user to reference the issuer is to encode the openid:// URL within a QR code.

openid://discovery?issuer=https://api.sovrin.one/ext/oidc/v1/issuers/983c0a86-204f-4431-9371-f5a22e506599&request_parameters={UrlEncoded({"login_hint": "xxx"})}
tip

Remember the issuer is long-lived and can be referenced by many clients. You could even print out the QR code.

tip

Sovrin is not affiliated with any of these service providers and cannot vouch for their offerings.

Make sure to make the QR a decent size to be resolvable by a phone camera, 200px square is a fine.

Let’s use an API service to generate the QR code:

https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=openid://discovery?issuer=https://tenant.vii.sovrin.one/ext/oidc/v1/issuers/983c0a86-204f-4431-9371-f5a22e506599&request_parameters={UrlEncoded({"login_hint": "xxx"})}

Alternatively, you can open the OIDC Credential Provider link directly from a mobile device by creating a Deep Link to the OpenID endpoint for the Sovrin Wallet. This can be achieved using the Sovrin Wallet bundle ID, along with the accept path and Base64Url encoding of the string.

global.mattr.wallet://accept/{base64Url(openid://...)}

Foe example:

global.mattr.wallet://accept/b3BlbmlkOi8vZGlzY292ZXJ5P2lzc3Vlcj1odHRwczovL1lPVVJfVEVOQU5UX1NVQkRPTUFJTi52aWkubWF0dHIuZ2xvYmFsL2V4dC9vaWRjL3YxL2lzc3VlcnMvOTgzYzBhODYtMjA0Zi00NDMxLTkzNzEtZjVhMjJlNTA2NTk5

Send as a notification

Encrypt the message

To send the offer URI you must first encrypt it by making the following request:

Request

POST https://api.sovrin.one/v1/messaging/encrypt
{
"senderDidUrl": "did:web:organization.com#CU6dJt9p8t",
"recipientDidUrls": [
"did:key:z6MkgmEkNM32vyFeMXcQA7AfQDznu47qHCZpy2AYH2Dtdu1d"
],
"payload": {
"id": "731961f2-bdc3-4f1e-8d59-cc308fd60ec8",
"type": "https://sovrin.one/schemas/verifiable-credential/offer/OidcCredentialProvider",
"from": "did:web:organization.com",
"created_time": 1616466734,
"body": {
"uri": "openid://discovery?issuer=https://tenant.vii.sovrin.one/ext/oidc/v1/issuers/0dceeddd-f717-4bf2-b520-b3ddcd104a60"
}
}
}
  • senderDidUrl: The sender's DID URL, obtained from the id field of the first keyAgreement entry of the DID document. Refer to our DID tutorial for more information.

  • recipientDidUrls: The recipient's DID URL. In production environments, you must have a secure way to obtain the DID that is associated with the intended recipient's digital wallet:

    • Use DID Auth for a new interaction.

    • Ask the user to manually obtain their public DID by opening their Sovrin Showcase wallet and navigating to Settings > Advanced > Public DID.

    • Request an existing credential as part of a verification workflow, and extract the recipient's digital wallet DID from that interaction.

  • payload:

    • id: Credential offer id.

    • type: Type of credential offer.

    • from: Credential issuer.

    • created_time: Time of creation (Unix time in milliseconds).

  • body:

    • uri: The credential offer URI.

Response

{
"jwe": {
"protected": "eyJhbGciOiJYQzIwUCJ9",
"recipients": [
{
"header": {
"alg": "ECDH-1PU+A256KW",
"kid": "did:key:z6MkgmEkNM32vyFeMXcQA7AfQDznu47qHCZpy2AYH2Dtdu1d#z6LSsvqSJkBvVEsDC8cxMHuQ3sKoLRMXB1MdtoLrMUq6A8Rg",
"epk": {
"kty": "OKP",
"crv": "X25519",
"x": "JOLnYaD7L-Rszz7fczPhn6MkNre25PUsztzB1RHoz14"
},
"skid": "did:key:z6MkreuqFq6WrwozTeGKuUDz8bniTFRNAg8f3ZB862YdLp7v#z6LScyz3YLToyoKwZE6Tfq65hgZUkZdHrC4ZqohcUH9X6Twx"
},
"encryption_key": "ag5iKzjJOth9Wa68dCVKJW_vnO_Ga0zSJgQp5rIUg69HCzIjuNYhDg"
}
],
"ciphertext": "xpW-D6sDPpWc_jk87nEyxPX7JQV8_OZpaQft7ySQ5XmNhoj-lQyDkXDncOCyhB7yMSdZrRBNQjKxlEbpY_WLk1hBoWfsTeszVSAuFbX_VKUSJ7GR6rcnWGVNgDfKS8GsyC_owtswXatkF_65_mzFOygctkUmd2eI5bcpQpWjhw2vqnvnWkb7l2J27aWFF_c9cu52dB559j8lwLYyYC9oSMgV5piB6ppfrWBGo_DigjxvJcAYcjFYqFcT6A1nphPhwVTQ2HNfJodbQoseHub8UQdG4qAOcggq5DI84tbqor1SU9rdPH03jPkLgoO_aeXyJg5meITXoFSiu_tRfvf8QQ6vKq6pkTTXs8zKXcBCGhGIyKBNBG4R4RIY1UffTMnJQQQGBble3P06pGOnsnSop0BtygelB9M0ZEwnAUSAQqN1RR4AQwWcn9nH6hHEu1pMhSvhCuFNAPWS-hg24JGGw8Xe3EEZlLH0PM8qpUAfksPq",
"iv": "FJq5zKvuPiUQIdRcMtiChHCJByuY8XK9",
"tag": "u8kT0VAAtTswjGXxNpuX0g=="
}
}

The result is a message payload constructed using the JWM format.

Send the message

Make the following request to send the offer as an encrypted jwe object to the user's digital wallet:

Request

POST https://api.sovrin.one/v1/messaging/send
{
"to": "{SUBJECT_DID}",
"message": {
"to": "did:key:z6MkgmEkNM32vyFeMXcQA7AfQDznu47qHCZpy2AYH2Dtdu1d",
"message": {
"protected": "eyJhbGciOiJYQzIwUCJ9",
"recipients": [
{
"header": {
"alg": "ECDH-1PU+A256KW",
"kid": "did:key:z6MkgmEkNM32vyFeMXcQA7AfQDznu47qHCZpy2AYH2Dtdu1d#z6LSsvqSJkBvVEsDC8cxMHuQ3sKoLRMXB1MdtoLrMUq6A8Rg",
"epk": {
"kty": "OKP",
"crv": "X25519",
"x": "JOLnYaD7L-Rszz7fczPhn6MkNre25PUsztzB1RHoz14"
},
"skid": "did:key:z6MkreuqFq6WrwozTeGKuUDz8bniTFRNAg8f3ZB862YdLp7v#z6LScyz3YLToyoKwZE6Tfq65hgZUkZdHrC4ZqohcUH9X6Twx"
},
"encryption_key": "ag5iKzjJOth9Wa68dCVKJW_vnO_Ga0zSJgQp5rIUg69HCzIjuNYhDg"
}
],
"ciphertext": "xpW-D6sDPpWc_jk87nEyxPX7JQV8_OZpaQft7ySQ5XmNhoj-lQyDkXDncOCyhB7yMSdZrRBNQjKxlEbpY_WLk1hBoWfsTeszVSAuFbX_VKUSJ7GR6rcnWGVNgDfKS8GsyC_owtswXatkF_65_mzFOygctkUmd2eI5bcpQpWjhw2vqnvnWkb7l2J27aWFF_c9cu52dB559j8lwLYyYC9oSMgV5piB6ppfrWBGo_DigjxvJcAYcjFYqFcT6A1nphPhwVTQ2HNfJodbQoseHub8UQdG4qAOcggq5DI84tbqor1SU9rdPH03jPkLgoO_aeXyJg5meITXoFSiu_tRfvf8QQ6vKq6pkTTXs8zKXcBCGhGIyKBNBG4R4RIY1UffTMnJQQQGBble3P06pGOnsnSop0BtygelB9M0ZEwnAUSAQqN1RR4AQwWcn9nH6hHEu1pMhSvhCuFNAPWS-hg24JGGw8Xe3EEZlLH0PM8qpUAfksPq",
"iv": "FJq5zKvuPiUQIdRcMtiChHCJByuY8XK9",
"tag": "u8kT0VAAtTswjGXxNpuX0g=="
}
}
}
  • to: Use your recipient's wallet public DID. This can be obtained from previous interactions, via DID authentication or directly from the user's wallet.

  • message: Use the jwe object obtained in the previous step.

Response

A 200 response indicates that the message payload was sent to the service endpoint of the dereferenced DID Document (or the default Sovrin service endpoint).

Accepting the offer

At this stage, you should be able to open the Sovrin Wallet, either tap ‘Scan’, and point the camera at the QR code, or tap the deep link or notifcation.

You will now see the Credential Offer on screen.

  • You should see that the offer has been sent from a verified domain (your Sovrin tenant).

  • Tap ‘View’ to see the particulars of the offer.

  • Tap ‘Proceed’ to move to the next step.

End-user authentication

Upon end-user acceptance of the offer:

  • The Sovrin Wallet retrieves the /.well-known/openid-configuration metadata values from the OIDC Issuer you configured.

  • The Sovrin Wallet creates a unique DID to be used for this interaction.

  • The Sovrin Wallet opens a WebView and navigate to the /authorize endpoint for the OIDC Issuer (the unique DID is included in this request).

  • The OIDC Issuer redirects the end user to the configured federated provider within the WebView.

  • The Federated Provider presents a login screen.

tip

Having login_hint as request_parameters pre-populates the username in your Federated Provider's login screen. Any other request parameters are not supported by Sovrin Wallet and SDK at the moment.

Credential issuance

Following successful end-user authentication via the federated provider:

  • The ID Token from the federated provider is passed to the OIDC Issuer.

  • The claims provided within the ID Token are used to create the credential (including the unique subject DID created above).

  • Finally, the credential is passed to the Sovrin Wallet wherein you can tap ‘View’ to inspect its contents.

This subject-bound Verifiable Credential is now saved in the Sovrin Wallet and able to be presented to any requesting party. Such a presentation will usually also evidence ownership of the DID named as subject.

tip

The issued credential will support revocation. For more information please see the credential revocation overview.

tip

The metadata for the issued credential is held in a registry and can be retrieved via the list credentials endpoint. The tag in the credential metadata will be set to the sub value of the ID token of the federated provider.

For more information on holding the credential in a registry, please see Hold a Credential in a Registry.

Troubleshooting

echnical difficulties while running this tutorial. Below are a few common problems and their solutions.

The app opens but refuses to show the credential being offered

  • Check that you have encoded the Issuer Id correctly in the QR code

  • Your phone will need public internet access. Check it can access common websites.

  • Check that you can open the exact URL embedded in the code

Scanning the QR code using the phone’s camera doesn’t open the app (opens Google search or tries to load in the browser and fails)

  • Make sure you have the Sovrin Wallet set up with a PIN

  • Make sure the QR is large enough to be read by your phone; try creating a larger QR Code (say 300 x 300 px)