DCQL forklart: slik ber en verifikator en lommebok om nøyaktig det den trenger
Digital Credentials Query Language, DCQL, er JSON-forespørselsformatet som OpenID4VP bruker i en presentasjonsforespørsel. Den lar en tillitspart beskrive hvilke bevis, og hvilke opplysninger i dem, den vil se, på en måte som enhver kompatibel lommebok kan tolke uten en skreddersydd integrasjon.
Problemet DCQL løser
En bedriftslommebok kan inneholde bevis i flere formater: en foretaksregistrering som SD-JWT VC, en fagkvalifikasjon kodet som mdoc og et W3C verifiable credential fra et tidligere pilotprosjekt. En verifikator som bare trenger å bekrefte et registreringsnummer og et juridisk navn, har ingen portabel måte å be om akkurat det på tvers av formater, uten enten å godta hele beviset eller håndkode en egen forespørsel per format og per lommebokleverandør.
DCQL tetter dette gapet på forespørselssiden. Det er ett enkelt JSON-objekt, innebygd i OpenID4VP-autorisasjonsforespørselen, som navngir én eller flere bevisforespørsler, hver knyttet til et format og et sett med opplysningsstier. Lommeboken evaluerer forespørselen mot lagrede bevis, finner ut hvilke som samsvarer, og ber først da innehaveren om å godkjenne utlevering av akkurat de opplysningene. Verifikatoren får en forutsigbar struktur å tolke, uansett hvilken lommebok innehaveren brukte.
1. Verifikator
Sender en OpenID4VP-forespørsel med en dcql_query
2. Lommebok
Sammenligner forespørselen med lagrede bevis
3. Innehaver
Godkjenner utlevering av bare de forespurte opplysningene
4. Verifikator
Mottar én presentasjon per id i bevisforespørselen
Oppbygningen av en DCQL-forespørsel
En DCQL-forespørsel er ett JSON-objekt med en credentials-array og eventuelt en credential_sets-array. Hver oppføring i credentials er en bevisforespørsel. Felt merket M er obligatoriske i den forespørselen.
dcql_query
credentials[ ]
Én bevisforespørsel per bevis du trenger
id + format
Hvilket bevis, i hvilket format
meta
Typefilter, for eksempel vct_values
claims[ ]
Stier til opplysninger som skal deles
claim_sets[ ]
Godtatte kombinasjoner av opplysninger
credential_sets[ ]
Valgfritt: hvilke kombinasjoner av bevisforespørsler som oppfyller forespørselen
| Felt | Type | Obligatorisk |
|---|---|---|
| id | string | M |
| format | enum: dc+sd-jwt | mso_mdoc | jwt_vc_json | ldp_vc | M |
| meta | objekt, formen avhenger av format | |
| claims | array av opplysningsforespørsler | |
| claim_sets | array av arrayer med opplysnings-id-er | |
| trusted_authorities | array av objekter med en type og verdier |
Hver oppføring i claims er selv et objekt: en id som brukes til å referere til den fra claim_sets, en path, en array som angir hvor opplysningen ligger i beviset (for eksempel ["legal_name"] for en SD-JWT-opplysning på toppnivå eller ["org", "registration_number"] for en nestet opplysning), og eventuelt values, en liste med verdier opplysningen må samsvare med.
Eksempel: kontroll av foretaksregistrering
Foretaksregistrering
dc+sd-jwtVerifikatoren sier: dette vil jeg motta
- ✓ Registreringsnummerreg_nopath: ["registration_number"]
- ✓ Juridisk navnlegal_namepath: ["legal_name"]
- ✓ Registreringslandreg_countrypath: ["registration_country"]
{
"credentials": [
{
"id": "company_registration",
"format": "dc+sd-jwt",
"meta": {
"vct_values": ["urn:eudi:business:company-registration:1"]
},
"claims": [
{ "id": "reg_no", "path": ["registration_number"] },
{ "id": "legal_name", "path": ["legal_name"] },
{ "id": "reg_country", "path": ["registration_country"] }
]
}
]
}Eksempel på svar fra lommeboken
Lommeboken svarer med et vp_token-objekt der nøklene er id-ene til bevisforespørslene. Hver verdi er en array av presentasjoner. For dc+sd-jwt består en presentasjon av den utstedersignerte JWT-en, én disclosure per utlevert opplysning og en key binding JWT som knytter den til nonce og klient for denne forespørselen.
Hva lommeboken sender
{
"vp_token": {
"company_registration": [
"<issuer-signed JWT>~<disclosure: registration_number>~<disclosure: legal_name>~<disclosure: registration_country>~<key binding JWT>"
]
}
}Opplysninger verifikatoren ser etter validering
{
"vct": "urn:eudi:business:company-registration:1",
"registration_number": "12345678",
"legal_name": "Example Logistics B.V.",
"registration_country": "NL"
}Be om et reservealternativ: claim_sets
claim_sets lister grupper av opplysnings-id-er i prioritert rekkefølge. Lommeboken returnerer den første gruppen den kan oppfylle fullt ut med det innehaveren faktisk har, slik at verifikatoren slipper å sende to separate forespørsler for et presist tilfelle og et reservetilfelle.
Eksempel: registreringsnummer, eller bare juridisk navn som reserve
1. Foretrukket
Returneres når beviset inneholder begge opplysningene
2. Reserve
Returneres bare når det første settet ikke kan oppfylles
{
"credentials": [
{
"id": "company_registration",
"format": "dc+sd-jwt",
"meta": { "vct_values": ["urn:eudi:business:company-registration:1"] },
"claims": [
{ "id": "reg_no", "path": ["registration_number"] },
{ "id": "legal_name", "path": ["legal_name"] }
],
"claim_sets": [
["reg_no", "legal_name"],
["legal_name"]
]
}
]
}Her foretrekker verifikatoren registreringsnummer og juridisk navn, men godtar det juridiske navnet alene hvis innehaverens bevis ikke inneholder en opplysning om registreringsnummer.
Eksempel på svar: reservealternativet ble brukt
Hva lommeboken sender
{
"vp_token": {
"company_registration": [
"<issuer-signed JWT>~<disclosure: legal_name>~<key binding JWT>"
]
}
}Opplysninger verifikatoren ser etter validering
{
"vct": "urn:eudi:business:company-registration:1",
"legal_name": "Example Logistics B.V."
}Innehaverens bevis har ikke noe registreringsnummer, så lommeboken oppfylte det andre opplysningssettet og utleverte én enkelt disclosure. Svaret sier ikke hvilket sett som ble brukt: verifikatoren leser det ut fra opplysningene den mottar.
Kombinere bevis: credential_sets
credential_sets virker ett nivå over claim_sets. Hver oppføring lister options, der hvert alternativ er en gruppe id-er for bevisforespørsler. Lommeboken må oppfylle ett alternativ i hver påkrevde oppføring, noe som gir verifikatoren OG- og ELLER-logikk på tvers av bevis i én enkelt forespørsel.
Påkrevd
Foretaksregistrering
Én av
MVA-registrering
Én av
Bekreftelse av bankkonto
"credential_sets": [
{ "options": [["company_registration"]] },
{ "options": [["vat_registration"], ["bank_account"]] }
]Eksempel på svar: registrering pluss bankkonto
Hva lommeboken sender
{
"vp_token": {
"company_registration": [
"<issuer-signed JWT>~<disclosures>~<key binding JWT>"
],
"bank_account": [
"<issuer-signed JWT>~<disclosures>~<key binding JWT>"
]
}
}Opplysninger verifikatoren ser etter validering
{
"company_registration": {
"vct": "urn:eudi:business:company-registration:1",
"registration_number": "12345678",
"legal_name": "Example Logistics B.V."
},
"bank_account": {
"vct": "urn:eudi:business:bank-account:1",
"iban": "NL91ABNA0417164300",
"account_holder": "Example Logistics B.V."
}
}Innehaveren har ikke noe MVA-registreringsbevis, så lommeboken valgte det andre alternativet i det andre settet. Forespørsels-id-er som ikke ble brukt, her vat_registration, er rett og slett fraværende i vp_token.
Bare pålitelige utstedere: trusted_authorities
trusted_authorities begrenser en bevisforespørsel til bevis der utstederen er støttet av en autoritet verifikatoren stoler på. Hver oppføring har en type og en liste med verdier: aki for en authority key identifier, etsi_tl for en ETSI-tillitsliste eller openid_federation for et tillitsanker i en føderasjon. Lommeboken tilbyr bare bevis som samsvarer.
Eksempel: en registrering fra en oppført utsteder
Verifikatoren sier: bare fra utstedere på denne tillitslisten
https://ec.europa.eu/tools/lotl/eu-lotl.xml
Registreringsbevis fra en oppført utsteder
utstederen står på tillitslisten
✓ Samsvarer med forespørselen
Registreringsbevis fra en ikke-oppført utsteder
utstederen står ikke på tillitslisten
✗ Samsvarer ikke, tilbys ikke innehaveren
{
"credentials": [
{
"id": "company_registration",
"format": "dc+sd-jwt",
"meta": { "vct_values": ["urn:eudi:business:company-registration:1"] },
"trusted_authorities": [
{
"type": "etsi_tl",
"values": ["https://ec.europa.eu/tools/lotl/eu-lotl.xml"]
}
],
"claims": [
{ "id": "reg_no", "path": ["registration_number"] },
{ "id": "legal_name", "path": ["legal_name"] }
]
}
]
}Eksempel på svar: bare beviset fra den oppførte utstederen
Hva lommeboken sender
{
"vp_token": {
"company_registration": [
"<issuer-signed JWT>~<disclosure: registration_number>~<disclosure: legal_name>~<key binding JWT>"
]
}
}Opplysninger verifikatoren ser etter validering
{
"vct": "urn:eudi:business:company-registration:1",
"registration_number": "12345678",
"legal_name": "Example Logistics B.V."
}Innehaveren hadde også et registreringsbevis fra en ikke-oppført utsteder, men lommeboken tilbød det ikke. trusted_authorities er et filter for lommeboken, ikke en garanti: verifikatoren kontrollerer likevel selv utstederen mot tillitslisten når den validerer presentasjonen.
Samsvar med en verdi: claims.values
En opplysningsforespørsel kan inneholde values, en liste med strenger, heltall eller boolske verdier. Lommeboken returnerer bare opplysningen når typen og verdien samsvarer nøyaktig med én av dem, slik at en verifikator kan kontrollere en betingelse uten først å be om noe annet.
Eksempel: bare foretak registrert i Nederland eller Belgia
Verifikatoren sier: bare et foretak registrert i ett av disse landene
Nederlandsk foretak
registration_country: "NL"
✓ Samsvarer med forespørselen
Tysk foretak
registration_country: "DE"
✗ Samsvarer ikke, tilbys ikke innehaveren
{
"credentials": [
{
"id": "company_registration",
"format": "dc+sd-jwt",
"meta": { "vct_values": ["urn:eudi:business:company-registration:1"] },
"claims": [
{ "id": "legal_name", "path": ["legal_name"] },
{
"id": "reg_country",
"path": ["registration_country"],
"values": ["NL", "BE"]
}
]
}
]
}Eksempel på svar: et nederlandsk foretak
Hva lommeboken sender
{
"vp_token": {
"company_registration": [
"<issuer-signed JWT>~<disclosure: legal_name>~<disclosure: registration_country>~<key binding JWT>"
]
}
}Opplysninger verifikatoren ser etter validering
{
"vct": "urn:eudi:business:company-registration:1",
"legal_name": "Example Logistics B.V.",
"registration_country": "NL"
}Beviset til et tysk foretak har registration_country "DE", så det oppfyller ikke forespørselen, og lommeboken har ingenting å returnere for det. Verifikatoren bør likevel kontrollere verdien i de validerte opplysningene i stedet for å stole på lommebokens filtrering.
Formatspesifikke begrensninger i meta
SD-JWT VC: vct_values
For dc+sd-jwt lister meta.vct_values de bevistype-identifikatorene verifikatoren godtar. En forespørsel samsvarer bare med et lagret bevis der vct er én av de oppførte verdiene, så en verifikator som bare stoler på én utsteders type registreringsbevis, oppgir nøyaktig den identifikatoren.
mso_mdoc: doctype_value og navnerom
For mso_mdoc fastsetter meta.doctype_value DocType etter ISO 18013-5, og hver opplysningssti starter med mdoc-navnerommet opplysningen hører til, i stedet for et enkelt feltnavn, fordi mdoc grupperer opplysninger etter navnerom i stedet for i et flatt objekt.
Hvor DCQL står i dag
- DCQL er definert i selve OpenID4VP-spesifikasjonen, ikke som et eget dokument, og har vært en del av utkastet siden mekanismen ble innført for å erstatte en tidligere avhengighet av DIF Presentation Exchange for OpenID4VP-forespørsler.
- EUDI Wallet Architecture and Reference Framework angir OpenID4VP som presentasjonsprotokoll og dermed DCQL som forespørselsmekanismen tillitsparter og lommebøker i økosystemet forventes å støtte.
- Referanseimplementasjoner av lommebøker og verifikatorer i EUDI Wallet Reference Implementation-programmet har samlet seg om DCQL. Nye integrasjoner av bedriftslommebøker som bygges mot OpenID4VP i dag, bør derfor forutsette DCQL og ikke Presentation Exchange som forespørselsformat for presentasjonsforespørsler.
Relaterte begreper
Ofte stilte spørsmål
Hvordan skiller DCQL seg fra DIF Presentation Exchange?
Begge beskriver hva en verifikator ønsker fra en lommebok, men DCQL er avgrenset til OpenID4VP og definert direkte i den spesifikasjonen, mens Presentation Exchange er en egen DIF-spesifikasjon som også dekker andre protokoller. DCQL er bevisst mindre: den har ingen input descriptor-grupper eller submission requirements, og den uttrykker formatspesifikke begrensninger, som en mdoc-doctype eller en SD-JWT VC-type, direkte i et forespørselsobjekt i stedet for gjennom et generisk JSON Schema-filter. EUDI Wallet-økosystemet har standardisert på DCQL for OpenID4VP-presentasjoner.
Kan én DCQL-forespørsel be om mer enn ett bevis?
Ja. credentials-arrayen kan liste flere bevisforespørsler, hver med sin egen id. En lommebok som har treff for hver oppføring, returnerer én presentasjon per oppføring. Det valgfrie credential_sets-objektet kan i tillegg kreve bestemte kombinasjoner, for eksempel godta enten et foretaksregistreringsbevis alene eller et foretaksregistreringsbevis sammen med en UBO-erklæring, uten å spørre innehaveren to ganger.
Hvilket problem løser claim_sets innenfor én enkelt bevisforespørsel?
Et bevis inneholder ikke alltid alle opplysningene en verifikator skulle ønske. claim_sets lister alternative grupper av opplysnings-id-er som hver for seg ville oppfylle forespørselen, sortert fra mest til minst foretrukket. Lommeboken velger den første gruppen den kan oppfylle fullt ut med opplysningene innehaveren faktisk har. Slik kan en verifikator be om et presist ID-nummer der det finnes, og falle tilbake på en grovere kontroll, som en over-18-indikator, uten å sende to separate forespørsler.
Er DCQL spesifikt for EUDI Wallet?
Nei. DCQL er en del av kjernespesifikasjonen til OpenID4VP, og enhver OpenID4VP-implementasjon kan bruke den. EUDI Wallet-økosystemet er en fremtredende bruker: Architecture and Reference Framework angir OpenID4VP med DCQL som presentasjonsmekanismen tillitsparter må støtte. Derfor er den særlig viktig for lommebøker og verifikatorer som bygges for det europeiske markedet.
Utfører DCQL selv selektiv deling?
Nei. DCQL beskriver bare hva det blir bedt om. Om lommeboken kan avsløre akkurat de opplysningene og ingenting annet, avhenger av bevisformatet: både SD-JWT VC og ISO mdoc støtter deling av et utvalg av opplysningene, så en DCQL claims-array bygger på den støtten. DCQL mot et format uten selektiv deling ville fortsatt fungere, men innehaveren måtte da utlevere hele beviset selv for en forespørsel om én enkelt opplysning.
Kilder
Denne siden er kun til informasjon og utgjør ikke juridisk rådgivning. For autoritativ veiledning, kontakt OpenID Foundation og Europakommisjonen direkte.