Decentralized Identity & Privacy

When CTOs Should Build or Buy Decentralized Identity

A CTO choosing a decentralized identity stack is choosing where failures, privacy decisions, and exit costs will live. My default is to buy credential issuance and protocol plumbing, then keep verification policy and authorization in-house. Building the entire stack is justified only when an external service cannot meet a specific trust or availability requirement. A standards-compliant demo is not evidence that either choice will survive production.

Buying the credential rail wins when the hard problem is operations

Option A: buy a managed credential platform. Give the provider responsibility for issuer endpoints, signing-key operations, protocol updates, and operational support. Keep your applications responsible for deciding what a verified claim permits. This wins when your team needs interoperable credentials but has no unusual requirement to run issuance or verification inside its own trust boundary, because maintaining those services consumes engineering time without settling your organization’s access rules.

Option B: build an in-house credential stack. Own the issuer, verifier, key lifecycle, status service, and protocol adapters. This wins when verification must continue without a provider connection, or when a provider cannot satisfy a documented custody constraint, because those requirements cannot be fixed by a better service-level agreement. It costs more than initial implementation: your team also owns compatibility testing, incident response, and upgrades when wallets or counterparties change behavior.

Put both options against the same transaction. An employee presents a credential to request access to an internal application. The verifier checks the issuer’s signature, the holder-binding proof where applicable, the credential’s status, and the requested audience. Your policy service then maps the accepted claims to an entitlement. That last step should remain yours under either option, because a vendor cannot reliably infer what an employee should be allowed to do in your systems.

Ask vendors to demonstrate the exact formats and flows you intend to use. W3C Verifiable Credentials Data Model v2.0 describes the credential data model; OpenID for Verifiable Credential Issuance 1.0 and OpenID for Verifiable Presentations 1.0 address issuance and presentation flows. A product’s support for one does not establish support for the others, because data format and exchange protocol solve different problems. If the proposal includes SD-JWT, test which claims a holder can withhold and which identifiers remain visible; selective disclosure does not itself prevent presentations from being linked.

For a planning comparison, suppose an in-house implementation reserves 3 engineers for 8 weeks at 40 hours per week. That is 960 engineer-hours before ongoing operations, and it is a capacity estimate to replace with your own staffing plan. A purchased service instead incurs contract charges, integration work, and potential migration costs. Compare those costs against the same acceptance tests rather than treating the vendor quote as the total cost of buying.

Building wins when the verifier must survive outside the vendor’s boundary

The strongest reason to build is not a preference for owning code. It is an enforceable requirement that your verifier continue making decisions during a provider outage, a network partition, or a contract dispute. If a vendor-hosted API must answer every presentation request, its availability becomes part of your access path. A vendor-published 99.9% monthly uptime commitment, if offered, permits roughly 43 minutes of downtime in a 30-day month; that calculation says nothing about whether an outage will occur during a critical access request.

Some purchased products can still meet an offline requirement by exporting material that a self-operated verifier can use. Require a demonstration: disconnect the provider, present an already issued credential, validate its signature and holder binding, and apply a locally available status rule. If the test fails because verification silently calls a vendor endpoint, either negotiate a different architecture or build that verification component yourself. Do not buy a hosted verifier on the assumption that its SDK is an offline verifier, because an SDK can be a client for a remote decision.

Status checking deserves a separate privacy test. A verifier that asks an issuer about each credential can reveal where and when a holder presents it. W3C Bitstring Status List v1.0 offers a way to publish status information for local checking, though the deployment still needs a refresh and caching policy. Set a 15-minute maximum status-list age as an initial value to tune against your revocation needs; a shorter interval reduces the window for stale status but increases network dependence. Record which component fetches lists and whether that fetch can identify the holder.

I would not build a new credential format or cryptographic proof scheme to gain this control, because a bespoke format makes external wallet support and independent security review harder. Build a verifier around specified formats, or buy one that can run under your control. DID Core v1.0, the did:web method, JSON Web Keys under RFC 7517, and OAuth 2.0 mutual-TLS client authentication under RFC 8705 are concrete choices to evaluate where they fit the design; none substitutes for a written rule about which issuers your organization trusts.

Standards support does not make a provider replaceable

