Spring til hovedindhold

DCQL forklaret: sådan beder en verifier en wallet om præcis det, den har brug for

Digital Credentials Query Language, DCQL, er det JSON-forespørgselsformat, som OpenID4VP bruger i en præsentationsanmodning. Det lader en relying party beskrive, hvilke credentials og hvilke claims i dem den vil se, på en måde som enhver kompatibel wallet kan fortolke uden en skræddersyet integration.

Problemet, DCQL løser

En business wallet kan indeholde credentials i flere formater: en virksomhedsregistrering som SD-JWT VC, en mdoc-kodet faglig kvalifikation, en W3C verifiable credential fra et tidligere pilotprojekt. En verifier, der kun skal bekræfte et registreringsnummer og et juridisk navn, har ingen portabel måde at bede om præcis det på tværs af formater, uden enten at acceptere hele credentialen eller håndkode en separat anmodning pr. format og pr. wallet-leverandør.

DCQL løser anmodningssiden af det problem. Det er et enkelt JSON-objekt, indlejret i OpenID4VP-autorisationsanmodningen, som angiver en eller flere credential queries, hver knyttet til et format og et sæt claim-stier. En wallet evaluerer forespørgslen mod sine gemte credentials, finder ud af hvilke der matcher, og beder først derefter indehaveren om at godkende udleveringen af netop de claims. Verifieren får en forudsigelig struktur at fortolke, uanset hvilken wallet indehaveren har brugt.

1. Verifier

Sender en OpenID4VP-anmodning med en dcql_query

2. Wallet

Matcher forespørgslen mod gemte credentials

3. Indehaver

Godkender kun udlevering af de anmodede claims

4. Verifier

Modtager én præsentation pr. credential query-id

Opbygningen af en DCQL-forespørgsel

En DCQL-forespørgsel er ét JSON-objekt med et credentials-array og eventuelt et credential_sets-array. Hver post i credentials er en credential query. Felter markeret med M er obligatoriske i den pågældende query.

dcql_query

credentials[ ]

Én credential query pr. credential, du har brug for

id + format

Hvilken credential, i hvilket format

meta

Typefilter, f.eks. vct_values

claims[ ]

Claim-stier, der skal udleveres

claim_sets[ ]

Accepterede kombinationer af claims

credential_sets[ ]

Valgfrit: hvilke kombinationer af credential queries der opfylder anmodningen

FeltTypeObligatorisk
idstringM
formatenum: dc+sd-jwt | mso_mdoc | jwt_vc_json | ldp_vcM
metaobjekt, opbygning afhænger af format
claimsarray af claim queries
claim_setsarray af arrays af claim-id'er
trusted_authoritiesarray af objekter med en type og values

Hver post i claims er selv et objekt: et id, der bruges til at henvise til den fra claim_sets, og en path, et array der angiver claimets placering i credentialen (for eksempel ["legal_name"] for et SD-JWT-claim på øverste niveau eller ["org", "registration_number"] for et indlejret), og eventuelt values, en liste over værdier som claimet skal matche.

Gennemgået eksempel: kontrol af en virksomhedsregistrering

Virksomhedsregistrering

dc+sd-jwt

Verifier siger: det er dette, jeg vil modtage

  • ✓ 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 wallet'en

Wallet'en svarer med et vp_token-objekt med credential query-id'et som nøgle. Hver værdi er et array af præsentationer. For dc+sd-jwt består en præsentation af den udstedersignerede JWT, én disclosure pr. udleveret claim og en key binding-JWT, der knytter den til nonce og klient for denne anmodning.

Det, wallet'en sender

{
  "vp_token": {
    "company_registration": [
      "<issuer-signed JWT>~<disclosure: registration_number>~<disclosure: legal_name>~<disclosure: registration_country>~<key binding JWT>"
    ]
  }
}

Claims, verifieren ser efter validering

{
  "vct": "urn:eudi:business:company-registration:1",
  "registration_number": "12345678",
  "legal_name": "Example Logistics B.V.",
  "registration_country": "NL"
}

Bed om et alternativ: claim_sets

claim_sets angiver grupper af claim-id'er i prioriteret rækkefølge. Wallet'en returnerer den første gruppe, den fuldt ud kan opfylde med det, indehaveren faktisk har, så verifieren ikke behøver sende to separate anmodninger for et præcist tilfælde og et alternativt tilfælde.

Gennemgået eksempel: registreringsnummer, eller alternativt kun juridisk navn

1. Foretrukket

reg_nolegal_name

Returneres, når credentialen indeholder begge claims

2. Alternativ

legal_name

Returneres kun, når det første sæt ikke kan opfyldes

