page_type languages products description urlFragment
sample
node.js
powershell
Entra
Verified ID
A code sample demonstrating issuance and verification of verifiable credentials.
entra-verifiedid-node

Verifiable Credentials Code Sample

This code sample demonstrates how to use Microsoft's Entra Verified ID to issue and verify verifiable credentials.

Deploy to Azure

Deploy to Azure

About this sample

Welcome to Microsoft Entra Verified ID standalone Node.js sample repository. In this sample, we'll help you to deploy a Verifier app that will help you verifye a VerifiedEmployee Verified ID issued to your employees. You could always customize it to accept under Verified ID credentials as well. The sample uses the REST API which supports VerifiedEmployee VC type to pass as a payload for the verifiable credential.

Contents

The project is divided in 2 parts, one for issuance and one for verifying a verifiable credential. Depending on the scenario you need you can remove 1 part. To verify if your environment is completely working you can use both parts to issue a verifiedcredentialexpert VC and verify that as well.

Issuance
public\issuer.html The basic webpage containing the javascript to call the APIs for issuance.
issuer.js This is the file which implements express routes which contains the API called from the webpage. It calls the REST API after getting an access token through MSAL.
issuance_request_config.json The sample payload send to the server to start issuing a VC.
Verification
static\verifier.html The webpage acting as the verifier of the verifiable credential.
static\presentation-verified.html The webpage that displays the result of the presented VC
verifier.js This is the file which implements express routes which contains the API called from the webpage. It calls the REST API after getting an access token through MSAL and helps verifying the presented verifiable credential.
presentation_request_config.json The sample payload send to the server to start issuing a vc.

Setup

Before you can run this sample make sure your environment is setup correctly, follow the instructions in the documentation here.

Create application registration

Run the Configure.PS1 powershell script in the AppCreationScripts directory or follow these manual steps to create an application registrations, give the application the correct permissions so it can access the Verifiable Credentials Request REST API:

Register an application in Azure Active Directory:

  1. Sign in to the Azure portal using either a work or school account or a personal Microsoft account.
  2. Navigate to the Microsoft identity platform for developers App registrations page.
  3. Select New registration
    • In the Name section, enter a meaningful application name for your issuance and/or verification application
    • In the supported account types section, select Accounts in this organizational directory only ({tenant name})
    • Select Register to create the application
  4. On the app overview page, find the Application (client) ID value and Directory (tenant) ID and record it for later.
  5. From the Certificates & secrets page, in the Client secrets section, choose New client secret:
    • Type a key description (for instance app secret)
    • Select a key duration.
    • When you press the Add button, the key value will be displayed, copy and save the value in a safe location.
    • You’ll need this key later to configure the sample application. This key value will not be displayed again, nor retrievable by any other means, so record it as soon as it is visible from the Azure portal.
  6. In the list of pages for the app, select API permissions
    • Click the Add a permission button
    • Search for APIs in my organization for 3db474b9-6a0c-4840-96ac-1fceb342124f or Verifiable Credential and click the “Verifiable Credentials Service Request”
    • Click the “Application Permission” and expand “VerifiableCredential.Create.All”
    • Click Grant admin consent for {tenant name} on top of the API/Permission list and click YES. This allows the application to get the correct permissions Admin concent

Setting up and running the sample

To run the sample, clone the repository, compile & run it. It's callback endpoint must be publically reachable, and for that reason, use a tool like ngrok as a reverse proxy to reach your app.

git clone https://github.com/Azure-Samples/active-directory-verifiable-credentials-node.git
cd active-directory-verifiable-credentials-node\1-node-api-idtokenhint

Create your credential

To use the sample we need a configured Verifiable Credential in the azure portal. In the project directory CredentialFiles you will find the VerifiedCredentialExpertDisplay.json file and the VerifiedCredentialExpertRules.json file. Use these 2 files to create your own VerifiedCredentialExpert credential.

If you navigate to your Verifiable Credentials blade in azure portal, follow the instructions how to create your first verifiable credential.

You can find the instructions on how to create a Verifiable Credential in the azure portal here

Make sure you copy the value of the credential URL after you created the credential in the portal. Copy the URL in the CredentialManifest part of the config.json. You need to manually copy your Microsoft AAD Verifiable Credential service created Decentralized Identifier (did:ion..) value from this page as well and paste that in the config.json file for IssuerAuthority and VerifierAuthority.

API Payloads

The API is called with special payloads for issuing and verifying verifiable credentials. The sample payload files are modified by the sample code by copying the correct values defined in the config.json file. If you want to modify the payloads issuance_request_config.json and presentation_request_config.json files yourself, make sure you comment out the code overwriting the values in the issuer.js and verifier.js files. The code overwrites the Authority, Manifest and trustedIssuers values. The callback URI is modified in code to match your hostname.

The file run.cmd is a template for passing the correct variables and run your node.js VC application.

Running the sample

In order to build & run the sample, you need to have the node installed locally.

  1. After you have edited the file config.json, start the node app by running this in the command prompt
