Skip to main content
European CommissionEBSI European Blockchain

Selective Disclosure with SD-JWT

Last updated on

Version: v1.0
Feedback: EBSI Help Desk

Introduction

The purpose of this guideline is to document how to use SD-JWT with both versions V1.1 and V2.0 of the W3C Verifiable Credentials Data Model (VCDM). The document also covers application of these models in either JSON or JSON-LD format, and methods for protecting them using JWS signatures (compact or JSON serialised).

Specifications published at the time of writing

SpecificationVersionNotes
SD-JWT0.4Limitation to JWT data model has been lifted, as there's no technical reason to limit into JWT.
JWSRFC 7515Both compact or JSON serialisation apply.
JWTRFC 7519JWS Compacted presentation, and JWT described claims.
VCDMV1.1, V2.0

Profile

This document is using the following profile for the SD-JWT

TopicProfileNotes
W3C Verifiable CredentialFormat: JSON or JSON-LDVerifiable Credentials can be processed as JSON for the purpose of the SD-JWT.
Note: W3C WG confirmed that Verifiable Credentials can be processed as JSON, even if the base media type is vc+ld+json
JWSCompact Serialised JWS*SD-JWT also defines a profile for JSON serialised JWS.
Note: IETF WG confirmed that the SD-JWT is extended to support any JSON and is therefore not limited to JWT.
Salt length128 bits/16 bytes
Hash algorithmSHA-256Use cases can propose other hashing algorithms.

*EBSI also supports JSON serialised JWS.

Main Components

  • Verifiable Credential (VC) is a JSON object carrying the information about a subject in clear text
  • Issuer issued disclosures are a set of disclosures (claim, salt, secret) that the issuer shares with the holder
  • SD-JWT is a digitally signed JSON document containing digests over the selectively disclosable claims with the Disclosures outside the document
  • Holder-selected disclosures are a set of disclosures (claim, salt, secret) that the holder shares with the verifier

sd-generic-flow

Issuance and Presentation

The issuance process of a Verifiable Credential with hidden claims is depicted below. First, the Verifiable Credential (VC) is constructed. Second, the issuer generates disclosures and updates the VC with the hidden claims. The output, known as an SD-JWT, has a data model consistent with a Verifiable Credential containing hidden claims.

sd-generic-flow

Placement of the _sd claim

For any selectively disclosable claim, the _sd key containing the digest value must be included in the SD-JWT at the same level as the original claim. Consequently, the _sd key may appear multiple times in an SD-JWT, even within the disclosures.

Input for the selective disclosure

Consider the following Verifiable Credential as input. The Verifiable Credential complies with both versions V1.1 and V2.0 of the W3C VCDM.

Original VC Data
{
"@context": ["https://www.w3.org/ns/credentials/v2"],
"id": "9bcc9aaa-3bdc-4414-9450-739c295c752c",
"type": ["VerifiableCredential", "StudentID"],
"issuer": "did:ebsi:zvHWX359A3CvfJnCYaAiAde",
"validFrom": "2023-01-01T00:00:00Z",
"validUntil": "2033-01-01T00:00:00Z",
"credentialSubject": {
"id": "did:key:z2dmzD81cgPx8Vki7JbuuMmFYrWPgYoytykUZ3eyqht1j9KbsDbVZXdb3jzCagESyY4EE2x7Yjx3gNwctoEuRCKKDrdNP3HPFtG8RTvBiYStT5ghBHhHizH2Dy6xQtW3Pd2SecizL9b2jzDCMr7Ka5cRAWZFwvqwAtwTT7xet769y9ERh6",
"familyName": "Carroll",
"givenName": "Lewis",
"birthDate": "1832-01-27",
"student": true
},
"credentialSchema": {
"id": "https://api-pilot.ebsi.eu/trusted-schemas-registry/v2/schemas/0x23039e6356ea6b703ce672e7cfac0b42765b150f63df78e2bd18ae785787f6a2",
"type": "FullJsonSchemaValidator2021"
}
}

Transforming the selected disclosures

Disclosures must be built by using any claim from a VC and protecting it with a secure random salt. The structure, as defined by the SD-JWT, is an ordered triplet represented in JSON. This contains, in order, a secure random salt, the attribute name and its value. The attribute value depends on the issuer's strategy for the disclosures. The attributes may be treated as flat, structured, recursive, or any combination thereof.

Terminal helpers to clarify the calculation. The sed command will turn base64 into base64url format.

Disclosure built from the data structure of a VC:
cmd: echo -n '["6qMQvRL5haj", "family_name", "Möbius"]' | openssl base64 -a -A | sed 's/+/-/g; s,/,_,g; s/=//g'
output: WyI2cU1RdlJMNWhhaiIsICJmYW1pbHlfbmFtZSIsICJNw7ZiaXVzIl0

