Hoppa till huvudinnehåll

DCQL förklarat: så begär en verifierare exakt det den behöver från en plånbok

Digital Credentials Query Language, DCQL, är det JSON-frågeformat som OpenID4VP använder i en presentationsbegäran. Det låter en förlitande part beskriva vilka intyg, och vilka uppgifter i dem, den vill se, på ett sätt som varje kompatibel plånbok kan tolka utan en skräddarsydd integration.

Problemet som DCQL löser

En företagsplånbok kan innehålla intyg i flera format: en företagsregistrering som SD-JWT VC, en yrkeskvalifikation kodad som mdoc och ett W3C verifiable credential från ett tidigare pilotprojekt. En verifierare som bara behöver bekräfta ett registreringsnummer och ett juridiskt namn har inget portabelt sätt att begära just det över olika format, utan att antingen godta hela intyget eller handkoda en separat begäran per format och per plånboksleverantör.

DCQL täpper till den luckan på begäranssidan. Det är ett enda JSON-objekt, inbäddat i OpenID4VP-auktoriseringsbegäran, som namnger en eller flera intygsfrågor, var och en knuten till ett format och en uppsättning uppgiftssökvägar. Plånboken utvärderar frågan mot sina lagrade intyg, tar reda på vilka som matchar och ber först därefter innehavaren att godkänna utlämnandet av just de uppgifterna. Verifieraren får en förutsägbar struktur att tolka, oavsett vilken plånbok innehavaren använde.

1. Verifierare

Skickar en OpenID4VP-begäran med en dcql_query

2. Plånbok

Matchar frågan mot lagrade intyg

3. Innehavare

Godkänner att bara de begärda uppgifterna lämnas ut

4. Verifierare

Tar emot en presentation per id i intygsfrågan

Så är en DCQL-fråga uppbyggd

En DCQL-fråga är ett JSON-objekt med en credentials-array och, valfritt, en credential_sets-array. Varje post i credentials är en intygsfråga. Fält markerade med M är obligatoriska i den frågan.

dcql_query

credentials[ ]

En intygsfråga per intyg du behöver

id + format

Vilket intyg, i vilket format

meta

Typfilter, till exempel vct_values

claims[ ]

Sökvägar till uppgifter som ska lämnas ut

claim_sets[ ]

Godtagbara kombinationer av uppgifter

credential_sets[ ]

Valfritt: vilka kombinationer av intygsfrågor som uppfyller begäran

FältTypObligatoriskt
idstringM
formatenum: dc+sd-jwt | mso_mdoc | jwt_vc_json | ldp_vcM
metaobjekt, formen beror på format
claimsarray av uppgiftsfrågor
claim_setsarray av arrayer med uppgifts-id:n
trusted_authoritiesarray av objekt med en typ och värden

Varje post i claims är i sin tur ett objekt: ett id som används för att referera till den från claim_sets, en path, en array som anger var uppgiften finns i intyget (till exempel ["legal_name"] för en SD-JWT-uppgift på toppnivå eller ["org", "registration_number"] för en nästlad uppgift), och valfritt values, en lista med värden som uppgiften måste matcha.

Exempel: kontroll av företagsregistrering

Företagsregistrering

dc+sd-jwt

Verifieraren säger: det här vill jag få

  • ✓ Registreringsnummerreg_nopath: ["registration_number"]
  • ✓ Juridiskt namnlegal_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"] }
      ]
    }
  ]
}

Exempel på svar från plånboken

Plånboken svarar med ett vp_token-objekt där nycklarna är intygsfrågornas id:n. Varje värde är en array av presentationer. För dc+sd-jwt består en presentation av den utfärdarsignerade JWT:n, en disclosure per utlämnad uppgift och en key binding JWT som knyter den till denna begärans nonce och klient.

Vad plånboken skickar

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

Uppgifter som verifieraren ser efter validering

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

Begära ett reservalternativ: claim_sets

claim_sets listar grupper av uppgifts-id:n i prioritetsordning. Plånboken returnerar den första grupp den helt kan uppfylla med det innehavaren faktiskt har, så att verifieraren slipper skicka två separata förfrågningar för ett exakt fall och ett reservfall.

Exempel: registreringsnummer, eller bara juridiskt namn som reserv

1. Föredraget