npm install
.\run.cmd
  1. Using a different command prompt, run ngrok to set up a URL on 8080. You can install ngrok globally from this link.
ngrok http 8080
  1. Open the HTTPS URL generated by ngrok. API Overview The sample dynamically copies the hostname to be part of the callback URL, this way the VC Request service can reach your sample web application to execute the callback method.

  2. Select GET CREDENTIAL

  3. In Authenticator, scan the QR code.

If this is the first time you are using Verifiable Credentials the Credentials page with the Scan QR button is hidden. You can use the add account button. Select other and scan the QR code, this will enable the preview of Verifiable Credentials in Authenticator.

  1. If you see the 'This app or website may be risky screen', select Advanced.
  2. On the next This app or website may be risky screen, select Proceed anyways (unsafe).
  3. On the Add a credential screen, notice that:
  • At the top of the screen, you can see a red Not verified message.
  • The credential is based on the information you uploaded as the display file.
  1. Select Add.

Verify the verifiable credential by using the sample app

  1. Navigate back and click on the Verify Credential link
  2. Click Verify Credential button
  3. Scan the QR code
  4. select the VerifiedCredentialExpert credential and click allow
  5. You should see the result presented on the screen.

About the code

Since the API is now a multi-tenant API it needs to receive an access token when it's called. The endpoint of the API is https://verifiedid.did.msidentity.com/v1.0/{YOURTENANTID}/verifiableCredentials/createIssuanceRequest

To get an access token we are using MSAL as library. MSAL supports the creation and caching of access token which are used when calling Azure Active Directory protected resources like the verifiable credential request API. Typical calling the library looks something like this:

var accessToken = "";
try {
  const result = await mainApp.msalCca.acquireTokenByClientCredential(mainApp.msalClientCredentialRequest);
  if ( result ) {
    accessToken = result.accessToken;
  }
} catch {
    console.log( "failed to get access token" );
    res.status(401).json({
      'error': 'Could not acquire credentials to access your Azure Key Vault'
      });  
    return; 
}

And creating an access token:

const msalConfig = {
  auth: {
      clientId: config.azClientId,
      authority: `https://login.microsoftonline.com/${config.azTenantId}`,
      clientSecret: config.azClientSecret,
  },
  system: {
      loggerOptions: {
          loggerCallback(loglevel, message, containsPii) {
              console.log(message);
          },
          piiLoggingEnabled: false,
          logLevel: msal.LogLevel.Verbose,
      }
  }
};
const cca = new msal.ConfidentialClientApplication(msalConfig);
const msalClientCredentialRequest = {
  scopes: ["3db474b9-6a0c-4840-96ac-1fceb342124f/.default"],
  skipCache: false, 
};

Important: At this moment the scope needs to be: 3db474b9-6a0c-4840-96ac-1fceb342124f/.default This might change in the future

Calling the API looks like this:

var payload = JSON.stringify(presentationConfig);
console.log( payload );
const fetchOptions = {
  method: 'POST',
  body: payload,
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': payload.length.toString(),
    'Authorization': `Bearer ${accessToken}`
  }
};
var client_api_request_endpoint = `https://verifiedid.did.msidentity.com/v1.0/verifiableCredentials/createPresentationRequest`;
const response = await fetch(client_api_request_endpoint, fetchOptions);
var resp = await response.json()

Deploying the sample to Azure AppServices

If you deploy the sample to Azure AppServices, as an alternative to using ngrok, you need to update the files config.json, issuance_request_config.json and presentation_request_config.json with your changes before you do Deploy To Web App in VSCode. After you have deployed your sample app, AppServices starts it via invoking the npm start command, which means if those files contain the right settings, your app will start successfully. When you create an Azure AppService instance, you should select Runtime stack = Node and OS = Linux and select the same region that you have your Azure KeyVault deployed to.

package.json

  ...
  "scripts": {
    "start": "node app.js ./config.json ./issuance_request_config.json ./presentation_request_config.json",
  ...

If the app doesn't start, if you view the logs in AppServices LogStream, you may see the problem. See docs.

Troubleshooting

Did you forget to provide admin consent? This is needed for confidential apps

If you get an error when calling the API Insufficient privileges to complete the operation., this is because the tenant administrator has not granted permissions to the application. See step 6 of 'Register the client app' above.

You will typically see, on the output window, something like the following:

Failed to call the Web Api: Forbidden
Content: {
  "error": {
    "code": "Authorization_RequestDenied",
    "message": "Insufficient privileges to complete the operation.",
    "innerError": {
      "request-id": "<a guid>",
      "date": "<date>"
    }
  }
}

Understanding what's going on

As a first source of information, the Node sample will trace output into the console window of all HTTP calls it receives. Then a good tip is to use Edge/Chrome/Firefox dev tools functionality found under F12 and watch the Network tab for traffic going from the browser to the Node app.

Best practices

When deploying applications which need client credentials and use secrets or certificates the more secure practice is to use certificates. If you are hosting your application on azure make sure you check how to deploy managed identities. This takes away the management and risks of secrets in your application. You can find more information here:

More information

For more information, see MSAL.NET's conceptual documentation: