Selective disclosure mechanics, two mechanisms, two different guarantees, one of them unaudited
Our BBS+ implementation is UNAUDITED.
The distinction this page exists to make
Selective disclosure and unlinkability are not the same property, and almost every explainer treats them as one. The merge flatters vendors, us included, so here they are separated:
- Selective disclosure, you reveal some fields from a credential and withhold the rest. The verifier learns your date of birth without learning your address.
- Unlinkability: two presentations of the same credential, to two different verifiers, cannot be correlated with each other even if those verifiers collude and compare notes.
The first does not imply the second. You can reveal one field and still hand over something that identifies the credential itself, which is a correlation handle whether or not you meant it to be.
Mechanism one: SD-JWT VC, shipped, and honestly bounded
This is the path that is live. Our issuer advertises it in standard metadata, and you can check that yourself:
$ curl -s https://capture-api.solidus.network/.well-known/openid-credential-issuer
format : vc+sd-jwt
HTTP 200, checked 2026-07-31. A format any conformant SD-JWT VC verifier can read.
What it gives you: genuine selective disclosure. Fields are individually disclosable; the ones you withhold are not revealed.
What it does not give you, by design: unlinkability. The digests of the undisclosed fields still travel with every presentation. Unless a credential is single-use, those digests are, in principle, a correlation handle for verifiers who collude.
That is a property of the mechanism, not a defect in our implementation: it is true of SD-JWT everywhere. We are saying it because a reader who assumed "selective disclosure" meant "untrackable" would be wrong, and would be wrong in our favour.
What we do about it, and its limit: we bind a credential to its holder with a key-bound proof, so a stolen credential cannot be presented by someone else. That controls who can present. It does not control whether presentations can be linked. It is a narrower guarantee than unlinkability and we are not going to let the two be confused.
Mechanism two: BBS+, the unlinkable path, and the unaudited one
Unlinkability specifically requires the BBS+ path. Rather than re-showing the same signature each time, the holder derives a fresh zero-knowledge proof per presentation, so two presentations share nothing a colluding pair of verifiers could match.
That is the design's intent. It is not a verified security property of our code, because our implementation has not been audited.
You can run the demonstration yourself, from the public registry:
$ npm i @solidus-network/auth @solidus-network/bbs # 0.6.3, checked 2026-07-31
$ node node_modules/@solidus-network/auth/demo/unlinkability-demo.mjs
The demo ships inside the published tarball, we verified that by fetching the tarball from the registry rather than trusting our own repository, and its own printed output states the boundary: external audit pending (NLnet NGI Zero, H2 2026 target).
A demonstration that announces its own unfinished audit is the correct shape for this. The argument is good; what is unverified is our implementation, not the shape of the idea.
How to choose between them
- Need to withhold fields from one verifier? SD-JWT VC does that today, and it is the live path.
- Need presentations to different verifiers to be uncorrelatable? That requires BBS+, and you would be relying on unaudited cryptographic code. For anything with real consequences, that is a reason to wait for the audit rather than a reason to proceed carefully.
We would rather lose the deal than have that sentence discovered later.
Other limits worth knowing
- The SDK is TypeScript only. Other language bindings are roadmap, not shipped.
- There is one credential configuration advertised by the issuer today.
Keep reading
- Vendor lock-in. We are also a vendor, and adopting us creates a real dependency of its own
- Liveness detection, what is built, what has not cleared review, and what depends on deployment
- Presentation attack detection, whose model this actually is, and a threshold we have never evaluated
- The OID4VP verifier, real endpoints, real policy knobs, and one of them means less than it reads