It’s not going to be a surprise that I’ve been working with Decentralized Identity over the last couple of years. A common thing I find myself doing is checking/debugging DID documents. Like many others I started with tools like the ION Network Explorer for the ION network and pasting in DID Web URLs into a browser. That evolved into a few functions in PowerShell to simplify and automate validation. This has now evolved into the Decentralized Identity Searcher PowerShell Module I’ve just published.
The Decentralized Identity Searcher PowerShell Module enables simple methods for searching the ION and Web networks for DID documents to discover their keys and endpoints.
How do I use it?
The module contains two key cmdlets:
- Search-DecentralizedIdentifier
- takes the -ION or -Web switches and then either the ION identifier or the Web Address of the DID Document (using the -FQDN parameter)
- Get-DIDJWTDetails
- decodes a DID JWT token
The following screenshot shows:
- searching the ION network for the DID identifier ‘EiB29JB4R0mbLmJ6_BEYjr8bGZKEPABwFopSNsDJBh_Diw’
- retrieving the DID document from the URL “https://identity.foundation/.well-known/did-configuration.json”
- decoding a linked DID from the DID document returned from “https://identity.foundation/.well-known/did-configuration.json”
Installation
The module is published in the PowerShell Gallery and is also available on GitHub.
From an Admin PowerShell session, install from the PowerShell Gallery
install-module -name DIDSearcher
or download from the PowerShell Gallery
Examples
DID ION Network
Search the ION network using a DID identifier to discover its keys and endpoints
Search-DecentralizedIdentifier -ION -identifier 'EiB29JB4R0mbLmJ6_BEYjr8bGZKEPABwFopSNsDJBh_Diw' | FL
The following DID document is returned
id : did:ion:EiB29JB4R0mbLmJ6_BEYjr8bGZKEPABwFopSNsDJBh_Diw
@context : {https://www.w3.org/ns/did/v1, @{@base=did:ion:EiB29JB4R0mbLmJ6_BEYjr8bGZKEPABwFopSNsDJBh_Diw}} verificationMethod : {@{id=#key-1; controller=did:ion:EiB29JB4R0mbLmJ6_BEYjr8bGZKEPABwFopSNsDJBh_Diw; type=EcdsaSecp256k1VerificationKey2019; publicKeyJwk=}} authentication : {#key-1}
Search the ION network using a DID to discover its keys and endpoints and output the document elements and hierarchy.
Search-DecentralizedIdentifier -ION -identifier 'EiB29JB4R0mbLmJ6_BEYjr8bGZKEPABwFopSNsDJBh_Diw' -outputHierarchy
The following DID document details are returned.
Path Value
---- -----
$.@context[0] https://www.w3.org/ns/did/v1
$.@context[1].@base did:ion:EiB29JB4R0mbLmJ6_BEYjr8bGZKEPABwFopSNsDJBh_Diw
$.authentication[0] #key-1
$.id did:ion:EiB29JB4R0mbLmJ6_BEYjr8bGZKEPABwFopSNsDJBh_Diw
$.verificationMethod[0].controller did:ion:EiB29JB4R0mbLmJ6_BEYjr8bGZKEPABwFopSNsDJBh_Diw
$.verificationMethod[0].id #key-1
$.verificationMethod[0].publicKeyJwk.crv secp256k1
$.verificationMethod[0].publicKeyJwk.kty EC
$.verificationMethod[0].publicKeyJwk.x 70EFbTwnhjbsbcJl0Fja5OOPOfDTrlaqX2J_iXvxRRE
$.verificationMethod[0].publicKeyJwk.y eWsMq6eJ-wpdIUGAMGTAdefazBH4sQMvuRo3U_mzM4o
$.verificationMethod[0].type EcdsaSecp256k1VerificationKey2019
DID Web
Get info from a DID Web document using the default-ish paths of https://{FQDN}/.well-known/did.json or https://{FQDN}/.well-known/did-configuration.json
By default, https://{FQDN}/.well-known/did.json is tried first. If not present https://{FQDN}/.well-known/did-configuration.json is tried.
Search-DecentralizedIdentifier -Web -FQDN "https://identity.foundation"
The following DID document is returned.
@context : {https://www.w3.org/ns/did/v1}
id : did:web:identity.foundation
In this instance Identity.Foundation has both a did.json and a did-configuration.json document. We can thereby call explicitly and get the .well-known/did-configuration.json document.
Search-DecentralizedIdentifier -Web -FQDN "https://identity.foundation/.well-known/did-configuration.json" | Format-List
The following DID document is returned.
@context : https://identity.foundation/.well-known/did-configuration/v1 linked_dids : {@{@context=System.Object[]; issuer=did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM; issuanceDate=5/12/2020 7:08:28 AM; expirationDate=5/12/2025 7:08:28 AM; type=System.Object[]; credentialSubject=; proof=}, eyJhbGciOiJFZERTQSJ9.eyJleHAiOjE3NjQ4Nzg5MDgsImlzcyI6ImRpZDprZXk6ejZNa29USHNnTk5yYnk4SnpDTlExaVJMeVc1UVE2UjhYdXU2QUE4aWdHck1WUFVNIiwibmJmIjoxNjA3MTEyNTA4LCJzdWIiOiJkaWQ6a2V5Ono2TWtvVEhzZ05OcmJ5OEp6Q05RMWlSTHlXNVFRNlI4WHV1NkFBOGlnR3JNVlBVTSIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly9pZGVudGl0eS5mb3VuZGF0aW9uLy53ZWxsLWtub3duL2RpZC1jb25maWd1cmF0aW9uL3YxIl0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmtleTp6Nk1rb1RIc2dOTnJieThKekNOUTFpUkx5VzVRUTZSOFh1dTZBQThpZ0dyTVZQVU0iLCJvcmlnaW4iOiJpZGVudGl0eS5mb3VuZGF0aW9uIn0sImV4cGlyYXRpb25EYXRlIjoiMjAyNS0xMi0wNFQxNDowODoyOC0wNjowMCIsImlzc3VhbmNlRGF0ZSI6IjIwMjAtMTItMDRUMTQ6MDg6MjgtMDY6MDAiLCJpc3N1ZXIiOiJkaWQ6a2V5Ono2TWtvVEhzZ05OcmJ5OEp6Q05RMWlSTHlXNVFRNlI4WHV1NkFBOGlnR3JNVlBVTSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJEb21haW5MaW5rYWdlQ3JlZGVudGlhbCJdfX0.6ovgQ-T_rmYueviySqXhzMzgqJMAizOGUKAObQr2iikoRNsb8DHfna4rh1puwWqYwgT3QJVpzdO_xZARAYM9Dw}
Just like with the ION example we can output the DID document elements and hierarchy
Search-DecentralizedIdentifier -Web -FQDN "https://identity.foundation/.well-known/did-configuration.json" -outputHierarchy
Which will output the following.
Path Value
---- -----
$.@context https://identity.foundation/.well-known/did-configuration/v1
$.linked_dids[0].@context[0] https://www.w3.org/2018/credentials/v1
$.linked_dids[0].@context[1] https://identity.foundation/.well-known/did-configuration/v1
$.linked_dids[0].credentialSubject.id did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM
$.linked_dids[0].credentialSubject.origin https://identity.foundation
$.linked_dids[0].expirationDate 5/12/2025 7:08:28 AM
$.linked_dids[0].issuanceDate 5/12/2020 7:08:28 AM
$.linked_dids[0].issuer did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM
$.linked_dids[0].proof.created 4/12/2020 8:08:28 PM
$.linked_dids[0].proof.jws eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..D0eDhglCMEjxDV9f_SNxsuU-r3ZB9GR4vaM9TYbyV7yzs1WfdUyYO8rFZdedHbwQafYy8YOpJ1iJlkSmB4JaDQ
$.linked_dids[0].proof.proofPurpose assertionMethod
$.linked_dids[0].proof.type Ed25519Signature2018
$.linked_dids[0].proof.verificationMethod id:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM#z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM
$.linked_dids[0].type[0] VerifiableCredential
$.linked_dids[0].type[1] DomainLinkageCredential
$.linked_dids[1] eyJhbGciOiJFZERTQSJ9.eyJleHAiOjE3NjQ4Nzg5MDgsImlzcyI6ImRpZDprZXk6ejZNa29USHNnTk5yYnk4SnpDTlExaVJMeVc1UVE2UjhYdXU2QUE4aWdHck1WUFVNIiwibmJmIjoxNjA3MTEyNTA4LCJzdWIiOiJka…
Additional examples of getting DID documents using DID Web from different URL options.
Search-DecentralizedIdentifier -Web -FQDN "https://identity.foundation/.well-known/mydid.json"
Search-DecentralizedIdentifier -Web -FQDN "https://identity.foundation:9000/user/alice/did.json"
Decode a DID JWT
The Decentralized Identity Searcher PowerShell Module also includes the ability to decode a linked DID JWT from a DID document.
This is based off my JWTDetails PowerShell Module. It also returns the expiryDateTime and timeToExpirey in as datetime elements in the PSObject.
$didResult = Search-DecentralizedIdentifier -Web -FQDN "https://identity.foundation/.well-known/did-configuration.json" $didResult.linked_dids[1] | Get-DIDJWTDetails
The decoded DID JWT document is returned.
exp : 1764878908
iss : did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM
nbf : 1607112508
sub : did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM
vc : @{@context=System.Object[]; credentialSubject=; expirationDate=5/12/2025 7:08:28 AM; issuanceDate=5/12/2020 7:08:28 AM; issuer=did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM; type=System.Object[]}
sig : 6ovgQ+T/rmYueviySqXhzMzgqJMAizOGUKAObQr2iikoRNsb8DHfna4rh1puwWqYwgT3QJVpzdO/xZARAYM9Dw==
expiryDateTime : 5/12/2025 7:08:28 AM
timeToExpiry : 1128.17:37:24.6985560
Summary
A simple but functional module to retrieve DID documents and functions to inspect them and their contents.