Skip to content
ecdsa.com

SD-JWT Inspector

Paste an SD-JWT, SD-JWT VC or a presentation with a key-binding JWT. The inspector follows the processing rules of RFC 9901 step by step and shows exactly which claims were disclosed.

100% local — everything runs in your browser, nothing is sent to any server

Source: RFC 9901 (November 2025), signed with the Appendix A.5 issuer key. Checked as of the KB-JWT creation time (2025-05-29).

Compact form with ~ separators, or JWS JSON
Keys
A JWK, a JWK Set, or a PEM public key or certificate
Only when cnf names the key by kid or jkt
Verifier policy
Check as ofTimes are in UTC.
Token Status List
The JWT served at status.status_list.uri
Usually the issuer key

Selective disclosure in one paragraph

An SD-JWT (RFC 9901) is a signed JWT in which some claims have been replaced by their hashes. The issuer signs the JWT with the digests and hands the holder the claims themselves as separate disclosures — base64url-encoded JSON arrays of a random salt, the claim name and its value. When presenting the credential, the holder appends only the disclosures the verifier needs, separated by ~. The verifier hashes each disclosure, finds the digest in the signed payload, and puts the claim back in its place; claims whose disclosures were left out stay invisible, and the issuer may add decoy digests so that even their number reveals nothing. SD-JWT VC builds verifiable credentials on top of this format, with a typ of dc+sd-jwt and a credential type in vct; it is one of the two credential formats of the European Digital Identity Wallet, the other being the mdoc of ISO 18013-5.

What the inspector does with your SD-JWT

It follows the verification rules of RFC 9901 §7 and reports every step:

  1. Splitting. Compact form (<issuer-signed JWT>~<disclosure>~…~[<KB-JWT>]) or the JWS JSON serialization of §8, flattened or general, are both accepted. A missing final ~, empty disclosures or a key-binding JWT in the wrong place are reported.
  2. The issuer-signed JWT. alg must not be none or a MAC; the signature is verified with the issuer key you paste — a JWK, a JWK Set (the key is chosen by kid, and every skipped candidate is explained) or a PEM public key or certificate — or with the certificate chain in the token's own x5c header.
  3. _sd_alg. The hash algorithm of the digests, SHA-256 when absent; SHA-384, SHA-512 and SHA3 variants are supported.
  4. Disclosures. Each one must decode to a JSON array of two (array element) or three (object property) items with a string salt; a short salt, a reused salt, a duplicated disclosure or one that no digest references are errors or warnings, because each of them breaks a property selective disclosure relies on.
  5. Processing. The inspector walks the payload, replaces every _sd digest and every {"...": digest} array element by its disclosed value, recursively, and refuses what §7.1 forbids: a disclosed name that already exists, the reserved names _sd and ..., a digest that occurs twice. The result is the disclosed claims, exactly the object a verifier's application receives. Digests left without a disclosure are counted per object and array.
  6. Validity. exp, nbf and iat of the processed payload are compared with the check time.

As a cross-check, the same input is decoded by @sd-jwt/core, the OpenWallet Foundation's reference implementation, and the inspector tells you whether it arrives at the same claims.

Key binding and sd_hash

A disclosure can be copied. What stops someone who saw a presentation from replaying it is key binding (RFC 9901 §4.3): the issuer puts the holder's public key in the cnf claim, and at presentation time the holder signs a short KB-JWT with typ kb+jwt, the verifier's aud, a fresh nonce, iat, and sd_hash — the hash of the presented SD-JWT with exactly the chosen disclosures. The inspector checks the KB-JWT signature with the key in cnf (or the holder key you paste, when cnf names it only by kid or thumbprint), recomputes sd_hash, compares aud and nonce with the values you expect, and checks that the KB-JWT is recent. Ticking Require a key-binding JWT turns a missing KB-JWT into an error, as a verifier with that policy would.

Token Status List

An SD-JWT VC can point at a revocation list: status.status_list names a URI and an index (Token Status List). The list is a JWT (typ statuslist+jwt) whose status_list.lst is a DEFLATE-compressed bit string, one, two, four or eight bits per credential. Paste that token and the inspector decompresses it, checks its sub against the URI, its iat, exp and ttl, verifies its signature, and reads the credential's entry: 0 valid, 1 invalid (revoked), 2 suspended. The page does not download the list itself — fetching it from your browser would tell the issuer which credential you are checking, which is precisely what the list's design avoids — so it shows the curl command instead.

The examples are the issuance, presentation, SD-JWT VC and JSON-serialization vectors of RFC 9901, signed with its Appendix A.5 key, and the referenced token and Status List Token of the status list draft, where the credential at index 0 is revoked. How these credentials fit into the EU Digital Identity Wallet is explained in SD-JWT and SD-JWT VC: selective disclosure for EUDI wallets.