Credentials

Selective disclosure

Selective disclosure is the ability to reveal some claims from a signed credential while keeping the rest hidden, without breaking the issuer's signature. It works by signing digests of salted values rather than the values themselves, so the holder can hand over only the values they choose and the verifier can still check every one against what was signed.

Also called: selective disclosure, salted hashes, data minimisation

At a glance

Mechanism
Salted hashes: sign digests of salted values, not the values
Core spec
RFC 9901, published November 2025
Formats using it
SD-JWT VC (JSON), and mdoc via a comparable digest scheme
Salt exists to
Stop a verifier brute-forcing a low-entropy value
Recursive
A disclosed value can carry further digests

How it works, in one paragraph

The issuer takes each disclosable claim, adds a random salt, and signs a digest of the result instead of the claim itself. The signed credential therefore contains a list of digests and nothing readable. Alongside it travel the disclosures, one per claim, each holding the salt, the name and the value. To reveal a claim you hand over its disclosure; to hide one you simply do not.

The verifier hashes each disclosure it receives and checks the result appears among the signed digests. Anything not handed over stays a digest, which reveals nothing, and the salt is what stops a verifier guessing a low-entropy value like a birth year by brute force.

Why this is stronger than a promise

The usual alternative is a service that receives everything and undertakes to delete what it does not need. That is a promise about behaviour, and you audit it by trusting whoever made it. Selective disclosure is a property of the format: the undisclosed values are not in the message, so there is nothing to delete, nothing to breach and nothing to produce in response to a subject access request.

It also moves the decision to the holder. The wallet, not the verifier, decides what leaves the device, and the consent screen is the moment that happens.

The part implementers get wrong

Disclosure is recursive. A disclosed value can itself contain further digests naming more disclosures, so a nested claim like an address with a selectively disclosable street is ordinary. A verifier that only looks for digests in the top-level signed payload will report a perfectly good nested credential as not binding. We shipped that bug and fixed it, which is why it is called out here.

The other one is arithmetic on multiplicity. RFC 9901 requires rejecting a credential where a digest appears more than once, and a naive implementation storing digests in a set throws away exactly the information that rule is about.

Check one yourself

Reading about it only gets you so far. These are free validators in Tessio Labs, no signup, and nothing you paste is stored.

Why it matters

If you're assessing a privacy claim, ask whether the data is absent or merely deleted afterwards. Only one of those is checkable by looking at the message.

If you're implementing, handle nesting and reject a reused digest. Both are in RFC 9901, and both are the kind of rule that a test suite of happy-path credentials never exercises.

Frequently asked

Can the verifier see the claims I did not disclose?

No. What travels is a digest, which reveals nothing about the value. The salt means the verifier can't narrow it down by guessing either, which matters for a value with few possibilities like a year of birth.

Does hiding claims break the issuer signature?

No, and that's the whole trick. The signature covers the digests, which don't change when you choose not to reveal the value behind one.

Is this the same as zero knowledge proofs?

No. Selective disclosure reveals the actual values you chose to share. A zero knowledge proof can answer a question about a value without revealing the value at all. Salted hashes are simpler, deployed today, and reveal more.

Primary sources

This is a plain language explanation, not legal advice. Specifications and dates in this area move, so check anything you are going to rely on against the primary sources.

Keep reading

Age verification API

Or skip the theory and build against it

Tessio proves someone is over 18 from their EU Digital Identity Wallet and stores no personal data. Access is invite only while we onboard design partners. Tell us what you're building.