Credentials

SD-JWT VC

SD-JWT VC is a verifiable credential format built on JSON Web Tokens with selective disclosure added, so a holder can reveal individual claims from an issuer signed credential. It is one of the two formats the EU Digital Identity Wallet uses, the other being ISO mdoc.

Also called: SD-JWT VC, SD-JWT, dc+sd-jwt, vc+sd-jwt

At a glance

Core spec
RFC 9901 (selective disclosure), published November 2025
VC layer
draft-ietf-oauth-sd-jwt-vc, at -17 in mid 2026
EUDI ARF pins
Draft 15, may be updated to 16
Media type
dc+sd-jwt (earlier drafts used vc+sd-jwt)
Presentation format
JWT ~ disclosure ~ ... ~ optional key binding JWT
Sibling format
ISO 18013-5 mdoc, used for mDL and the EU age attestation

What it adds to a JWT

A plain JWT is all or nothing: the payload is readable by anyone holding the token, so presenting it reveals every claim in it. SD-JWT keeps the JWS structure and replaces disclosable claims with digests, moving the values into separate disclosures that travel alongside and are handed over one by one.

Around that sits the VC layer, which adds the things a credential needs beyond the mechanism: a type (vct), issuer identification with key resolution and optional holder key binding so a presentation can be tied to the device holding it.

Which spec version to build against

This is the question that costs implementers time, and the answer is three different numbers. The selective disclosure core is settled: it became RFC 9901 in November 2025 and will not move. The SD-JWT VC layer on top is still an Internet-Draft, at -17 as of mid 2026.

And the EU Architecture and Reference Framework pins draft 15, with a note that 16 may be used. So if you are building for the EU wallet specifically, the newest IETF draft is not the target: the ARF's pin is. Building against -17 means implementing something the ecosystem you are joining does not yet reference.

How a presentation is put together

A presentation is the issuer signed JWT, then each disclosure being revealed, then optionally a key binding JWT, all joined with tildes. A trailing tilde with nothing after it means there is no key binding. That format detail catches people out, because an empty final segment and a missing final segment mean different things.

The key binding JWT is signed by the holder's own key and ties the presentation to a specific verifier and moment. Verifying it is what shows the presenter holds the credential and did not copy it, and it is a separate check from verifying the issuer signature.

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 building for the EU wallet, target the draft the ARF pins, not the newest one. The gap between them is currently two revisions, and matching IETF instead of the ecosystem is how you end up conformant to nothing anyone is using.

If you're assessing a credential, verifying the issuer signature and verifying key binding are two different checks. Only the second shows the presenter holds the key the credential was bound to.

Frequently asked

Is SD-JWT VC replacing mdoc in the EU wallet?

No, both are in use. mdoc comes from the ISO mobile driving licence world and is CBOR based; SD-JWT VC is JSON based and comes from the OAuth world. The EU age verification attestation is an mdoc, for example, while other attestations are SD-JWT VC.

Do I need the holder's public key to verify one?

You need the issuer's key to verify the credential itself. You need the holder key, from the cnf claim, only to verify key binding. Only presentations that carry a key binding JWT have one.

What does the trailing tilde mean?

That there is no key binding JWT. A presentation ending in a tilde has none; one ending in a nonempty segment has that segment as the key binding JWT. It tells you whether key binding is present, not whether you hold an issued credential or a presentation.

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 stores no documents or dates of birth and proves someone is over 18 with the EU age verification app (the EU Digital Identity Wallet follows once our access certificate is issued). Signup is open and a test project works as soon as you create one. Tell us what you're building.