Verifiable Credentials Technical Overview (DID Credential Flows)

Microsoft has launched ION hosting (beta) on Bitcoin mainnet, and new verifiable credentials service (private preview) on Azure Active Directory (Azure AD).

ION is an open source and permissionless, Decentralized Identifier (DID) network, which runs on Sidetree protocol. (I have described a walk-through about ION-based network in my early post.)
On contrary, verification credentials (VC) handles the workflow of proofs and assertions between users, issuers, and verifiers. In the physical world, the users will submit one’s proofs, such as, student’s ID card, driver’s license, so on and so forth, for getting permissions of using some services. This will be achieved between the users and parties, such as, companies, schools, and other agencies.
The flow of digital verification credentials handles the same manners along with W3C open standard specification (see here).

In this post, I show you the outline (the concepts and flows) of verifiable credentials (VC) with several payload examples.

Before starting, I have several notices.
In the perspective of W3C specification, verifiable credential (VC) doesn’t rely on DID specification. (i.e, The “id” property used in VC shouldn’t be necessarily a DID.) However, in its real implementations, it might be expected that verifiable credentials will resolve DIDs with consistent decentralized manners and technologies. Then, in this post, we also assume that DID is used with verifiable credentials.
In order to explain things plainly, I’ll include not only VC flows, but also other parts of flows, such as, DID flows or OpenID compliant flows. I note that I won’t explicitly separate these descriptions in this post.
For details about exact W3C specification of verifiable credentials, see “Verifiable Credentials Data Model 1.0“.

Users (Holders), Issuers, and Verifiers

Before seeing the details about flows and payloads, here I show you the base concepts and ideas of Verifiable Credentials.

Imagine that you will get the discount for students in some specific service.
In this scenario, you will receive the student ID card from your belonging school (agency), and submit this card to this service provider. This service provider will see your card and verify whether it’s a correct (valid) ID – i.e, this ID is surely issued by an existing agent (school) – and it’s surely issued for you.

In general scenarios, there will exist multiple issuers and verifiers. Then the holder (the user) might submit one or more credentials for verifiers.
The credential issued by issuer (authority) is called a verifiable credential. The verifiable credential will include not only ID (in this post, we assume it has a DID format), but also other attributes called claims, such as, degree, major, badge, and so on. When one or more credentials are requested by verifiers (service providers), the holder will assemble collections of verifiable credentials (which are issued from different issuers) into a single artifact, called a verifiable presentation.

Credential Format

Both verifiable credentials and verifiable presentations are tamper-evidents, in which authorship and non tampering are proved by digital signatures. These format can be either of JWT (Json Web Token) or Linked Data Proofs.
Throughout this post, I’ll explain using a JWT format.

As I explained in my early post about Azure Active Directory (see here), JWT consists of the following components. (Here I show you again as follows.)

  • JWT has 3 string tokens delimited by the dot (.) character.
  • Each delimited tokens (each 3 string tokens) consists of :
    1. Meta information about key :
      e.g, the type of key, key id, X.509 Thumbprint, and so on.
    2. Claims :
      e.g, subject (sub), issuer (iss), expiration (nbf and exp), so on and so forth. (It depends on the applications.)
    3. Digital signature :
      A digital signature signed by a private key. This is a byte code, not UTF string.
  • Each delimited tokens should be encodes by Base64 URL encoding (encoded by RFC 4686), which is the Base64 string replaced with : “+” to “-“, “/” to “_”, and removed all “=” characters in its termination.

By verifying a digital signature with public key, you can ensure that this JWT is signed by the correct user (or agent) who has a private key.
If the claims will be changed, the digital signature should also be changed. Therefore, you can also ensure that these claims are not tampered by malicious programs.

For simplicity, we only focus on the above 2nd token (i.e, JWT claims) in this post, but the entire message will be signed by
issuers, holders or verifiers, as I mentioned above.
With DID ecosystem, a digital signature can be verified using public keys in DID network without any specific servers or providers. (See here for details.)