Digest built from Disclosure:
cmd: echo -n "WyI2cU1RdlJMNWhhaiIsICJmYW1pbHlfbmFtZSIsICJNw7ZiaXVzIl0" | openssl sha256 -binary | openssl base64 -a -A | sed 's/+/-/g; s,/,_,g; s/=//g'
output: uutlBuYeMDyjLLTpf6Jxi7yNkEF35jdyWMn9U7b_RYY

In the following example, certain data fields have been chosen for selective disclosure by the issuer. Given the disclosure style is "structured", each claim can be disclosed separately.

Content: '["2GLC42sKQveCfGfryNRN9w", "familyName", "Carroll"]'
calculated Disclosure: WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImZhbWlseU5hbWUiLCAiQ2Fycm9sbCJd
calculated Digest: zSmImWHPJzQ7Rx8ZG0IYhUF1Ozj8f17wDKJGhxUkrdU


Content: '["eluV5Og3gSNII8EYnsxA_A", "givenName", "Lewis"]'
calculated Disclosure: WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImdpdmVuTmFtZSIsICJMZXdpcyJd
calculated Digest: T4RnDm1clVLCav2Mrsel6sNMz8pqGCeMrrp__YrV_-w

Content: '["6Ij7tM-a5iVPGboS5tmvVA", "birthDate", "1832-01-27"]'
calculated Disclosure: WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImJpcnRoRGF0ZSIsICIxODMyLTAxLTI3Il0
calculated Digest: SFQTjr91IkPi6betQ0EYs5rdJ2TbMesJGftF6h7hjTA

Output for Selective Disclosure

The transformation of the VC into SD-JWT, with the selected disclosures, will resemble the following:

SD-JWT
{
"@context": ["https://www.w3.org/ns/credentials/v2"],
"id": "9bcc9aaa-3bdc-4414-9450-739c295c752c",
"type": ["VerifiableCredential", "StudentID"],
"issuer": "did:ebsi:zvHWX359A3CvfJnCYaAiAde",
"validFrom": "2023-01-01T00:00:00Z",
"validUntil": "2033-01-01T00:00:00Z",
"credentialSubject": {
"id": "did:key:z2dmzD81cgPx8Vki7JbuuMmFYrWPgYoytykUZ3eyqht1j9KbsDbVZXdb3jzCagESyY4EE2x7Yjx3gNwctoEuRCKKDrdNP3HPFtG8RTvBiYStT5ghBHhHizH2Dy6xQtW3Pd2SecizL9b2jzDCMr7Ka5cRAWZFwvqwAtwTT7xet769y9ERh6",
"_sd": [
"zSmImWHPJzQ7Rx8ZG0IYhUF1Ozj8f17wDKJGhxUkrdU",
"T4RnDm1clVLCav2Mrsel6sNMz8pqGCeMrrp__YrV_-w",
"SFQTjr91IkPi6betQ0EYs5rdJ2TbMesJGftF6h7hjTA"
],
"student": true
},
"credentialSchema": {
"id": "https://api-pilot.ebsi.eu/trusted-schemas-registry/v2/schemas/0x23039e6356ea6b703ce672e7cfac0b42765b150f63df78e2bd18ae785787f6a2",
"type": "FullJsonSchemaValidator2021"
},
"_sd_alg": "sha-256"
}

Issuance of the SD-JWT

The SD-JWT and the Disclosures are issued to the holder as a single concatenated string, with the tilde ~ serving as a separator. The first block comprises the SD-JWT, while the remainder constitutes the Disclosures.

