Part 4 in the series
In my first blog in the series, I introduced you to Verifiable Credentials (VCs) and Decentralized Identifiers (DIDs). In the second blog, I took a look under the hood and showed you how VCs were issued and verified. In the third blog, you learned how to set up and run the Microsoft Sample App. In this blog, I will describe the format of the rule and display files that are used to create the VC and then show you how to issue and verify different types of VCs.
In the previous blog I explained there are various methods for specifying claim values. These include values that are:
Asserted by the issuer App
The user is asked to enter a PIN to obtain the VC
Asserted by an Idp via an OpenID Connect id_token
Requires the user to sign in to the Idp
Statically defined in the VC manifest
Asserted by the user filling in values in the Authenticator
Asserted by one or more existing VCs in the holder's possession
Stay tuned because in this blog I will show you how to issue all the different types of VCs. I'll also show you how the verifier app can request the presentation of multiple claims.
Issuing a VC with claims asserted by the issuing app
Let's start by looking at the display and rule files used with the Microsoft sample app. For convenience, I have uploaded all of the files mentioned in this blog to https://github.com/xtseminars/Verifiable-Credential-Blog-files, and you can download them. Don't use my logo file as it has already been changed.
The display file controls how the Authenticator displays the card and other data associated with the VC.
In the diagram above, most of the settings are self-explanatory. However, the claims section needs some explanation. Entries under the claims section display the claim values in the Authenticator. The label is used as the name of the claim and the value taken from the VC vc.credentialsubject.firstname.
Look at the Rules file, and you will see that the source for the claims is a self-issued ID Token, and the mapping section shows how the claims in the ID Token map to the VC claims. For instance, the given_name in the ID Token maps to "vc.credentialsubject.firstname"
The ID token is constructed by the Request Service REST API. When the app calls the API, it provides the claim values to add to the self-issued ID_token. In the last blog, I mentioned that the request API body was constructed from values in the issuance_request_config.json file. This file is shown below:
The api-key is used to authenticate against your callback. It states that it is optional but recently changed to a mandatory requirement. The pin value shown as 123456 is set at runtime to a randomly generated value. In the last blog, we set the claim values at runtime. You could add more claims if you want to, but you will also need to update the display and rules files. In this example, the claims are statically defined in the code. However, the claims could be taken from anywhere. For example, the app could be written to take the values from:
An id_token that is used to authenticate to the app
Data entered by a user
Queries to other data services
You can read the spec for the API here: https://docs.microsoft.com/en-gb/azure/active-directory/verifiable-credentials/issuance-request-api
When the Authenticator picks up the issuance request. The request will contain the self-issued ID_token. The token holds the appropriate claims. If you want to examine the details, you can do so with Fiddler.
Issuing a VC with claims asserted by an IdP
I showed you the flow in my second blog when an Alumni card was issued. The Alumni VC requires the claims to be taken from an ID_token issued by an IdP.
You will see that the display file is the same as before except for the text, logo, and colours.
Look at the Rules file, and you will see that the source for the claims is again an ID Token, but this time it is not self-issued. The token is issued when the user signs into an IdP. The source of the ID Token is defined using the well-know OpenID Connect metadata URL. Via the URL, all of the required endpoints can be discovered. This includes the endpoint that allows access to the public key needed to verify the signature on the ID Token.
The Authenticator app will send a request to the IdP to issue an OpenID Connect id_token for the application identified by the client_id. This is returned to vcclient://openid (the Authenticator)
You can use any IdP that supports OpenID Connect. In my example, I am going to use an Azure AD tenant. To get an Id_token for the Authenticator, you will need to register an application in the tenant you are using for authentication. This can be but doesn't have to be the tenant where the Verifiable Claims service is running.
Registering the Authenticator in Azure AD
Registering the Authenticator is done via App registrations.
You will need to choose a name, set the app type to Public client/native… and redirect URI to vcclient://openid/. After registering the app, update the rules file with the client ID and metadata endpoint.
The last step is to add the additional claims to the ID token and add the profile permission.
For your VC card logo, you could use the Microsoft image. Alternatively, upload an image to the Azure AD public container created in the last blog. For my logo, I used a 200 x 50 pixel image.
Copy the URL to the file and update the display file.
Create a new credential
As shown in my last blog, create a new credential in the Azure VC service. Name the credential Alumni and upload your display and rules files. After the credential is created, copy the Issue Credential URL.
Creating a new app
Rather than modifying the version1 app, create a version2 folder and follow the steps shown in my last blog to copy the files from version0 and get the website running to the point where you can display the home page.
Copy C:\VC-APIs\version1\active-directory-verifiable-credentials-node\1-node-api-idtokenhint\config.json file to the new project and overwrite the existing file.
Open the config.json file and update CredentialManifest URL with your new credential.
Open issuer.js and locate the following two lines and remove them:
issuanceConfig.issuance.claims.given_name = "James";
issuanceConfig.issuance.claims.family_name = "Bond";
Open the issuance_request_config.json and remove the pin and claims sections. Update the VC type to Alumni. From the end of the line that declares the manifest, remove the comma. It should now look like this:
Open the presentation_request_config.json and update the VC type to Alumni.
If necessary stop and restart the app. As I showed you in the second blog, you can now successfully issue and verify claims with an IdP logon.
Issuing a VC with claims asserted by the user and static claims
This section will explain how you can issue a VC where the claims are asserted by the user filling in values in the Authenticator. You will also see how you can statically define values in the rules file. I have used this type of VC for a conference where codes were given out during sessions. The user could then create a VC for the attended session by entering the code. At the end of the conference, the user went to the conference website, and a presentation request was generated requesting multiple VCs. If the user had the VCs and the correct codes, they were automatically entered for the competition.
Before we look at the files, let's look at the Authenticator flow:
Step 1 is after the QR Code has been scanned. You will see that the user is asked to add an email and a session draw code. After adding the values, the user is prompted, in step 2, to add the credential. The card is then added to the wallet, and if you examine the VC (step 3), you will see the two values the user asserted and the session claim, which was statically defined in the rules file.
Once again, the display file is very similar to the previous display files. The claims section has been updated to reflect the new names, and an extra claim has been added.
You will see the three displayed claims that are mapped from the VC. Take a look at the Rules files, and you will see that the session claim is statically defined. The email and code require user input (selfIssued). At the moment, it only supports string values for the user-defined claims.
Create a new credential
In the Azure portal, create a new credential. Name the credential ConferenceSession and upload your display and rules files. After the credential is created, copy the Issue Credential URL.
Creating a new app
As before, create a new app directory called version3. This time simply copy the entire contents of the version2 folder into version3. Start VS Code and open the version3 folder containing the code. You can run the app from the terminal. You do not need to install it this time as you have copied all the modules.
Update the following:
Config.json with the new manifest URL
issuance_request_config with the new VC type "ConferenceSession"
presentation_request_config with the new VC type " ConferenceSession"
Run the app, and you can issue and verify your new VC.
Issuing a VC with claims asserted by other VCs
This section will show you how to create a new VC from claims held in two existing VCs. I will show you how to create a VC based on the firstname and lastname claims from the Alumni VC and the email claim from the ConferenceCard VC.
The display file is similar to the others:
The required VCs are defined in the rules file. In the presentations section, you can see both VCs declared together with the claims required from each VC.
You will need to update the file with your Issuer DID (two instances) and the Issue Credential URLs for the Alumni and ConferenceSession VCs.
After scanning the QR code, you are asked to add a credential based on the conference and alumni credential. After the CompoundCard credential is created, you can see the email from the ConferenceSession VC and the user's name from the Alumni VC.
Create a new credential
In the Azure portal, create a new credential. Name the credential CompoundCard and upload your display and rules files. After the credential is created, copy the Issue Credential URL.
Creating a new app
As before, create a new app directory called version4. This time simply copy the entire contents of the version2 folder into version4. Start VS Code and open the version4 folder containing the code. You can run the app from the terminal. You do not need to install it this time as you have copied all the modules.
Update the following:
Config.json with the new CompoundCard manifest URL
issuance_request_config with the new VC type " CompoundCard"
presentation_request_config with the new VC type " CompoundCard "
Run the app, and you can issue and verify your new VC.
Requesting the presentation of multiple VCs
A verifier can request that one or more VCs are presented. Currently, when you select verify credential, the app requests the presentation of a single VC. The next job is to update the app to request two VCs. You could extend this to ask for more VCs if you wanted to.
We'll start by creating a new app rather than modifying anything that is already working.
As before, create a new app directory called version5. Copy the entire contents of the version2 folder into version5. Start VS Code and open the version5 folder containing the code. You can run the app from the terminal.
The presentation request is build using the Request Service REST API. You can find the details of the API here: https://docs.microsoft.com/en-gb/azure/active-directory/verifiable-credentials/presentation-request-api
The app builds the request for the API in presentation_request_config.json. We need to update the file to ask for two VCs. In this example, we will ask for an Alumni VC and a ConferenceSession VC to be presented. The current presentation_request_config.json for Version2(Alumni) is as below:
The "requestedCredentials":[] section is an array of the required VCs (currently with a single element). We need to add the ConferenceSession VC to the array. You can copy this from the Version3 app. Don't forget to add the comma between the two array elements.
Before we can run the app, we need to update verifier.js to set the “acceptedIssuers” DID in both array elements. Open verifier.js and locate the following line of code:
presentationConfig.presentation.requestedCredentials[0].acceptedIssuers[0] = mainApp.config["IssuerAuthority"]
This sets the DID into the "acceptedIssuers" element for the Alumni credential, which is element [0].
Add another line to set the value for element [1].
presentationConfig.presentation.requestedCredentials[1].acceptedIssuers[0] = mainApp.config["IssuerAuthority"]
Your verifier.js file should now have these two lines of code:
Run the app and verify your credential. You will be prompted to present an Alumni VC and ConferenceSession VC.
If you examine the results shown on the website you will see the two cards have been presented with the following claims:
["VerifiableCredential","Alumni"],"claims":{"firstName":"John","lastName":"Williams"}
["VerifiableCredential","ConferenceSession"],"claims":{"session":"Keynote with John Craddock","email":"john@example.com","code":"34hg7no"}
Wrap-up…
If you have got this far, well done. Again, it has been a long blog. However, you are now able to define the types of VCs you want to use and start evaluating the exciting new technology.
Please let me know on Twitter or LinkedIn your thoughts on VCs and how you plan to use them.
Please let your friends and colleagues know about the blog via LinkedIn and Twitter, don't forget to include me, so I see it! @john_craddock www.linkedin.com/in/johnxts
My next identity masterclasses are coming soon, and it would be great to meet with you for a week of identity geekery! Full details at https://learn.xtseminars.com
Creating my own Azure AD Verifiable Credential was an eye-opener, reminding me about the structured approach I used while working on my marketing dissertation help. It is like breaking down a hugely complex topic into manageable chunks for research, which indeed requires planning and execution to set up verifiable credentials.