reg_nolegal_name

Returneras när intyget innehåller båda uppgifterna

2. Reserv

legal_name

Returneras bara när den första uppsättningen inte kan uppfyllas

{
  "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"]
      ]
    }
  ]
}

Här föredrar verifieraren registreringsnummer plus juridiskt namn, men godtar enbart det juridiska namnet om innehavarens intyg inte innehåller någon uppgift om registreringsnummer.

Exempel på svar: reservalternativet användes

Vad plånboken skickar

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

Uppgifter som verifieraren ser efter validering

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

Innehavarens intyg har inget registreringsnummer, så plånboken uppfyllde den andra uppgiftsuppsättningen och lämnade ut en enda disclosure. Svaret anger inte vilken uppsättning som användes: verifieraren utläser det av de uppgifter den tar emot.

Kombinera intyg: credential_sets

credential_sets verkar en nivå ovanför claim_sets. Varje post listar options, där varje alternativ är en grupp id:n för intygsfrågor. Plånboken måste uppfylla ett alternativ i varje obligatorisk post, vilket ger verifieraren OCH- och ELLER-logik mellan intyg i en enda begäran.

Obligatorisk

Företagsregistrering

AND

En av

Momsregistrering

OR

En av

Intyg om bankkonto

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

Exempel på svar: registrering plus bankkonto

Vad plånboken skickar

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

Uppgifter som verifieraren 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."
  }
}

Innehavaren har inget intyg om momsregistrering, så plånboken valde det andra alternativet i den andra uppsättningen. Fråge-id:n som inte användes, här vat_registration, saknas helt enkelt i vp_token.

Bara betrodda utfärdare: trusted_authorities

trusted_authorities begränsar en intygsfråga till intyg vars utfärdare backas av en myndighet som verifieraren litar på. Varje post har en typ och en lista med värden: aki för en authority key identifier, etsi_tl för en ETSI-betrodd lista eller openid_federation för ett förtroendeankare i en federation. Plånboken erbjuder bara intyg som matchar.

Exempel: en registrering från en listad utfärdare

Verifieraren säger: bara från utfärdare på den här betrodda listan

type: etsi_tl

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

Registreringsintyg från en listad utfärdare

utfärdaren finns på den betrodda listan

✓ Matchar frågan

Registreringsintyg från en olistad utfärdare

utfärdaren finns inte på den betrodda listan

✗ Matchar inte, erbjuds inte innehavaren

{
  "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"] }
      ]
    }
  ]
}

Exempel på svar: bara intyget från den listade utfärdaren

Vad plånboken skickar

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

Uppgifter som verifieraren ser efter validering

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

Innehavaren hade också ett registreringsintyg från en olistad utfärdare, men plånboken erbjöd det inte. trusted_authorities är ett filter för plånboken, inte en garanti: verifieraren kontrollerar ändå själv utfärdaren mot den betrodda listan när den validerar presentationen.

Matcha ett värde: claims.values

En uppgiftsfråga kan innehålla values, en lista med strängar, heltal eller booleska värden. Plånboken returnerar bara uppgiften när dess typ och värde exakt matchar något av dem, så att en verifierare kan kontrollera ett villkor utan att först begära något annat.

Exempel: bara företag registrerade i Nederländerna eller Belgien

Verifieraren säger: bara ett företag registrerat i något av dessa länder

reg_countryvalues:"NL""BE"

Nederländskt företag

registration_country: "NL"

✓ Matchar frågan

Tyskt företag

registration_country: "DE"

✗ Matchar inte, erbjuds inte innehavaren

{
  "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"]
        }
      ]
    }
  ]
}

Exempel på svar: ett nederländskt företag

Vad plånboken skickar

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

Uppgifter som verifieraren ser efter validering

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

Ett tyskt företags intyg har registration_country "DE", så det uppfyller inte frågan och plånboken har inget att returnera för det. Verifieraren bör ändå kontrollera värdet i de validerade uppgifterna i stället för att förlita sig på plånbokens filtrering.

Formatspecifika villkor i meta

SD-JWT VC: vct_values

För dc+sd-jwt listar meta.vct_values de identifierare för intygstyper som verifieraren godtar. En fråga matchar bara ett lagrat intyg vars vct är ett av de listade värdena, så en verifierare som bara litar på en viss utfärdares typ av registreringsintyg listar exakt den identifieraren.