Combined Format for Issuance
<SD-JWT>~<Disclosure 1>~<Disclosure 2>~...~<Disclosure N>
Example Credential Response with in-time flow
{
"format": "jwt_vc",
"credential": "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDplYnNpOnp2SFdYMzU5QTNDdmZKbkNZYUFpQWRlI0YwcjVPeXRfbGFodnZ6Nk1XbFlzM21jWU5LWmlpUWRVZnF2OHRzaEhOOXcifQ.eyJpc3MiOiJkaWQ6ZWJzaTp6dkhXWDM1OUEzQ3ZmSm5DWWFBaUFkZSIsInN1YiI6ImRpZDprZXk6ejJkbXpEODFjZ1B4OFZraTdKYnV1TW1GWXJXUGdZb3l0eWtVWjNleXFodDFqOUtic0RiVlpYZGIzanpDYWdFU3lZNEVFMng3WWp4M2dOd2N0b0V1UkNLS0RyZE5QM0hQRnRHOFJUdkJpWVN0VDVnaEJIaEhpekgyRHk2eFF0VzNQZDJTZWNpekw5YjJqekRDTXI3S2E1Y1JBV1pGd3Zxd0F0d1RUN3hldDc2OXk5RVJoNiIsIm5iZiI6IjIwMjMtMDEtMDFUMDA6MDA6MDBaIiwiZXhwIjoiMjAzMy0wMS0wMVQwMDowMDowMFoiLCJqdGkiOiI5YmNjOWFhYS0zYmRjLTQ0MTQtOTQ1MC03MzljMjk1Yzc1MmMiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvdjIiXSwiaWQiOiI5YmNjOWFhYS0zYmRjLTQ0MTQtOTQ1MC03MzljMjk1Yzc1MmMiLCJ0eXBlIjpbIlZlcmlmaWFibGVBdHRlc3RhdGlvbiIsIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiU3R1ZGVudElEIl0sImlzc3VlciI6ImRpZDplYnNpOnp2SFdYMzU5QTNDdmZKbkNZYUFpQWRlIiwidmFsaWRGcm9tIjoiMjAyMy0wMS0wMVQwMDowMDowMFoiLCJ2YWxpZFVudGlsIjoiMjAzMy0wMS0wMVQwMDowMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDprZXk6ejJkbXpEODFjZ1B4OFZraTdKYnV1TW1GWXJXUGdZb3l0eWtVWjNleXFodDFqOUtic0RiVlpYZGIzanpDYWdFU3lZNEVFMng3WWp4M2dOd2N0b0V1UkNLS0RyZE5QM0hQRnRHOFJUdkJpWVN0VDVnaEJIaEhpekgyRHk2eFF0VzNQZDJTZWNpekw5YjJqekRDTXI3S2E1Y1JBV1pGd3Zxd0F0d1RUN3hldDc2OXk5RVJoNiIsIl9zZCI6WyJ6U21JbVdIUEp6UTdSeDhaRzBJWWhVRjFPemo4ZjE3d0RLSkdoeFVrcmRVIiwiVDRSbkRtMWNsVkxDYXYyTXJzZWw2c05NejhwcUdDZU1ycnBfX1lyVl8tdyIsIlNGUVRqcjkxSWtQaTZiZXRRMEVZczVyZEoyVGJNZXNKR2Z0RjZoN2hqVEEiXSwic3R1ZGVudCI6dHJ1ZX0sImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2FwaS1waWxvdC5lYnNpLmV1L3RydXN0ZWQtc2NoZW1hcy1yZWdpc3RyeS92Mi9zY2hlbWFzLzB4MjMwMzllNjM1NmVhNmI3MDNjZTY3MmU3Y2ZhYzBiNDI3NjViMTUwZjYzZGY3OGUyYmQxOGFlNzg1Nzg3ZjZhMiIsInR5cGUiOiJGdWxsSnNvblNjaGVtYVZhbGlkYXRvcjIwMjEifSwiX3NkX2FsZyI6InNoYS0yNTYifX0.wC1jmebWUSVQYO18DluQhYUbTXDpvWuBSQv3apiiP3OdHlyPMRmFjX7jWPshjaWQkasuL_DBJ-IQufgDzT8z7Q~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImZhbWlseU5hbWUiLCAiQ2Fycm9sbCJd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImdpdmVuTmFtZSIsICJMZXdpcyJd~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImJpcnRoRGF0ZSIsICIxODMyLTAxLTI3Il0",
"c_nonce": "fGFF7UkhLa",
"c_nonce_expires_in": 86400
}

The Holder Wallet is responsible for the mapping between the Disclosures and the plaintext claim values, and for the selection for the presentation.

Presentation of the SD-JWT

The SD-JWT and the Holder-selected Disclosures are concatenated into a string, using the tilde ~ as a separator. The first block comprises the SD-JWT, while the remainder are the Disclosures.

The Combined Format for Presentation, which is always devoid of Holder Binding, is inserted as a single item into the vp_token's array of verifiableCredential. Please note that the final tilde must remain, despite the consistent removal of the Holder Binding.

Holder binding is covered in OpenID 4 Verifiable Presentation, thus the extra binding is not required.

Combined Format for Presentation
<SD-JWT>~<Disclosure 1>~<Disclosure 2>~...~<Disclosure M>~<optional Holder Binding JWT>
VC in SD-JWT Combined Format for Presentation
eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDplYnNpOnp2SFdYMzU5QTNDdm
ZKbkNZYUFpQWRlI0YwcjVPeXRfbGFodnZ6Nk1XbFlzM21jWU5LWmlpUWRVZnF2OHRzaEhOOXci
fQ.eyJpc3MiOiJkaWQ6ZWJzaTp6dkhXWDM1OUEzQ3ZmSm5DWWFBaUFkZSIsInN1YiI6ImRpZDp
rZXk6ejJkbXpEODFjZ1B4OFZraTdKYnV1TW1GWXJXUGdZb3l0eWtVWjNleXFodDFqOUtic0RiV
lpYZGIzanpDYWdFU3lZNEVFMng3WWp4M2dOd2N0b0V1UkNLS0RyZE5QM0hQRnRHOFJUdkJpWVN
0VDVnaEJIaEhpekgyRHk2eFF0VzNQZDJTZWNpekw5YjJqekRDTXI3S2E1Y1JBV1pGd3Zxd0F0d
1RUN3hldDc2OXk5RVJoNiIsIm5iZiI6IjIwMjMtMDEtMDFUMDA6MDA6MDBaIiwiZXhwIjoiMjA
zMy0wMS0wMVQwMDowMDowMFoiLCJqdGkiOiI5YmNjOWFhYS0zYmRjLTQ0MTQtOTQ1MC03MzljM
jk1Yzc1MmMiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGV
udGlhbHMvdjIiXSwiaWQiOiI5YmNjOWFhYS0zYmRjLTQ0MTQtOTQ1MC03MzljMjk1Yzc1MmMiL
CJ0eXBlIjpbIlZlcmlmaWFibGVBdHRlc3RhdGlvbiIsIlZlcmlmaWFibGVDcmVkZW50aWFsIiw
iU3R1ZGVudElEIl0sImlzc3VlciI6ImRpZDplYnNpOnp2SFdYMzU5QTNDdmZKbkNZYUFpQWRlI
iwidmFsaWRGcm9tIjoiMjAyMy0wMS0wMVQwMDowMDowMFoiLCJ2YWxpZFVudGlsIjoiMjAzMy0
wMS0wMVQwMDowMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDprZXk6ejJkb
XpEODFjZ1B4OFZraTdKYnV1TW1GWXJXUGdZb3l0eWtVWjNleXFodDFqOUtic0RiVlpYZGIzanp
DYWdFU3lZNEVFMng3WWp4M2dOd2N0b0V1UkNLS0RyZE5QM0hQRnRHOFJUdkJpWVN0VDVnaEJIa
EhpekgyRHk2eFF0VzNQZDJTZWNpekw5YjJqekRDTXI3S2E1Y1JBV1pGd3Zxd0F0d1RUN3hldDc
2OXk5RVJoNiIsIl9zZCI6WyJ6U21JbVdIUEp6UTdSeDhaRzBJWWhVRjFPemo4ZjE3d0RLSkdoe
FVrcmRVIiwiVDRSbkRtMWNsVkxDYXYyTXJzZWw2c05NejhwcUdDZU1ycnBfX1lyVl8tdyIsIlN
GUVRqcjkxSWtQaTZiZXRRMEVZczVyZEoyVGJNZXNKR2Z0RjZoN2hqVEEiXSwic3R1ZGVudCI6d
HJ1ZX0sImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2FwaS1waWxvdC5lYnNpLmV
1L3RydXN0ZWQtc2NoZW1hcy1yZWdpc3RyeS92Mi9zY2hlbWFzLzB4MjMwMzllNjM1NmVhNmI3M
DNjZTY3MmU3Y2ZhYzBiNDI3NjViMTUwZjYzZGY3OGUyYmQxOGFlNzg1Nzg3ZjZhMiIsInR5cGU
iOiJGdWxsSnNvblNjaGVtYVZhbGlkYXRvcjIwMjEifSwiX3NkX2FsZyI6InNoYS0yNTYifX0.wC
1jmebWUSVQYO18DluQhYUbTXDpvWuBSQv3apiiP3OdHlyPMRmFjX7jWPshjaWQkasuL_DBJ-IQu
fgDzT8z7Q~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImZhbWlseU5hbWUiLCAiQ2Fycm9s
bCJd~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImdpdmVuTmFtZSIsICJMZXdpcyJd~WyI2S
Wo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImJpcnRoRGF0ZSIsICIxODMyLTAxLTI3Il0~
Extra tilde

Please note the final tilde is mandatory

Security considerations

The security of the SD-JWT depends on the security of the (pseudo) random number generator. To prevent insecure implementations, refer to the following:

For further information on insecure randomness, refer to the following:

The Random Number Generation - Examples guideline contains short code snippets for secure random number generation.

Privacy considerations

If the SD-JWT contains personal information and is transmitted via URL (e.g., when the response is sent via a redirect), the SD-JWT must be encrypted.