transaction_data: interop report + offer of a worked KB-JWT example (multi-credential credential_ids binding)
Nobody has claimed this yet.
- Dominant language
- Shell
- Stars
- 112
- Forks
- 38
- Avg merge
- 12d 19h
- Merged PRs (30d)
- 4
Description
Context. We implemented OpenID4VP 1.0 transaction_data end-to-end for a research prototype (per-action, human-in-the-loop authorization of a delegated action): an SD-JWT VC credential, a payment-style transaction_data entry, presented from the EUDI reference wallet (a commit-pinned research build) to a conformant verifier. It works end-to-end — request accepted, per-action user confirmation, and the verifier returns 200 once transaction_data_hashes is bound into the holder KB-JWT. Sharing two small things back to the WG. (This is a spec-side note to the DCP WG; distinct from the EUDI wallet-app implementation gap we filed separately at eu-digital-identity-wallet/eudi-lib-android-wallet-core#411.)
1. A worked KB-JWT example the spec could carry (non-normative)
The single most useful missing artefact when building this was one concrete, end-to-end example that walks from the transaction_data array value, through the hash, into the holder KB-JWT. A conformant verifier rejected our first attempts until the KB-JWT carried both transaction_data_hashes and transaction_data_hashes_alg: sha-256 (verifier error: 'transaction_data_hashes_alg' must be 'sha-256'). Once bound, the same verifier accepted.
A fully worked example — the hash below is real and recomputable:
Transaction Data object (before encoding):
{"type":"payment","credential_ids":["payment_card"],"transaction_data_hashes_alg":["sha-256"],"payee":"ACME GmbH","amount":"120.00","currency":"EUR"}
Value as it appears in the transaction_data array (base64url, no padding):
eyJ0eXBlIjoicGF5bWVudCIsImNyZWRlbnRpYWxfaWRzIjpbInBheW1lbnRfY2FyZCJdLCJ0cmFuc2FjdGlvbl9kYXRhX2hhc2hlc19hbGciOlsic2hhLTI1NiJdLCJwYXllZSI6IkFDTUUgR21iSCIsImFtb3VudCI6IjEyMC4wMCIsImN1cnJlbmN5IjoiRVVSIn0
Hash entry = base64url( SHA-256( the base64url string above ) ), no padding (cf. eu-digital-identity-wallet/eudi-app-android-wallet-ui#418):
Xzo6puFg3O2W4vzj3HgQKEROrFEEa8lwkQHFAkM5ff8
Holder KB-JWT payload (SD-JWT VC presentation), hash bound in:
{
"nonce": "<verifier-nonce>",
"aud": "x509_hash:<verifier-cert-thumbprint>",
"iat": "<unix-time>",
"sd_hash": "<hash-of-issued-sd-jwt>",
"transaction_data_hashes": ["Xzo6puFg3O2W4vzj3HgQKEROrFEEa8lwkQHFAkM5ff8"],
"transaction_data_hashes_alg": "sha-256"
}
Reviewer self-check (reproduces the hash entry):
printf %s '<the base64url string>' | openssl dgst -sha256 -binary | basenc --base64url | tr -d '='
If a short non-normative worked example like this would be welcome in the Transaction Data section, I'm happy to open a PR — implementers seem to hit the same "which JWT, which claims, what is the hash input" questions we did.
2. One binding detail to confirm — multi-credential credential_ids
For a single presented credential the binding is unambiguous. For a presentation of multiple credentials where different transaction_data entries carry different credential_ids, we read the spec as: each presented credential's KB-JWT should carry hashes for only those transaction_data objects whose credential_ids reference that credential (per-credential filtering), not the full set. Is that the intended behaviour? We could not find a reference implementation exercising the multi-credential case to check against, so we'd like to confirm the reading before contributing test vectors for it.
Offer
We have a working wallet + verifier setup and can contribute (a) the non-normative KB-JWT example above and (b) interop test vectors for both the single- and multi-credential transaction_data cases, if useful.
Thanks — glad to be contributing.
— Anton Sokolov, Tyche Institute (Tallinn); contribution agreements signed with the OpenID Foundation.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read the OpenID4VP Transaction Data section and reproduce the supplied hash with the openssl command. Confirm the intended per-credential filtering for multi-credential credential_ids, then prepare the non-normative KB-JWT example and single- and multi-credential interop test vectors; done means the WG accepts the interpretation and proposed materials.
Written by the indexing model from the issue text.
Assessment
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100