{
  "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 foretrækker verifieren et registreringsnummer plus det juridiske navn, men accepterer det juridiske navn alene, hvis indehaverens credential ikke indeholder et claim med registreringsnummer.

Eksempel på svar: alternativet blev brugt

Det, wallet'en sender

{
  "vp_token": {
    "company_registration": [
      "<issuer-signed JWT>~<disclosure: legal_name>~<key binding JWT>"
    ]
  }
}

Claims, verifieren ser efter validering

{
  "vct": "urn:eudi:business:company-registration:1",
  "legal_name": "Example Logistics B.V."
}

Indehaverens credential har intet registreringsnummer, så wallet'en opfyldte det andet claim-sæt og udleverede en enkelt disclosure. Svaret angiver ikke, hvilket sæt der blev brugt: det aflæser verifieren af de claims, den modtager.

Kombination af credentials: credential_sets

credential_sets virker ét niveau over claim_sets. Hver post angiver options, hvor hver option er en gruppe af credential query-id'er. Wallet'en skal opfylde én option i hver påkrævet post, hvilket giver en verifier AND- og OR-logik på tværs af credentials i én anmodning.

Påkrævet

Virksomhedsregistrering

AND

En af

Momsregistrering

OR

En af

Attestering af bankkonto

"credential_sets": [
  { "options": [["company_registration"]] },
  { "options": [["vat_registration"], ["bank_account"]] }
]

Eksempel på svar: registrering plus bankkonto

Det, wallet'en sender

{
  "vp_token": {
    "company_registration": [
      "<issuer-signed JWT>~<disclosures>~<key binding JWT>"
    ],
    "bank_account": [
      "<issuer-signed JWT>~<disclosures>~<key binding JWT>"
    ]
  }
}

Claims, verifieren ser efter 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."
  }
}

Indehaveren har ingen credential for momsregistrering, så wallet'en valgte den anden option i det andet sæt. Query-id'er, der ikke blev brugt, her vat_registration, er simpelthen fraværende i vp_token.

Kun betroede udstedere: trusted_authorities

trusted_authorities begrænser en credential query til credentials, hvis udsteder er understøttet af en myndighed, som verifieren har tillid til. Hver post har en type og en liste af values: aki for en authority key identifier, etsi_tl for en ETSI-tillidsliste eller openid_federation for et trust anchor i en føderation. Wallet'en tilbyder kun credentials, der matcher.

Gennemgået eksempel: en registrering fra en listet udsteder

Verifier siger: kun fra udstedere på denne tillidsliste

type: etsi_tl

https://ec.europa.eu/tools/lotl/eu-lotl.xml

Registreringscredential fra en listet udsteder

udstederen er på tillidslisten

✓ Matcher forespørgslen

Registreringscredential fra en ikke-listet udsteder

udstederen er ikke på tillidslisten

✗ Matcher ikke, tilbydes ikke indehaveren

