Skip to content

Support Multiple Credentials per Query and Multiple Queries per Credential in Credential Response - #77

Open
GarethCOliver wants to merge 18 commits into
openid:jogu/format-annexesfrom
GarethCOliver:gco/69-credential-refs
Open

GarethCOliver wants to merge 18 commits into
openid:jogu/format-annexesfrom
GarethCOliver:gco/69-credential-refs

Conversation

@GarethCOliver

Copy link
Copy Markdown
Collaborator

#69
#70

Stacked on #57, DO NOT MERGE until 57 is merged.

Updates Credential Response to support CredentialItem to be associated with multiple CredentialQueries (to avoid duplication) and to support multiple CredentialItems for the same CredentialQuery.

As part of this change rename 'CredentialRef' to 'QueryRef' to more accurately reflect that it is refering to a query, not a Credential.

jogu and others added 18 commits September 7, 2026 16:14
Structure agreed at the 2026-08-31 meeting: one normative annex per
credential format, with a generic extension point so other documents can
define further formats.

- New "Credential Formats" clause: the protocol is format agnostic, a
  "credential format definition" shall specify the ten items from openid#36,
  and the main body no longer names any format or annex.
- New annexes for ISO mdoc and SD-JWT VC with identical headings in the
  order of the openid#21/openid#22 checklists; existing format text moves there.
- format_extensions and CredentialItem.data become CDDL sockets
  ($formatExtensions, $CredentialData); the undefined ZkDocument /
  zkFormatExtensions alternatives go away.
- ISO/IEC 18013-5, RFC 9901 and draft-ietf-oauth-sd-jwt-vc added to
  Normative references.
- SD-JWT VC format identifier is now dc+sd-jwt; vc+sd-jwt as a mimetype
  means a w3c vc encoded in sd-jwt; vp uses dc+sd-jwt.

New text added by this PR: case-sensitive credential_type matching;
mdoc elements may be issuer- or device-signed; mdoc issuer identifiers
match the AKI of a certificate in the IssuerAuth x5chain; KB-JWT may be
omitted only when support_no_cryptographic_binding is true; for mdocs
that flag maps to nonKeyBoundSupported from the 18013-5 second edition
DIS text (openid#56).

Left "To be completed": value matching (openid#9), transaction data (openid#4),
SessionTranscript derivation and KB-JWT nonce/aud (openid#10), non-X.509
issuer identification for SD-JWT VC.

Raised separately: array elements in path (openid#52), vct inheritance (openid#53),
mdoc alg value names and matching rule (openid#54)

There's now no mention of ZKP responses - that's already recorded in openid#17

closes openid#21, openid#22, openid#36
The SD-JWT VC annex only said the x509_ref values are compared against
the x5c chain, without saying what outcome satisfies the request. Use
the same rule as the mdoc annex.
The previous text let the wallet drop the KB-JWT from a key-bound
SD-JWT VC whenever support_no_cryptographic_binding was true. That is a
downgrade the mdoc annex does not permit (a key-bound mdoc always
carries DeviceSigned) and OpenID4VP does not permit either. Tie the
permission to the absence of cnf, matching the mdoc rule.
IssuerSignedItems is not a structure in ISO/IEC 18013-5; the standard
has IssuerSignedItem entries under IssuerNameSpaces and
DeviceSignedItems under DeviceNameSpaces.
The mdoc annex introduction presented its list as the structures the
annex refers to, but omitted IssuerAuth, the MSO, KeyAuthorizations,
IssuerNameSpaces, DeviceNameSpaces and DeviceSignedItems, all used
later in the annex. The SD-JWT VC annex uses the x5c header, which
comes from RFC 7515 rather than the SD-JWT documents.
The annexes say format carries the same value as credential_format, but
the main-body table did not connect the field to the extension point.
… too

The note that an mDL is always key-bound also relies on the unpublished
second edition text, so move the editor's note ahead of it and say it
covers both.
Co-authored-by: Oliver Terbu <o.terbu@gmail.com>
The SD-JWT VC annex cites it for the x5c JOSE header.

Addresses Oliver's comment in
openid#57 (comment)
The mdoc annex introduction says Document is one of the structures
defined in ISO/IEC 18013-5, where it is a CBOR map, but the annex CDDL
then declared Document = bstr. Name our type MdocData and define it as
bstr .cbor Document so the ISO name keeps its ISO meaning and the wire
format (a byte string holding the encoded Document) is unchanged.

Addresses Oliver's review comment on openid#57.
Each annex said in prose that its type extends the $CredentialData or
$formatExtensions socket, immediately before the CDDL line that says the
same thing. The Credential Formats clause already states the general
rule once, so remove the four repetitions.
Co-authored-by: Martijn Haring <62745275+martijnharing@users.noreply.github.com>
Co-authored-by: Gareth Oliver <gco@google.com>
Co-authored-by: Oliver Terbu <o.terbu@gmail.com>
Co-authored-by: Joseph Heenan <joseph@heenan.me.uk>
Martijn and Gareth both asked for the sentence to go: DCHP should not
define itself in terms of the ISO/IEC 18013-5 request structure it may
replace. DocRequestInfo is no longer referred to, so it leaves the list
of borrowed structures too.
The mDL key-binding note the openid#56 editor's note pointed to has been
removed, and item 10 of the format definition requirements lost its
full stop when the review suggestion was applied.
(also remove a stray DOS line ending the github web interface added)

Co-authored-by: Oliver Terbu <o.terbu@gmail.com>
A suggestion applied in the GitHub web UI converted the whole draft to
CRLF, which showed every line as changed and left review comments
detached from their lines. I don't know if the web interface pays
attentions to .gitattributes but I don't think it can make things
worse.
…to QueryRef

Restructure the response Envelope so that `credentials` is an array of
CredentialItems, each of which declares the CredentialQueries it satisfies
via a new `query_refs` field (option 2 from the discussion in openid#69 / openid#70).
This allows a single credential to satisfy several queries without being
duplicated, and allows several credentials to satisfy a single query when
`allow_multiple` is set.

Rename `CredentialRef` to `QueryRef` throughout, since it identifies a
CredentialQuery in the request rather than a credential.

closes openid#69, closes openid#70
minor edits
@GarethCOliver GarethCOliver changed the title Gco/69 credential refs Support Multiple Credentials per Query and Multiple Queries per Credential in Credential Response Oct 15, 2026

The `QueryRef` values used in the response are the **same integers** used as keys in the request's `CredentialQueries` map, so the verifier can directly correlate a returned credential to the queries that requested it without any additional mapping.

A single `CredentialItem` may satisfy more than one `CredentialQuery` (e.g. two queries for different elements of the same credential, in different scenarios). In that case the credential is included in the pool once, and all of the satisfied `QueryRef`s are listed in its `query_refs`, rather than the credential being duplicated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed on the WG call today - Martijn suggested this is an optimisation and doesn't need to be mandatory:

Suggested change
A single `CredentialItem` may satisfy more than one `CredentialQuery` (e.g. two queries for different elements of the same credential, in different scenarios). In that case the credential is included in the pool once, and all of the satisfied `QueryRef`s are listed in its `query_refs`, rather than the credential being duplicated.
A single `CredentialItem` may satisfy more than one `CredentialQuery` (e.g. two queries for different elements of the same credential, in different scenarios). In that case the credential should be included in the pool once, and all of the satisfied `QueryRef`s are listed in its `query_refs`, rather than the credential being duplicated.

@jogu
jogu force-pushed the jogu/format-annexes branch from 4d461ea to 2b6b0f3 Compare October 22, 2026 10:24

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants