DSA: Which field values of the following documents are locator DIDs and which are identity DIDs?

Create your own magic with Web 7.0 DIDLibOS™ / TDW AgenticOS™. Imagine the possibilities.

Copyright © 2026 Michael Herman (Bindloss, Alberta, Canada) – Creative Commons Attribution-ShareAlike 4.0 International Public License
Web 7.0™, Web 7.0 DILibOS™, TDW AgenticOS™, TDW™, Trusted Digital Web™ and Hyperonomy™ are trademarks of the Web 7.0 Foundation. All Rights Reserved.

DSA: Which field values of the following documents are locator DIDs and which are identity DIDs?

  • DID Document
  • VC Document
  • DIDComm Message

In what follows, each document type is systematically and precisely mapped to the DID identity/locator framework.


DID Document

{
"id": "did:drn:z6Mk...9xEg", ← IDENTITY
"controller": "did:drn:z6MkController...abc", ← IDENTITY
"alsoKnownAs": ["did:drn:z6MkAka...xyz"], ← IDENTITY
"verificationMethod": [{
"id": "did:drn:z6Mk...9xEg#key-1", ← LOCATOR
"controller": "did:drn:z6Mk...9xEg", ← IDENTITY
"type": "Ed25519VerificationKey2020",
"publicKeyMultibase": "z6Mk..."
}],
"authentication": [
"did:drn:z6Mk...9xEg#key-1" ← LOCATOR
],
"assertionMethod": [
"did:drn:z6Mk...9xEg#key-1" ← LOCATOR
],
"capabilityInvocation": [
"did:drn:z6Mk...9xEg#key-1" ← LOCATOR
],
"capabilityDelegation": [
"did:drn:z6Mk...9xEg#key-1" ← LOCATOR
],
"keyAgreement": [
"did:drn:z6Mk...9xEg#key-2" ← LOCATOR
],
"service": [{
"id": "did:drn:z6Mk...9xEg#vcregistry-1", ← LOCATOR
"type": "CredentialRegistry",
"serviceEndpoint": "https://registry.example.com/..." ← URL (retrieval)
},
{
"id": "did:drn:z6Mk...9xEg#didcomm-1", ← LOCATOR
"type": "DIDCommMessaging",
"serviceEndpoint": "https://agent.example.com/..." ← URL (retrieval)
}]
}

Pattern: id at the document root is always an identity DID. Every field that contains a fragment — verification methods, verification relationships, service entries — is always a locator DID. controller is always an identity DID. serviceEndpoint values are retrieval URLs, outside the DID identity/locator taxonomy entirely.


VC Document

{
"@context": [...],
"id": "did:drn:z6MkCredential...abc", ← IDENTITY (envelope identity)
"type": ["VerifiableCredential", "MembershipCredential"],
"issuer": {
"id": "did:drn:z6MkIssuer...3kRt", ← IDENTITY
"name": "Web 7.0 Foundation"
},
"validFrom": "2026-01-01T00:00:00Z",
"validUntil": "2027-01-01T00:00:00Z",
"credentialSubject": {
"id": "did:drn:z6MkSubject...9xEg", ← IDENTITY (subject identity)
"memberOf": "did:drn:z6MkOrg...7fPq", ← IDENTITY
"role": "Member"
},
"credentialStatus": {
"id": "did:drn:z6MkStatus...8bNm", ← LOCATOR (points into status registry)
"type": "StatusList2021Entry"
},
"cryptoseal": [{
"type": "DataIntegrityProof",
"verificationMethod": "did:drn:z6MkIssuer...3kRt#key-1", ← LOCATOR
"cryptosuite": "eddsa-2022",
"created": "2026-01-01T00:00:00Z",
"proofValue": "z58DAdFfa..."
}]
}

Pattern: Top-level id, issuer.id, credentialSubject.id, and any DID references within claims are all identity DIDs — they name entities. credentialStatus.id and proof.verificationMethod are locator DIDs — they navigate to sub-resources. The credentialStatus.id is the one field that often goes unrecognized as a locator but clearly is: it points into a status registry to retrieve the current revocation state of this specific credential.


DIDComm Message

{
"id": "urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6", ← IDENTITY (message identity — URN, not DID)
"type": "https://didcomm.org/basicmessage/2.0/message", ← IDENTITY (IRI naming message type)
"typ": "application/didcomm-encrypted+json",
"from": "did:drn:z6MkSender...abc", ← IDENTITY
"to": ["did:drn:z6MkRecipient...xyz"], ← IDENTITY
"thid": "urn:uuid:parent-thread-id", ← IDENTITY (thread identity)
"pthid": "urn:uuid:parent-parent-thread-id", ← IDENTITY (parent thread identity)
"created_time": 1704067200,
"expires_time": 1704153600,
"from_prior": {
"iss": "did:drn:z6MkPrior...def", ← IDENTITY (prior DID — rotation)
"sub": "did:drn:z6MkSender...abc", ← IDENTITY (new DID — rotation)
"aud": "did:drn:z6MkRecipient...xyz" ← IDENTITY
},
"body": {
"content": "..."
},
"attachments": [{
"id": "attachment-1", ← IDENTITY (attachment identity)
"media_type": "application/vc+ld+json",
"data": {
"links": ["did:drn:z6MkSubject...9xEg?service=CredentialRegistry"] ← LOCATOR
}
}]
}

Pattern: DIDComm message fields are overwhelmingly identity DIDs — from, to, from_prior.iss, from_prior.sub, from_prior.aud all name parties, not locations. The message id is typically a URN UUID — an identity token outside the DID space entirely. Locator DIDs appear only when explicitly navigating to a sub-resource — such as a CredentialRegistry service endpoint in an attachment link, or a verification method reference in an attached cryptoseal.


Cross-Document Summary

FieldDID DocVC DocDIDComm
Document idIdentityIdentityIdentity (URN)
controllerIdentity
issuer / issuer.idIdentity
credentialSubject.idIdentity
from / toIdentity
from_prior.iss / .subIdentity
verificationMethod.idLocator
Verification relationship refsLocator
service.idLocator
proof.verificationMethodLocator
credentialStatus.idLocator
Attachment links with ?service=Locator

The governing rule across all three document types is consistent and clean:

A DID with no # or ? is always an identity DID — it names an entity.
A DID with # or ? is always a locator DID — it navigates to a sub-resource.
This rule holds uniformly across DID Documents, VC Documents, and DIDComm Messages.

Leave a comment

Filed under Uncategorized

Leave a comment