← Insights
chain

On-Chain Identity and Verifiable Credentials

Proving who someone is, or what's true, without a central authority and without leaking everything onto a public ledger. The privacy-verifiability tradeoff, built

A user needs to prove they are over 18, or accredited, or a licensed professional, or simply the same person who held an account last month. The naive on-chain answer is to write the fact to the chain and let anyone read it. That answer is a privacy disaster. A public ledger is the worst possible place to store identity data, because it is public, permanent, and correlatable forever. Write someone's date of birth on-chain to prove they are an adult and you have published their date of birth to everyone, for all time, linked to every other thing that wallet ever did.

The hard version of this problem — the one worth building — is proving something true without a central authority vouching for it on every request, and without spilling the underlying data onto a permanent public record. Those two requirements pull in opposite directions, and the engineering is in resolving the tension rather than picking a side.

Here is how we build it.

The three roles, and why they have to stay separate

Every credential system has three roles, and conflating any two of them is where designs go wrong.

The issuer asserts a fact: a government attests to age, a regulator attests to accreditation, a university attests to a degree. The holder receives that assertion and controls it. The verifier — a relying party — needs to check the fact before granting access.

The failure most teams ship is making the verifier call the issuer on every check. That rebuilds the centralized model with extra latency: the issuer becomes a bottleneck, sees every place the credential is used, and can deny service. The whole point of verifiable credentials is that the holder can prove the issuer's assertion to a verifier without the issuer being in the loop. The cryptographic signature does the vouching, offline, after the fact. The issuer signs once. The holder presents the signed credential however many times they like, to whomever they like, and the issuer never knows.

Keeping these roles separate is the architecture. The issuer signs and steps away. The holder custodies. The verifier checks a signature, not a server.

DIDs: identity without an account at a company

A decentralized identifier is an identifier the subject controls, resolvable to a set of public keys and service endpoints, that does not live in any company's user table. The point is not the string. The point is that control of the identifier is proven by control of a key, not by a password stored on someone's server that can be reset, leaked, or revoked by the company.

This matters because it decouples identity from any single provider. A credential issued to a DID stays valid even if the platform that introduced the user disappears, because the binding is to a key the user holds, not to a row the company maintains. For mission-critical systems — where a user's access or credential cannot evaporate because a vendor changed their terms — this is the property that justifies the whole approach.

What goes on-chain here is deliberately minimal. Not the identity. At most a DID document or a pointer to one, and often the on-chain footprint is just the issuer's public key and a revocation registry. The identity data itself stays off the public ledger entirely. The chain provides the one thing it is good at — a tamper-evident, censorship-resistant anchor for public keys and revocation status — and nothing else.

The verifiable credential: signed, held, presented

A verifiable credential is a set of claims, signed by the issuer, bound to the holder's identifier. "This DID is over 18, signed by this issuer." The holder stores it themselves — in a wallet, off-chain. When a verifier asks, the holder presents it, and the verifier checks the issuer's signature against the issuer's known public key.

Nothing about that flow requires the chain except, optionally, two things: discovering the issuer's public key, and checking whether the credential has been revoked. Both are small, both are public by nature, and both are exactly what a chain is good for. The credential payload — the actual claims about a person — never touches the ledger. This is the discipline that separates a real credential system from a privacy leak: the public ledger holds keys and revocation, the holder's wallet holds the claims.

Revocation is the part teams forget. Credentials expire and get revoked — a license is suspended, an accreditation lapses. A credential that can never be revoked is not a credential, it is a permanent assertion of a fact that may no longer be true. So the design includes a revocation registry the verifier checks, built so that checking revocation does not leak which credential is being checked. A naive revocation list that reveals the holder every time a verifier looks them up has reintroduced the surveillance the whole system was meant to remove.

Zero-knowledge and selective disclosure: the actual hard part

Here is the requirement that breaks naive designs. The verifier needs to know the user is over 18. The verifier does not need, and should not get, the date of birth. The credential contains the date of birth. How does the holder prove the derived fact without revealing the underlying data?

This is selective disclosure, and at its strongest it is zero-knowledge. The holder generates a proof that the signed credential contains a date of birth implying an age over 18, and the verifier checks the proof. The verifier learns one bit — over 18, true — and nothing else. Not the date. Not the exact age. Not enough to correlate the user across services.

This is the difference between a credential system that protects users and one that turns every verification into a data exposure. With selective disclosure, a single rich credential — issued once — can answer many narrow questions without ever revealing more than the question asked for. "Over 18" without the birthday. "Resident of an eligible jurisdiction" without the address. "Accredited" without the financial statements. The proof reveals the predicate, never the premise.

The cost is real and worth naming. Zero-knowledge proofs are computationally heavier to generate, the circuits are specialized work to build and audit, and the holder's wallet has to do real cryptographic work. We use ZK where the privacy requirement is strict — regulated identity, anything where correlation is itself a harm — and simpler signed selective disclosure where the threat model does not warrant the cost. Reaching for ZK on every field because it sounds rigorous is how a project ships a wallet that takes thirty seconds to prove someone is a human. Engineering judgment is choosing the lightest mechanism that actually meets the threat model.

The privacy-verifiability tradeoff, made concrete

The whole field is one tradeoff. More verifiability — more parties able to independently confirm a fact — tends to mean more data exposed. More privacy — less data exposed — tends to mean leaning harder on cryptography to preserve the ability to verify at all.

The on-chain part of the system is where this tradeoff bites hardest, because the chain is permanent and public. So our rule is narrow and load-bearing: the chain holds only what is meant to be public forever. Issuer keys. Revocation status. Schema definitions. Never claims, never personal data, never anything that correlates a person across their activity. Everything private stays in the holder's custody and is revealed, if at all, through proofs that disclose the minimum.

Get that boundary right and the system is both verifiable and private. Get it wrong — write one personal field to the chain "to make verification easier" — and you have built a permanent surveillance record that no later fix can erase, because the ledger does not forget.

This is the kind of provenance-and-verification work we have shipped in production, where what had to be proven was tightly scoped and what stayed private stayed private. See how we approached Sigil →

What fixed looks like

A credential system we would put our name on keeps the issuer, holder, and verifier roles cleanly separated, so verification never phones home to the issuer. The chain anchors only public, permanent data — keys, revocation, schemas — and never personal claims. Holders custody their own credentials. Revocation works and does not leak who is being checked. And where the threat model demands it, selective disclosure and zero-knowledge proofs let a verifier learn exactly one true bit and nothing more.

A user proves they are over 18 a hundred times and leaks their birthday zero times. A verifier confirms a license without calling the regulator. And nothing private was ever written somewhere it can never be erased.

This is for you if

You are building a system where users must prove identity, eligibility, or credentials, and getting it wrong means either a privacy breach on a permanent public record or a centralized bottleneck that defeats the point. You want the privacy-verifiability boundary engineered correctly the first time, because on a ledger there is no second time. The scope for a production identity and verifiable-credential system — DID infrastructure, issuance and revocation, and selective-disclosure or ZK proofs where warranted — runs $100k and up depending on the strength of the privacy requirement.

This is not for you if you need a login and a profile table. That is a database, not a credential system, and you should build the database.