{
  "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: kun den listede udsteders credential

Det, wallet'en sender

{
  "vp_token": {
    "company_registration": [
      "<issuer-signed JWT>~<disclosure: registration_number>~<disclosure: legal_name>~<key binding JWT>"
    ]
  }
}

Claims, verifieren ser efter validering

{
  "vct": "urn:eudi:business:company-registration:1",
  "registration_number": "12345678",
  "legal_name": "Example Logistics B.V."
}

Indehaveren havde også en registreringscredential fra en ikke-listet udsteder, men wallet'en tilbød den ikke. trusted_authorities er et filter for wallet'en, ikke en garanti: verifieren kontrollerer stadig selv udstederen mod tillidslisten, når den validerer præsentationen.

Match på en værdi: claims.values

En claim query kan indeholde values, en liste af strenge, heltal eller booleans. Wallet'en returnerer kun claimet, når dets type og værdi præcist matcher en af dem, så en verifier kan kontrollere en betingelse uden først at bede om noget andet.

Gennemgået eksempel: kun virksomheder registreret i Nederlandene eller Belgien

Verifier siger: kun en virksomhed registreret i et af disse lande

reg_countryvalues:"NL""BE"

Hollandsk virksomhed

registration_country: "NL"

✓ Matcher forespørgslen

Tysk virksomhed

registration_country: "DE"

✗ Matcher ikke, tilbydes ikke indehaveren

{
  "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: en hollandsk virksomhed

Det, wallet'en sender

{
  "vp_token": {
    "company_registration": [
      "<issuer-signed JWT>~<disclosure: legal_name>~<disclosure: registration_country>~<key binding JWT>"
    ]
  }
}

Claims, verifieren ser efter validering

{
  "vct": "urn:eudi:business:company-registration:1",
  "legal_name": "Example Logistics B.V.",
  "registration_country": "NL"
}

En tysk virksomheds credential har registration_country "DE", så den opfylder ikke forespørgslen, og wallet'en har intet at returnere for den. Verifieren bør stadig kontrollere værdien i de validerede claims i stedet for at stole på wallet'ens filtrering.

Formatspecifikke begrænsninger i meta

SD-JWT VC: vct_values

For dc+sd-jwt angiver meta.vct_values de credential-typeidentifikatorer, verifieren accepterer. En forespørgsel matcher kun en gemt credential, hvis vct er en af de angivne værdier, så en verifier, der kun har tillid til én udsteders registreringscredential-type, angiver præcis den identifikator.

mso_mdoc: doctype_value og namespace

For mso_mdoc fastlægger meta.doctype_value ISO 18013-5 DocType, og hver claim-sti starter med det mdoc-namespace, claimet hører under, frem for et almindeligt feltnavn, da mdoc grupperer claims efter namespace i stedet for i et fladt objekt.

Hvor DCQL står i dag

  • DCQL er defineret i selve OpenID4VP-specifikationen, ikke som et separat dokument, og har været en del af udkastet, siden mekanismen blev indført for at erstatte en tidligere afhængighed af DIF Presentation Exchange i OpenID4VP-anmodninger.
  • EUDI Wallet Architecture and Reference Framework angiver OpenID4VP som præsentationsprotokol og dermed DCQL som den forespørgselsmekanisme, relying parties og wallets i økosystemet forventes at understøtte.
  • Referenceimplementeringer af wallets og verifiers i programmet EUDI Wallet Reference Implementation er konvergeret mod DCQL, så nye business wallet-integrationer, der bygges mod OpenID4VP i dag, bør gå ud fra DCQL frem for Presentation Exchange som forespørgselsformat for præsentationsanmodninger.

Relaterede begreber

Ofte stillede spørgsmål

Hvordan adskiller DCQL sig fra DIF Presentation Exchange?

Begge beskriver, hvad en verifier ønsker fra en wallet, men DCQL er afgrænset til OpenID4VP og defineret direkte i den specifikation, mens Presentation Exchange er en separat DIF-specifikation, der også dækker andre protokoller. DCQL er bevidst mindre: det har ingen input descriptor-grupper eller submission requirements, og det udtrykker formatspecifikke begrænsninger, såsom en mdoc-doctype eller en SD-JWT VC-type, direkte i et query-objekt i stedet for via et generisk JSON Schema-filter. EUDI Wallet-økosystemet har standardiseret på DCQL til OpenID4VP-præsentationer.

Kan én DCQL-forespørgsel bede om mere end én credential?

Ja. Arrayet credentials kan indeholde flere credential queries, hver med sit eget id. En wallet, der har match for alle poster, returnerer én præsentation pr. post. Det valgfrie credential_sets-objekt kan derudover kræve bestemte kombinationer, for eksempel acceptere enten en virksomhedsregistrerings-credential alene eller en virksomhedsregistrerings-credential sammen med en UBO-erklæring, uden at spørge indehaveren to gange.

Hvilket problem løser claim_sets inden for en enkelt credential query?

En credential indeholder ikke altid alle de claims, en verifier gerne vil have. claim_sets angiver alternative grupper af claim-id'er, som hver for sig kan opfylde anmodningen, ordnet fra mest til mindst foretrukket. Wallet'en vælger den første gruppe, den fuldt ud kan opfylde med de claims, indehaveren faktisk har, så en verifier kan bede om et præcist ID-nummer, hvor det findes, og falde tilbage på en grovere kontrol, såsom et over-18-flag, uden at sende to separate anmodninger.

Er DCQL specifikt for EUDI Wallet?

Nej. DCQL er en del af OpenID4VP-kernespecifikationen, og enhver OpenID4VP-implementering kan bruge det. EUDI Wallet-økosystemet er en fremtrædende bruger: Architecture and Reference Framework angiver OpenID4VP med DCQL som den præsentationsmekanisme, relying parties skal understøtte, og derfor er det særligt vigtigt for wallets og verifiers bygget til det europæiske marked.

Udfører DCQL selv selektiv offentliggørelse?

Nej. DCQL beskriver kun, hvad der anmodes om. Om wallet'en kan afsløre præcis de claims og intet andet, afhænger af credential-formatet: både en SD-JWT VC og en ISO mdoc understøtter udlevering af en delmængde af deres claims, så et DCQL claims-array bygger på den understøttelse. DCQL mod et format uden selektiv offentliggørelse vil stadig fungere, men indehaveren vil skulle udlevere hele credentialen for at opfylde selv en forespørgsel på ét claim.

Kilder

  1. OpenID for Verifiable Presentations 1.0, afsnittet Digital Credentials Query Language (DCQL)
  2. EUDI Wallet Architecture and Reference Framework
  3. DIF Presentation Exchange 2.0.0-specifikationen

Denne side er udelukkende til orientering og udgør ikke juridisk rådgivning. Kontakt OpenID Foundation og Europa-Kommissionen direkte for autoritativ vejledning.

Tal med os om integration med EUDI Wallet