mso_mdoc: doctype_value och namnrymd

För mso_mdoc fastställer meta.doctype_value DocType enligt ISO 18013-5, och varje uppgiftssökväg börjar med den mdoc-namnrymd som uppgiften tillhör i stället för ett vanligt fältnamn, eftersom mdoc grupperar uppgifter per namnrymd i stället för i ett platt objekt.

Var DCQL står i dag

  • DCQL definieras i själva OpenID4VP-specifikationen, inte i ett separat dokument, och har ingått i utkastet sedan mekanismen infördes för att ersätta ett tidigare beroende av DIF Presentation Exchange för OpenID4VP-förfrågningar.
  • EUDI Wallet Architecture and Reference Framework anger OpenID4VP som presentationsprotokoll och därmed DCQL som den frågemekanism som förlitande parter och plånböcker i ekosystemet förväntas stödja.
  • Referensimplementationer av plånböcker och verifierare i programmet EUDI Wallet Reference Implementation har samlats kring DCQL. Nya integrationer av företagsplånböcker som byggs mot OpenID4VP i dag bör därför utgå från DCQL, inte Presentation Exchange, som frågeformat för presentationsbegäranden.

Relaterade begrepp

Vanliga frågor

Hur skiljer sig DCQL från DIF Presentation Exchange?

Båda beskriver vad en verifierare vill ha från en plånbok, men DCQL är avgränsat till OpenID4VP och definieras direkt i den specifikationen, medan Presentation Exchange är en separat DIF-specifikation som även täcker andra protokoll. DCQL är medvetet mindre: det saknar input descriptor-grupper och submission requirements, och det uttrycker formatspecifika villkor, som en mdoc-doctype eller en SD-JWT VC-typ, direkt i ett frågeobjekt i stället för via ett generiskt JSON Schema-filter. EUDI Wallet-ekosystemet har standardiserat på DCQL för OpenID4VP-presentationer.

Kan en DCQL-fråga begära mer än ett intyg?

Ja. Arrayen credentials kan lista flera intygsfrågor, var och en med eget id. En plånbok som har träffar för varje post returnerar en presentation per post. Det valfria objektet credential_sets kan dessutom kräva särskilda kombinationer, till exempel godta antingen ett företagsregistreringsintyg ensamt eller ett företagsregistreringsintyg tillsammans med en UBO-förklaring, utan att fråga innehavaren två gånger.

Vilket problem löser claim_sets inom en enskild intygsfråga?

Ett intyg innehåller inte alltid alla uppgifter som en verifierare skulle vilja ha. claim_sets listar alternativa grupper av uppgifts-id:n som var för sig skulle uppfylla begäran, ordnade från mest till minst föredragen. Plånboken väljer den första grupp den helt kan uppfylla med de uppgifter innehavaren faktiskt har. På så sätt kan en verifierare begära ett exakt ID-nummer där det finns och falla tillbaka på en grövre kontroll, som en över 18-flagga, utan att skicka två separata förfrågningar.

Är DCQL specifikt för EUDI Wallet?

Nej. DCQL är en del av OpenID4VP:s kärnspecifikation och kan användas av alla OpenID4VP-implementationer. EUDI Wallet-ekosystemet är en framträdande användare: Architecture and Reference Framework anger OpenID4VP med DCQL som den presentationsmekanism som förlitande parter måste stödja. Därför är det särskilt viktigt för plånböcker och verifierare som byggs för den europeiska marknaden.

Utför DCQL själv selektivt utlämnande?

Nej. DCQL beskriver bara vad som efterfrågas. Om plånboken kan avslöja exakt de uppgifterna och inget annat beror på intygsformatet: både SD-JWT VC och ISO mdoc stöder utlämnande av en delmängd av sina uppgifter, så en DCQL claims-array bygger på det stödet. DCQL mot ett format utan selektivt utlämnande skulle fortfarande fungera, men innehavaren skulle då behöva lämna ut hela intyget även för en fråga om en enda uppgift.

Källor

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

Den här sidan är endast informativ och utgör inte juridisk rådgivning. För auktoritativ vägledning, kontakta OpenID Foundation och Europeiska kommissionen direkt.

Prata med oss om integration med EUDI Wallet