Resolution is the act of turning a DID string into a DID Document you can trust. It is an eight-stage pipeline, and the rules at each stage exist because something went wrong without them.

The pipeline

1. Parse DID

Extract the namespace, entity kind, and identifier from the DID string. The resolver validates the format against the did:oas method specification and extracts four components: method (oas), namespace, entity kind, and the multibase-encoded identifier. Malformed DIDs are rejected with a parse error, immediately. Output: ParsedDid { method, namespace, kind, identifier }

2. Check Cache

Look up the DID Document in the local resolution cache — time-bounded entries carrying the document, version, and TTL. Valid entries return immediately; invalidation happens on TTL expiry or a deactivation notification. Output: Hit(document) | Miss

3. Network Resolution

On a cache miss, query the resolution network. OAS supports multiple transports: HTTP-based Universal Resolver, DHT-based P2P resolution, and direct endpoint resolution when the Document names a self-hosted location. Output: NetworkResponse { document, metadata, transport }

4. Schema Validation

Validate the raw Document against the canonical OAS JSON Schema: required fields (id, verificationMethod), each verification method’s format, valid service endpoint URLs, and entity-kind consistency. Output: ValidationResult { valid, errors? }

5. Signature Verification

Verify the Document’s self-signature: extract the proof, identify the verification method, canonicalize the document with JCS (RFC 8785), and verify the Ed25519 signature. Constant-time, to prevent timing side-channels. Output: SignatureResult { valid, method }

6. Revocation Check

Check the deactivated flag in document metadata, and query the anchor backend’s revocation state before accepting any privileged path. For delegated DIDs, every ancestor and edge in the lineage path must remain active — revocation cascades down the tree. Output: Active | Revoked(reason)

7. Lineage Authority Check

For privileged actions, verify against the anchor backend: root anchors exist, metadata commitments match, typed lineage edges are present at or before the finalized block, org lineage roots include the creator, and nothing in the chain is revoked or expired. The backend is pluggable (Sigil is the reference; any LineageAnchor backend can stand in via the verifier’s anchor policy). Output: Verified(path) | Rejected(reason)

8. Return Result

Package the verified Document with resolution metadata: content type, resolution timestamp, resolver version, cache status, transport used, and the verification audit trail. The result is cached for future lookups. Output: ResolutionResult { document, metadata, audit }

The rules embedded in the pipeline

  1. Parse before fetch. Malformed inputs never touch the network.
  2. Signature before trust. A Document is attacker-controlled until its self-signature verifies — the same normative ordering as ACT verification.
  3. Revocation is authoritative, not advisory. A revoked ancestor poisons the whole tree below it.
  4. Authority paths fail closed. An unreachable anchor means the privileged action is not authorized — never a best-effort pass.

Next