Η DCQL εξηγημένη: πώς ένας επαληθευτής ζητά από ένα πορτοφόλι ακριβώς ό,τι χρειάζεται
Η Digital Credentials Query Language, DCQL, είναι η μορφή ερωτημάτων JSON που χρησιμοποιεί το OpenID4VP μέσα σε ένα αίτημα παρουσίασης. Επιτρέπει σε ένα βασιζόμενο μέρος να περιγράψει ποια διαπιστευτήρια και ποια στοιχεία τους θέλει να δει, με τρόπο που κάθε συμβατό πορτοφόλι μπορεί να αναλύσει χωρίς ειδική ενσωμάτωση.
Το πρόβλημα που λύνει η DCQL
Ένα επιχειρηματικό πορτοφόλι μπορεί να περιέχει διαπιστευτήρια σε διάφορες μορφές: εγγραφή εταιρείας ως SD-JWT VC, επαγγελματικό προσόν κωδικοποιημένο ως mdoc, ένα W3C verifiable credential από παλαιότερο πιλοτικό έργο. Ένας επαληθευτής που χρειάζεται μόνο να επιβεβαιώσει αριθμό μητρώου και νόμιμη επωνυμία δεν έχει φορητό τρόπο να ζητήσει ακριβώς αυτό, ανεξαρτήτως μορφής, χωρίς είτε να δεχτεί ολόκληρο το διαπιστευτήριο είτε να γράψει χειροκίνητα ξεχωριστό αίτημα ανά μορφή και ανά προμηθευτή πορτοφολιού.
Η DCQL καλύπτει την πλευρά του αιτήματος σε αυτό το κενό. Είναι ένα ενιαίο αντικείμενο JSON, ενσωματωμένο στο αίτημα εξουσιοδότησης OpenID4VP, που ορίζει ένα ή περισσότερα ερωτήματα διαπιστευτηρίων, το καθένα δεμένο σε μια μορφή και ένα σύνολο διαδρομών στοιχείων. Το πορτοφόλι αξιολογεί το ερώτημα έναντι των αποθηκευμένων διαπιστευτηρίων, βρίσκει ποια ταιριάζουν και μόνο τότε ζητά από τον κάτοχο να εγκρίνει την αποκάλυψη αυτών των συγκεκριμένων στοιχείων. Ο επαληθευτής λαμβάνει μια προβλέψιμη δομή, όποιο πορτοφόλι κι αν χρησιμοποίησε ο κάτοχος.
1. Επαληθευτής
Στέλνει αίτημα OpenID4VP με dcql_query
2. Πορτοφόλι
Συγκρίνει το ερώτημα με τα αποθηκευμένα διαπιστευτήρια
3. Κάτοχος
Εγκρίνει την αποκάλυψη μόνο των ζητούμενων στοιχείων
4. Επαληθευτής
Λαμβάνει μία παρουσίαση ανά id ερωτήματος διαπιστευτηρίου
Η μορφή ενός ερωτήματος DCQL
Ένα ερώτημα DCQL είναι ένα αντικείμενο JSON με έναν πίνακα credentials και, προαιρετικά, έναν πίνακα credential_sets. Κάθε καταχώριση στο credentials είναι ένα ερώτημα διαπιστευτηρίου. Τα πεδία με την ένδειξη M είναι υποχρεωτικά σε αυτό το ερώτημα.
dcql_query
credentials[ ]
Ένα ερώτημα για κάθε διαπιστευτήριο που χρειάζεστε
id + format
Ποιο διαπιστευτήριο, σε ποια μορφή
meta
Φίλτρο τύπου, π.χ. vct_values
claims[ ]
Διαδρομές στοιχείων προς αποκάλυψη
claim_sets[ ]
Αποδεκτοί συνδυασμοί στοιχείων
credential_sets[ ]
Προαιρετικό: ποιοι συνδυασμοί ερωτημάτων διαπιστευτηρίων ικανοποιούν το αίτημα
| Πεδίο | Τύπος | Υποχρεωτικό |
|---|---|---|
| id | string | M |
| format | enum: dc+sd-jwt | mso_mdoc | jwt_vc_json | ldp_vc | M |
| meta | αντικείμενο, η δομή εξαρτάται από τη μορφή | |
| claims | πίνακας ερωτημάτων στοιχείων | |
| claim_sets | πίνακας πινάκων με id στοιχείων | |
| trusted_authorities | πίνακας αντικειμένων με τύπο και τιμές |
Κάθε καταχώριση στο claims είναι επίσης αντικείμενο: ένα id με το οποίο αναφέρεται από το claim_sets, ένα path, δηλαδή πίνακας που εντοπίζει το στοιχείο μέσα στο διαπιστευτήριο (για παράδειγμα ["legal_name"] για στοιχείο SD-JWT ανώτατου επιπέδου ή ["org", "registration_number"] για εμφωλευμένο), και προαιρετικά values, μια λίστα τιμών με τις οποίες πρέπει να ταιριάζει το στοιχείο.
Παράδειγμα: έλεγχος εγγραφής εταιρείας
Εγγραφή εταιρείας
dc+sd-jwtΟ επαληθευτής λέει: αυτό θέλω να λάβω
- ✓ Αριθμός μητρώουreg_nopath: ["registration_number"]
- ✓ Νόμιμη επωνυμίαlegal_namepath: ["legal_name"]
- ✓ Χώρα εγγραφήςreg_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"] }
]
}
]
}Παράδειγμα απάντησης από το πορτοφόλι
Το πορτοφόλι απαντά με ένα αντικείμενο vp_token με κλειδιά τα id των ερωτημάτων διαπιστευτηρίων. Κάθε τιμή είναι πίνακας παρουσιάσεων. Για dc+sd-jwt, μια παρουσίαση αποτελείται από το JWT υπογεγραμμένο από τον εκδότη, ένα disclosure ανά αποκαλυπτόμενο στοιχείο και ένα key binding JWT που τη συνδέει με το nonce και τον client αυτού του αιτήματος.
Τι στέλνει το πορτοφόλι
{
"vp_token": {
"company_registration": [
"<issuer-signed JWT>~<disclosure: registration_number>~<disclosure: legal_name>~<disclosure: registration_country>~<key binding JWT>"
]
}
}Στοιχεία που βλέπει ο επαληθευτής μετά την επικύρωση
{
"vct": "urn:eudi:business:company-registration:1",
"registration_number": "12345678",
"legal_name": "Example Logistics B.V.",
"registration_country": "NL"
}Εναλλακτική επιλογή: claim_sets
Το claim_sets απαριθμεί ομάδες id στοιχείων με σειρά προτίμησης. Το πορτοφόλι επιστρέφει την πρώτη ομάδα που μπορεί να ικανοποιήσει πλήρως με όσα έχει πράγματι ο κάτοχος, ώστε ο επαληθευτής να μη χρειάζεται δύο ξεχωριστά αιτήματα για την ακριβή και την εναλλακτική περίπτωση.
Παράδειγμα: αριθμός μητρώου ή, εναλλακτικά, μόνο νόμιμη επωνυμία
1. Προτιμώμενο
Επιστρέφεται όταν το διαπιστευτήριο περιέχει και τα δύο στοιχεία
2. Εναλλακτικό
Επιστρέφεται μόνο αν δεν ικανοποιείται το πρώτο σύνολο
{
"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"]
]
}
]
}Εδώ ο επαληθευτής προτιμά αριθμό μητρώου μαζί με τη νόμιμη επωνυμία, αλλά δέχεται και μόνο τη νόμιμη επωνυμία αν το διαπιστευτήριο του κατόχου δεν περιέχει στοιχείο αριθμού μητρώου.
Παράδειγμα απάντησης: χρησιμοποιήθηκε η εναλλακτική
Τι στέλνει το πορτοφόλι
{
"vp_token": {
"company_registration": [
"<issuer-signed JWT>~<disclosure: legal_name>~<key binding JWT>"
]
}
}Στοιχεία που βλέπει ο επαληθευτής μετά την επικύρωση
{
"vct": "urn:eudi:business:company-registration:1",
"legal_name": "Example Logistics B.V."
}Το διαπιστευτήριο του κατόχου δεν έχει αριθμό μητρώου, οπότε το πορτοφόλι ικανοποίησε το δεύτερο σύνολο στοιχείων και αποκάλυψε ένα μόνο disclosure. Η απάντηση δεν αναφέρει ποιο σύνολο χρησιμοποιήθηκε: ο επαληθευτής το συμπεραίνει από τα στοιχεία που λαμβάνει.
Συνδυασμός διαπιστευτηρίων: credential_sets
Το credential_sets λειτουργεί ένα επίπεδο πάνω από το claim_sets. Κάθε καταχώριση απαριθμεί options, όπου κάθε επιλογή είναι μια ομάδα id ερωτημάτων διαπιστευτηρίων. Το πορτοφόλι πρέπει να ικανοποιήσει μία επιλογή από κάθε υποχρεωτική καταχώριση, κάτι που δίνει στον επαληθευτή λογική AND και OR μεταξύ διαπιστευτηρίων σε ένα μόνο αίτημα.
Υποχρεωτικό
Εγγραφή εταιρείας
Ένα από
Εγγραφή ΦΠΑ
Ένα από
Βεβαίωση τραπεζικού λογαριασμού
"credential_sets": [
{ "options": [["company_registration"]] },
{ "options": [["vat_registration"], ["bank_account"]] }
]Παράδειγμα απάντησης: εγγραφή και τραπεζικός λογαριασμός
Τι στέλνει το πορτοφόλι
{
"vp_token": {
"company_registration": [
"<issuer-signed JWT>~<disclosures>~<key binding JWT>"
],
"bank_account": [
"<issuer-signed JWT>~<disclosures>~<key binding JWT>"
]
}
}Στοιχεία που βλέπει ο επαληθευτής μετά την επικύρωση
{
"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."
}
}Ο κάτοχος δεν έχει διαπιστευτήριο εγγραφής ΦΠΑ, οπότε το πορτοφόλι επέλεξε τη δεύτερη επιλογή του δεύτερου συνόλου. Τα id ερωτημάτων που δεν χρησιμοποιήθηκαν, εδώ το vat_registration, απλώς απουσιάζουν από το vp_token.
Μόνο αξιόπιστοι εκδότες: trusted_authorities
Το trusted_authorities περιορίζει ένα ερώτημα διαπιστευτηρίου σε διαπιστευτήρια των οποίων ο εκδότης υποστηρίζεται από αρχή που εμπιστεύεται ο επαληθευτής. Κάθε καταχώριση έχει έναν τύπο και μια λίστα τιμών: aki για αναγνωριστικό κλειδιού αρχής, etsi_tl για λίστα εμπιστοσύνης ETSI ή openid_federation για άγκυρα εμπιστοσύνης ομοσπονδίας. Το πορτοφόλι προσφέρει μόνο διαπιστευτήρια που ταιριάζουν.
Παράδειγμα: εγγραφή από εκδότη της λίστας
Ο επαληθευτής λέει: μόνο από εκδότες αυτής της λίστας εμπιστοσύνης
https://ec.europa.eu/tools/lotl/eu-lotl.xml
Διαπιστευτήριο εγγραφής από εκδότη της λίστας
ο εκδότης είναι στη λίστα εμπιστοσύνης
✓ Ταιριάζει
Διαπιστευτήριο εγγραφής από εκδότη εκτός λίστας
ο εκδότης δεν είναι στη λίστα εμπιστοσύνης
✗ Δεν ταιριάζει, δεν προσφέρεται στον κάτοχο
{
"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"] }
]
}
]
}Παράδειγμα απάντησης: μόνο το διαπιστευτήριο του εκδότη της λίστας
Τι στέλνει το πορτοφόλι
{
"vp_token": {
"company_registration": [
"<issuer-signed JWT>~<disclosure: registration_number>~<disclosure: legal_name>~<key binding JWT>"
]
}
}Στοιχεία που βλέπει ο επαληθευτής μετά την επικύρωση
{
"vct": "urn:eudi:business:company-registration:1",
"registration_number": "12345678",
"legal_name": "Example Logistics B.V."
}Ο κάτοχος είχε επίσης διαπιστευτήριο εγγραφής από εκδότη εκτός λίστας, αλλά το πορτοφόλι δεν το προσέφερε. Το trusted_authorities είναι φίλτρο για το πορτοφόλι, όχι εγγύηση: ο επαληθευτής ελέγχει ο ίδιος τον εκδότη έναντι της λίστας εμπιστοσύνης όταν επικυρώνει την παρουσίαση.
Αντιστοίχιση τιμής: claims.values
Ένα ερώτημα στοιχείου μπορεί να περιέχει values, μια λίστα από συμβολοσειρές, ακέραιους ή λογικές τιμές. Το πορτοφόλι επιστρέφει το στοιχείο μόνο όταν ο τύπος και η τιμή του ταιριάζουν ακριβώς με μία από αυτές, ώστε ο επαληθευτής να ελέγχει μια συνθήκη χωρίς να ζητήσει πρώτα οτιδήποτε άλλο.
Παράδειγμα: μόνο εταιρείες εγγεγραμμένες στην Ολλανδία ή στο Βέλγιο
Ο επαληθευτής λέει: μόνο εταιρεία εγγεγραμμένη σε μία από αυτές τις χώρες
Ολλανδική εταιρεία
registration_country: "NL"
✓ Ταιριάζει
Γερμανική εταιρεία
registration_country: "DE"
✗ Δεν ταιριάζει, δεν προσφέρεται στον κάτοχο
{
"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"]
}
]
}
]
}Παράδειγμα απάντησης: μια ολλανδική εταιρεία
Τι στέλνει το πορτοφόλι
{
"vp_token": {
"company_registration": [
"<issuer-signed JWT>~<disclosure: legal_name>~<disclosure: registration_country>~<key binding JWT>"
]
}
}Στοιχεία που βλέπει ο επαληθευτής μετά την επικύρωση
{
"vct": "urn:eudi:business:company-registration:1",
"legal_name": "Example Logistics B.V.",
"registration_country": "NL"
}Το διαπιστευτήριο μιας γερμανικής εταιρείας έχει registration_country "DE", οπότε δεν ικανοποιεί το ερώτημα και το πορτοφόλι δεν έχει τίποτα να επιστρέψει γι' αυτό. Ο επαληθευτής θα πρέπει παρ' όλα αυτά να ελέγχει την τιμή στα επικυρωμένα στοιχεία αντί να βασίζεται στο φιλτράρισμα του πορτοφολιού.
Περιορισμοί ανά μορφή στο meta
SD-JWT VC: vct_values
Για dc+sd-jwt, το meta.vct_values απαριθμεί τα αναγνωριστικά τύπων διαπιστευτηρίων που δέχεται ο επαληθευτής. Ένα ερώτημα ταιριάζει μόνο με αποθηκευμένο διαπιστευτήριο του οποίου το vct είναι μία από τις τιμές της λίστας, οπότε ένας επαληθευτής που εμπιστεύεται μόνο τον τύπο διαπιστευτηρίου εγγραφής ενός εκδότη αναφέρει ακριβώς αυτό το αναγνωριστικό.
mso_mdoc: doctype_value και namespace
Για mso_mdoc, το meta.doctype_value καθορίζει το ISO 18013-5 DocType, και κάθε διαδρομή στοιχείου ξεκινά με το mdoc namespace στο οποίο ανήκει το στοιχείο αντί για απλό όνομα πεδίου, επειδή το mdoc ομαδοποιεί τα στοιχεία ανά namespace αντί για επίπεδο αντικείμενο.
Πού βρίσκεται σήμερα η DCQL
- Η DCQL ορίζεται μέσα στην ίδια την προδιαγραφή OpenID4VP, όχι σε ξεχωριστό έγγραφο, και είναι μέρος του σχεδίου από τότε που ο μηχανισμός εισήχθη για να αντικαταστήσει την παλαιότερη εξάρτηση από το DIF Presentation Exchange για αιτήματα OpenID4VP.
- Το EUDI Wallet Architecture and Reference Framework ορίζει το OpenID4VP ως πρωτόκολλο παρουσίασης και, μαζί του, τη DCQL ως τον μηχανισμό ερωτημάτων που αναμένεται να υποστηρίζουν τα βασιζόμενα μέρη και τα πορτοφόλια του οικοσυστήματος.
- Οι υλοποιήσεις αναφοράς πορτοφολιών και επαληθευτών στο πρόγραμμα EUDI Wallet Reference Implementation έχουν συγκλίνει στη DCQL, οπότε οι νέες ενσωματώσεις επιχειρηματικών πορτοφολιών που χτίζονται σήμερα πάνω στο OpenID4VP θα πρέπει να θεωρούν δεδομένη τη DCQL, και όχι το Presentation Exchange, ως μορφή ερωτημάτων για αιτήματα παρουσίασης.
Σχετικοί όροι
Συχνές ερωτήσεις
Σε τι διαφέρει η DCQL από το DIF Presentation Exchange;
Και τα δύο περιγράφουν τι ζητά ένας επαληθευτής από ένα πορτοφόλι, όμως η DCQL αφορά αποκλειστικά το OpenID4VP και ορίζεται απευθείας σε αυτή την προδιαγραφή, ενώ το Presentation Exchange είναι ξεχωριστή προδιαγραφή του DIF που καλύπτει και άλλα πρωτόκολλα. Η DCQL είναι σκόπιμα μικρότερη: δεν έχει ομάδες input descriptors ούτε submission requirements, και εκφράζει περιορισμούς ανά μορφή, όπως ένα mdoc doctype ή έναν τύπο SD-JWT VC, απευθείας σε ένα αντικείμενο ερωτήματος αντί για ένα γενικό φίλτρο JSON Schema. Το οικοσύστημα του EUDI Wallet έχει τυποποιηθεί στη DCQL για παρουσιάσεις OpenID4VP.
Μπορεί ένα ερώτημα DCQL να ζητήσει περισσότερα από ένα διαπιστευτήρια;
Ναι. Ο πίνακας credentials μπορεί να περιέχει πολλά ερωτήματα διαπιστευτηρίων, το καθένα με δικό του id. Ένα πορτοφόλι που διαθέτει αντιστοιχίες για κάθε καταχώριση επιστρέφει μία παρουσίαση ανά καταχώριση. Επιπλέον, το προαιρετικό αντικείμενο credential_sets μπορεί να απαιτεί συγκεκριμένους συνδυασμούς, για παράδειγμα να δέχεται είτε μόνο ένα διαπιστευτήριο εγγραφής εταιρείας είτε ένα διαπιστευτήριο εγγραφής εταιρείας μαζί με δήλωση UBO, χωρίς να ερωτάται ο κάτοχος δύο φορές.
Ποιο πρόβλημα λύνουν τα claim_sets μέσα σε ένα ερώτημα διαπιστευτηρίου;
Ένα διαπιστευτήριο δεν περιέχει πάντα κάθε στοιχείο που θα ήθελε ένας επαληθευτής. Το claim_sets απαριθμεί εναλλακτικές ομάδες id στοιχείων, καθεμία από τις οποίες ικανοποιεί από μόνη της το αίτημα, με σειρά από την πιο προτιμώμενη στη λιγότερο προτιμώμενη. Το πορτοφόλι επιλέγει την πρώτη ομάδα που μπορεί να ικανοποιήσει πλήρως με τα στοιχεία που έχει πράγματι ο κάτοχος, ώστε ο επαληθευτής να ζητά έναν ακριβή αριθμό ταυτότητας όπου υπάρχει και να καταφεύγει σε πιο χονδρικό έλεγχο, όπως μια ένδειξη ενηλικότητας, χωρίς να στέλνει δύο ξεχωριστά αιτήματα.
Είναι η DCQL ειδική για το EUDI Wallet;
Όχι. Η DCQL αποτελεί μέρος της βασικής προδιαγραφής OpenID4VP και μπορεί να τη χρησιμοποιήσει κάθε υλοποίηση OpenID4VP. Το οικοσύστημα του EUDI Wallet είναι σημαντικός χρήστης της: το Architecture and Reference Framework ορίζει το OpenID4VP με DCQL ως τον μηχανισμό παρουσίασης που πρέπει να υποστηρίζουν τα βασιζόμενα μέρη, γι' αυτό έχει ιδιαίτερη σημασία για πορτοφόλια και επαληθευτές που προορίζονται για την ευρωπαϊκή αγορά.
Εκτελεί η ίδια η DCQL επιλεκτική αποκάλυψη;
Όχι. Η DCQL περιγράφει μόνο τι ζητείται. Το αν το πορτοφόλι μπορεί να αποκαλύψει ακριβώς αυτά τα στοιχεία και τίποτα άλλο εξαρτάται από τη μορφή του διαπιστευτηρίου: τόσο το SD-JWT VC όσο και το ISO mdoc υποστηρίζουν αποκάλυψη υποσυνόλου στοιχείων, οπότε ένας πίνακας claims της DCQL αντιστοιχίζεται σε αυτή την υποστήριξη. Η DCQL θα λειτουργούσε και με μορφή χωρίς επιλεκτική αποκάλυψη, όμως ο κάτοχος θα έπρεπε να αποκαλύψει ολόκληρο το διαπιστευτήριο ακόμη και για ερώτημα ενός στοιχείου.
Πηγές
Η σελίδα αυτή έχει ενημερωτικό χαρακτήρα και δεν αποτελεί νομική συμβουλή. Για έγκυρη καθοδήγηση απευθυνθείτε απευθείας στο OpenID Foundation και στην Ευρωπαϊκή Επιτροπή.