Construct the SD-JWT: for each claim to be selectively disclosable, replace the claim value in the JWT payload with a hash of a disclosure object (salt + claim name + value); include the hashes in a _sd array in the JWT payload.
Sign the JWT (the Issuer-signed JWT, or I-JWT) with the issuer's key; the typ header should be 'dc+sd-jwt' for VC use cases.
Append each disclosure as a base64url-encoded JSON string separated by '~' after the JWT; the final SD-JWT string is: <I-JWT>~<disclosure1>~<disclosure2>~...
For presentation, the holder selects which disclosures to include (omitting others achieves selective disclosure), optionally appends a Key Binding JWT (KB-JWT) signed with the holder's key to bind the presentation to the verifier's nonce, and sends the resulting SD-JWT+KB.
The verifier: splits on '~', verifies the I-JWT signature, computes SHA-256 of each included disclosure and confirms each hash appears in the _sd arrays, reconstructs the plaintext claims from the disclosed values, and verifies the KB-JWT nonce and audience.
Known gotchas
Salt values in disclosures must be cryptographically random (at least 128 bits) and unique per disclosure; predictable salts allow verifiers or adversaries to brute-force undisclosed claim values.
The _sd_alg claim in the JWT payload specifies the hash algorithm (default sha-256); if omitted, implementations must assume sha-256 — explicitly including it avoids ambiguity.
Omitting the Key Binding JWT means the presentation is not audience-bound and could be replayed by any verifier who obtains it; always include KB-JWT for online presentations.
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp