| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
SDJWT.Holder
Description
Convenience module for SD-JWT holders.
This module provides everything needed to receive SD-JWTs and create presentations. It exports a focused API for the holder role, excluding modules that holders don't need (like Issuance and Verification).
Usage
For holders, import this module:
import SDJWT.Holder
This gives you access to:
- Core data types (HashAlgorithm, SDJWT, SDJWTPresentation, etc.)
- Serialization functions (
deserializeSDJWT,serializePresentation) - Presentation functions (
selectDisclosuresByNames) - Key binding functions (
addKeyBindingToPresentation)
Creating Presentations
The main workflow for holders is:
-- 1. Deserialize SD-JWT received from issuer
case deserializeSDJWT sdjwtText of
Right sdjwt -> do
-- 2. Select which disclosures to include
-- Examples of different selection patterns:
-- Top-level claims: ["given_name", "email"]
-- Nested object claims: ["address/street_address", "address/locality"]
-- Array elements: ["nationalities/0", "nationalities/2"]
-- Mixed paths: ["address/street_address", "nationalities/1"]
case selectDisclosuresByNames sdjwt ["given_name", "email"] of
Right presentation -> do
-- 3. Optionally add key binding for proof of possession
holderPrivateKeyJWK <- loadPrivateKeyJWK
let audience = "verifier.example.com"
let nonce = "random-nonce-12345"
let issuedAt = 1683000000 :: Int64
-- Optional: Add standard JWT claims like exp (expiration time) to KB-JWT
-- These claims will be automatically validated during verification if present
let expirationTime = issuedAt + 3600 -- 1 hour from issued time
let optionalClaims = Aeson.object [("exp", Aeson.Number (fromIntegral expirationTime))]
kbResult <- addKeyBindingToPresentation SHA256 holderPrivateKeyJWK audience nonce issuedAt presentation optionalClaims
case kbResult of
Right presentationWithKB -> do
-- 4. Serialize presentation to send to verifier
let serialized = serializePresentation presentationWithKB
-- Send serialized presentation...
Left err -> -- Handle error
Left err -> -- Handle error
Left err -> -- Handle error
Optional Claims in KB-JWT
The optionalClaims parameter allows adding standard JWT claims (RFC 7519) to the KB-JWT,
such as exp (expiration time) or nbf (not before). These claims will be automatically
validated during verification if present. Pass Aeson.object [] for no additional claims.
Note: RFC 9901 Section 4.3 states that additional claims SHOULD be avoided unless there is
a compelling reason, as they may harm interoperability.
For advanced use cases (e.g., creating presentations manually or computing
SD hash separately), import Presentation or
KeyBinding to access additional low-level functions.
Synopsis
- module SDJWT.Internal.Types
- deserializeSDJWT :: Text -> Either SDJWTError SDJWT
- serializePresentation :: SDJWTPresentation -> Text
- selectDisclosuresByNames :: SDJWT -> [Text] -> Either SDJWTError SDJWTPresentation
- addKeyBindingToPresentation :: JWKLike jwk => HashAlgorithm -> jwk -> Text -> Text -> Int64 -> SDJWTPresentation -> Object -> IO (Either SDJWTError SDJWTPresentation)
Core Types
module SDJWT.Internal.Types
Serialization
deserializeSDJWT :: Text -> Either SDJWTError SDJWT Source #
Deserialize SD-JWT from tilde-separated format.
Parses a tilde-separated string into an SDJWT structure.
Returns an error if the format is invalid or if a Key Binding JWT
is present (use deserializePresentation for SD-JWT+KB).
Presentation
Functions for creating SD-JWT presentations with selected disclosures.
selectDisclosuresByNames Source #
Arguments
| :: SDJWT | |
| -> [Text] | Claim names to include in presentation (supports JSON Pointer syntax for nested paths, including array indices) |
| -> Either SDJWTError SDJWTPresentation |
Select disclosures from an SD-JWT based on claim names.
This function:
- Decodes all disclosures from the SD-JWT
- Filters disclosures to include only those matching the provided claim names
- Handles recursive disclosures (Section 6.3): when selecting nested claims, automatically includes parent disclosures if they are recursively disclosable
- Validates disclosure dependencies (ensures all required parent disclosures are present)
- Returns a presentation with the selected disclosures
Note: This function validates that the selected disclosures exist in the SD-JWT. Supports JSON Pointer syntax for nested paths:
- Object properties:
["address/street_address", "address/locality"] - Array elements:
["nationalities/0", "nationalities/2"] - Mixed paths:
["address/street_address", "nationalities/1"] - Nested arrays:
["nested_array/0/0", "nested_array/1/1"]
Paths with numeric segments (e.g., ["x/22"]) are resolved by checking the
actual claim type: if x is an array, it refers to index 22; if x is an
object, it refers to property "22".
Key Binding
Functions for adding key binding to presentations (SD-JWT+KB).
addKeyBindingToPresentation Source #
Arguments
| :: JWKLike jwk | |
| => HashAlgorithm | Hash algorithm for computing sd_hash |
| -> jwk | Holder private key (Text or jose JWK object) |
| -> Text | Audience claim (verifier identifier) |
| -> Text | Nonce provided by verifier |
| -> Int64 | Issued at timestamp (Unix epoch seconds) |
| -> SDJWTPresentation | The SD-JWT presentation to bind |
| -> Object | Optional additional claims (e.g., exp, nbf). Standard JWT claims will be validated during verification if present. Pass |
| -> IO (Either SDJWTError SDJWTPresentation) |
Add key binding to a presentation.
Creates a KB-JWT and adds it to the presentation, converting it to SD-JWT+KB format.
The KB-JWT includes required claims (aud, nonce, iat, sd_hash) plus any optional
claims provided. Standard JWT claims like exp (expiration time) and nbf (not before)
will be automatically validated during verification if present.
Note: RFC 9901 Section 4.3 states that additional claims in optionalClaims SHOULD be avoided
unless there is a compelling reason, as they may harm interoperability.