Note : The payload in JWT will be easily viewed using the parser service in the internet. (For instance, go to https://jwt.io/ .)

Run Issuer

First of all, the issuer registration will be needed in verifiable credential’s system.

In verifiable credential’s scenario, all issuers, holders, and verifiers should have cryptographic key pairs.
There’ll exist multiple issuers, so each issuer will have the corresponding id and corresponding key pairs (i.e, DID).

For example, in Verifiable Credentials Service on Azure AD, you can register your own issuer with cryptographic key pairs (which are stored in your key vault on Azure) by configuring the required settings in the Azure Portal. (See here for details about settings.) I note that the issuer’s DID will be soon created, but the registration will be completed in around 10 minutes, since this service runs on ION with Bitcoin mainnet as underlying blockchain network. (See my early post “Consensus Algorithms in Blockchain” for Bitcoin consensus.)

Note : When you’re using Verifiable Credentials Service on Azure AD, you can see whether DID is active or not, by connecting https://beta.discover.did.microsoft.com/1.0/identifiers/{your DID} in your web browser. (See my early post “Walkthrough of Decentralized Identity (DID) Implementation (ION)“.)


Once the issuer is ready, now we can start to issue a verifiable credential for user (holder).

There will be needed several steps for issuing new verifiable credential with decentralized identifiers (DID).

First, the user (holder) should generate key pairs (both private key and public key) for user’s DID. (When using ION with underlying Bitcoin blockchain, secp256k1 with ECDSA algorithm should be used.)
The private key will be saved on user’s wallet, and this key will be used for generating a signature. This wallet might be the secure personal storage, such like a local storage on browser, a device app (Authenticator), an isolated desktop application, so on and so forth. (In the complete system, this key can be backuped or transferred, since it’s such like your identification and crucial for you.)
The public key is registered into the DID network, and everyone can use this public key for verifying user’s signature.

Now the issuer can create (issue) the user’s verifiable credential, which has the following json payload. (This sample is the one issued by VC Service on Azure AD.)

The following iss is issuer’s DID, and the sub is user’s DID.
As I mentioned above (see my description about JWT), this payload will be signed using issuer’s key (i.e, issuer’s DID, did:ion:EiBz3b8v9c...) and formatted as a JWT.

  "jti": "urn:pic:ab1b223e-cd94-462d-91cc-55ee1895dbc8",
  "vc": {
    "@context": [
    "type": [
    "credentialSubject": {
      "givenname": "Tsuyoshi",
      "surname": "Matsuzaki",
      "degree": "master",
      "major": "mathematics"
    "credentialStatus": {
      "id": "https://portableidentitycards.azure-api.net/v1.0/1f659db9-9812-4c4d-b958-405e30571b65/portableIdentities/card/status",
      "type": "PortableIdentityCardServiceCredentialStatus2020"
    "revokeService": {
      "id": "https://portableidentitycards.azure-api.net/v1.0/9c59be8b-bd18-45d9-b9d9-082bc07c094f/portableIdentities/card/revoke",
      "type": "PortableIdentityCardServiceRevoke2020"
  "iss": "did:ion:EiBz3b8v9c...",
  "sub": "did:ion:EiDYHnvoiz...",
  "iat": 1592992800,
  "exp": 1595584800

In this payload, the properties in credentialSubject are claims, and others are metedata.
The claims will depend on each issuers. For instance, the issuer of other university might have “certificate” or “badge”. (In my service, I have defined above 4 claims, “givenname”, “surname”, “degree”, and “major”.)

In the verification phase (which I explain later in this post), the verifier might expect some specific types of claims. For instance, some service provider (verifier) might require “age” claim for ensuring that the user is over 20 years old.
The type property in above metadata declares what type of data is this credential. In my example, this credential has the type “VerifiedCredentialTest”.

Note : In Verifiable Credentials Service on Azure AD, you should set the value of credential type on the uploaded rule file in the issuer. (See here.)

As I mentioned above, this verifiable credential is signed by issuer’s key (did:ion:EiBz3b8v9c...). Therefore the users (holders) cannot change these claims (such as, “degree”, “major”, …) by their wills. It means that this credential is proved to be surely issued by this agent.

In Verifiable Credentials Service on Azure AD, it assumes a traditional (current) OpenID compliant identity provider – such as, Azure AD, Azure AD B2C, so on and so forth – as a source provider to issue the verifiable credential.
When the user (holder) starts to request the issuance with Authenticator app in device (by reading QR code), the login for the source OpenID provider is required. After the user has successfully signed-in, the issuer maps the claims of source OpenID provider to the verifiable credential’s claims, and complete issuance of a verifiable credential to the user. Once it’s issued, the user will use this verifiable credential for sign-in, then this source provider (traditional OpenID identity provider) will no longer be used.

Fig : The user should login to current OpenID provider (“Azure AD” in this example) for allowing issuance.
(From “Verifiable Credentials as a Service by Azure AD” Tutorials)

Note : For configuring OpenID compliant provider (current OpenID provider), see “Tutorials – Source credentials from an identity provider“.

Here I don’t go so far, but, in Verifiable Credentials Service on Azure AD, all workflows (issuance, sign-in, …) in verifiable credentials are also performed by OpenID compliant manners using request_uri, redirect_uri, id_token, so on and so forth. (Though the protocol name is “verifiablecredential://”.)
For this OpenID compliant flow for decentralized identifier, see SIOP (Self-Issued OpenID Connect Provider) in DIF documentation.

Authenticate (Sign-In)

Here I’ll show you the outline of authentication with the above issued verifiable credential.
In this scenario, we assume 2 roles, the verifier and the user. (We assume that the verifier also has one’s own key pair.)

First, the verifier (who provides some services) will request the submission of credentials for the user.
Imagine that some verifier might require “age” claim for ensuring the user is over 20 years old. In order to tell the user these requirements, the verifier will specify the type of credentials (e.g, “VC issued by some agent”, “VC issued by US gov for some purposes”, …) in the submission request. As you saw above, this type is the same as type property written in a verifiable credential (in our example, “VerifiedCredentialTest”).
I note that the verifier might request the multiple VCs, i.e, multiple types. (In current identity technology, multiple federations at a time will be impossible.)

Note : This request will also be expected to be signed by verifier’s DID (corresponding private key), and the user can check whether this request is valid or not using a public key.

After the user has accepted (for passing the requested credentials), then the user aggregates the corresponding credentials in one’s wallet and create a submission, called a verifiable presentation. This presentation is signed (as a JWT format) by user’s private key (this key is also stored in user’s wallet) as a tamper-evident. (See below illustrated.)

After the user agent passes a verifiable presentation (JWT) to the verifier, then the verifier will extract user’s public key from DID network and check (verify) the sigunature to ensure it’s surely generated by this user.

Using metadata and claims in each submitted credential, the verifier will also check whether the submitted credential is exactly same as the requested type, whether it’s expired or not, and other additional requirements, such as, user’s license, so on and so forth. (These verification will depend on application’s requirements.)
If it’s valid, finally the verifier (service provider) will provide the services.

Note : If the user agent, such as Authenticator app, is used, this response (including a verifiable presentation) will be synced with user’s UI session.
In the example application for Verifiable Credential Services on Azure AD, this is done by using sessions on server and state in SIOP.

Let’s see an example json of a verifiable presentation. (See below. This sample is generated by Microsoft Authenticator VC add-on.)

The “eyJraWQiOiJkaWQ6aW9u...” in verifiableCredential property is a JWT string of above verifiable credential (which is signed by an issuer, not a user). If multiple credentials are required, you can add more VCs in this verifiableCredential property.
The iss is user’s DID. As I mentioned above, this payload (verifiable presentation) is signed by the user’s private key (i.e, this DID, did:ion:EiDYHnvoiz...) and formatted as a JWT.
The verifier will check (verify) all these signatures – both the user’s one in presentation’s JWT and issuer’s ones in verifiableCredential – and ensure that this is surely generated by this user and these credentials are surely issued by the corresponding issuers. (These public keys are all shared in DID network.)

  "jti": "934000f9-1a34-4c38-a9f4-cdfaeb5d35be",
  "vp": {
    "@context": [
    "type": [
    "verifiableCredential": [
  "iss": "did:ion:EiDYHnvoiz...",
  "iat": 1592992800,
  "exp": 1595584800,
  "nbf": 1592992800,
  "aud": "https://7b41783ac7a9.ngrok.io/issue-response"

In Verifiable Credential Services on Azure AD, these process are performed between the service app (such as, a web app) and Authenticator app (mobile app). For details about implementation, see the source code for service application (which uses Verifiable Credentials NodeJS SDK) and authenticator application (which uses PortableIdentityCard-ClientSDK).


In this post, I summarized what is a verifiable credential and how it’s used in the applications.
This style of identity and credentials are very much like ones in our physical world. I hope this credentials backed by decentralized technology will mitigate the impedance mismatch between the real world and the digital world in the near future.


Reference :

Verifiable Credentials as a Service by Azure AD


Categories: Uncategorized

Tagged as: , ,

2 replies »

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s