Portability has at least three parts: credentials already issued must remain verifiable, new credentials must be issuable elsewhere, and your application policies must keep working. A vendor can pass a standards checklist while retaining control of issuer keys, status publication, or proprietary claim mappings. The first failure may appear only when you try to leave, because a successful issuance-and-presentation demo rarely tests departure.

I disagree with the sequencing implied by Measure Privacy Before You Scope Decentralized Identity for this decision: measure privacy during evaluation, but test exit before signing, because a privacy-preserving pilot can still leave issued credentials dependent on a vendor-controlled status endpoint. Put the ownership of signing keys and status infrastructure in the contract. Ask whether you can retain the issuer identifier, rotate keys, export audit records, and continue verifying credentials issued before termination. A promise to export credential JSON is insufficient if the corresponding trust and status services disappear.

Identifiers also affect both portability and privacy. Reusing one subject identifier across applications makes correlation easier because the same value can join otherwise separate presentation records. A pairwise identifier can reduce that exposure when your access model permits it. This Python 3 example runs as written and produces different pseudonyms for two audiences:

python3 - <<'PY'
import hashlib
import hmac
import os
key = os.urandom(32)
subject = b"internal-user-274"
for audience in ("app-a.example", "app-b.example"):
    message = audience.encode() + b"\0" + subject
    scoped = hmac.new(key, message, hashlib.sha256).hexdigest()
    print(audience, scoped)
PY

This is a design illustration, not a credential or an authorization check. Production use needs protected key storage, a rotation plan, and a decision about whether account recovery requires stable mappings, because losing the HMAC key prevents regeneration of these pseudonyms. It also needs a review of other correlating fields: distinct subject values provide little benefit if every presentation includes the same unique claim.

Decentralized Identity and Privacy for Modern IT Systems is useful context, but privacy should be a purchase condition rather than a reason to select a decentralized architecture: a vendor that receives every verification request may learn more about use than an existing identity system did. Require a data-flow diagram showing wallet, issuer, verifier, status host, and logs. Then ask who can join those records and how deletion works, because decentralizing an identifier does not decentralize the telemetry around it.

A reversible pilot is more valuable than a feature comparison

Run a pilot with one issuer, one application, and one credential whose claims your policy service can evaluate without vendor-specific fields. Make the acceptance tests identical for buying and building. The managed option wins if it passes those tests with less operating work and an acceptable exit path. The in-house option wins if the managed option fails a non-negotiable boundary test and your team can demonstrate that it can operate the alternative.

Start with a negative test, not a polished presentation. Reject an untrusted issuer, an expired credential, a presentation for the wrong audience, and a credential whose status has changed. Test holder binding where your chosen presentation profile requires it. These cases matter because a verifier that accepts a valid signature without checking context can authorize the wrong request. Record the reason for each rejection in a log that does not copy the entire credential, because full presentation logging can defeat selective disclosure.

Next, impose an outage and an exit. Disconnect the vendor during verification; then switch to a second verifier using documented exports. Set 2 independent verifiers as a pilot acceptance target to adjust if your deployment has a different recovery design. Give the team 30 days as a trial migration window, not as a claim that every production migration should finish that quickly. Count manual steps, broken credentials, policy changes, and issuer dependencies. A replacement verifier that accepts signatures but cannot reproduce status decisions has not completed the migration.

Finally, measure the access path you will operate. Set an initial 200 ms p95 verification-latency budget for a local test, then revise it against your application’s actual latency allowance and the cost of fresh status checks. Treat a staging result as measured only after recording load, cache state, and network conditions. Request the same observations from a vendor-hosted path, because a fast cached demonstration is not comparable to an uncached verification that contacts external services.

The pilot should produce a decision record, not a platform roadmap. Name the owner of issuer keys, trust-list changes, status freshness, policy rules, and incident response under each option. Price the work of changing those owners later. If buying passes the boundary and exit tests, buy the rail; if it cannot pass a documented boundary test, build the necessary component rather than purchasing a promise to fix it.

Make the first decision an outage test

Book a test session before approving a vendor shortlist. Have one engineer disconnect the proposed verifier from its provider, another present a previously issued credential, and the access-policy owner record the resulting decision and its evidence. That small exercise will expose the real dependency faster than another standards matrix. Use its failure mode to decide whether to buy, build, or change the boundary between them.