If you’ve read the previous blog post or are already an expert, you know that the verifiable credentials spec is interesting enough to completely change the way we handle user identities. At the end of the day though, the thing that matters is getting it working and into the hands of real users. In this post, I’ll walk you through how we implemented Entra Verified ID.

Building the demo

Since Verifiable Credentials is based on a regular Web2 REST API, there’s no steep learning curve of figuring out how to pin data to the blockchain or IPFS – Microsoft handles that for you. However, it does inform your architecture decisions. Effectively, you have two options:

1. Integrate Verified ID with your existing identity solution

This is how the Woodgrove demo works and how the in-person verifier works. This approach is recommended for apps that are currently in production and integrated with an OpenID Connect (OIDC) based identity provider (basically anything not green-field).
Essentially, your identity provider works with an API to issue a Verifiable Credential with your identity provider’s user key (objectId in our case). When you present that credential back to the IdP, it is able to resolve your account and log you in. Since the credential is both cryptographically signed by the issuer, it can act as a valid identifier. The demo below uses the “id token hint” attestation flow where the user’s identifier (object ID in this case) is passed directly to the Verified ID API to issue the credential.
Note that there is another flow – the “id token” attestation, which ties the VC directly to the OpenID IdP and requires the user to sign in on their device.
To try the demo, go to https://woodgrovedemo.com/Configuration and select “Local & Social with Integrated DID” and hit “update”.
Then, go to “https://woodgrovedemo.com/Account/LogIn” and select “Sign in with your personal account”.
This will take you through the sign-up flow where you’ll be presented with an ID to scan and add to your wallet. You should then be able to log out and back in using the Verifiable Credential issued to you.

2. Use Entra Verified ID directly in a greenfield app

With this method, you need control over the full web stack. Since Verified ID is a REST API that requires a token, your app needs to be able to keep a secret. So you need a backend, and that backend needs to interact with Verified ID.
Another problem is that there are multiple callback events that your app needs to respond to. When the user scans the QR code, Azure notifies your app (request_retrieved). If verification or issuance was successful, you get an event there too:
So, your app effectively needs a webhook-like endpoint that Azure can POST to…but then how do you notify the frontend? You could do polling…but that can get costly at scale and you waste resources looking for events that aren’t there yet. Enter Websockets:
Now when the server receives a callback event from Verified ID, we can notify the client immediately, in real time! The frontend app feels better with this too since there’s no wait for the next poll interval.
But wait, there’s more. In testing, we found that iOS is pretty aggressive about terminating WebSocket connections. Since mobile users need to switch to Microsoft Authenticator to present their credential, this was a big problem, because when users came back, their WebSocket connection wasn’t restored and the flow was broken.
I was at a bit of a loss, but I figured if Jackbox games got it working, I could too (anyone else play a lot of Jackbox during the pandemic? Party Pack 9 is out by the way).
I ended up writing a device identifier + server-side caching solution to allow clients to reconnect and get the latest event that happened while they were offline.
Well that was a lot of work but I’d say it was worth it! You could run through the whole demo on your phone if you wanted to which I think is pretty cool (not to mention usable and practical).

Wrap Up

As you can see, Verifiable Credentials is very much a service that you have to wrap your own solution around. Having said that, the hardest part is rewiring your brain to learn all the new concepts and new ways of doing things. In my experience, the API has has solid uptime. The documentation is good, but code samples are lacking for anything that’s not C# .NET.