Liigu põhisisu juurde

OpenID4VCI tunnistuse väljastamine selgitatud: pakkumisest vastuvõetud tunnistuseni

OpenID4VCI ehk OpenID for Verifiable Credential Issuance määratleb, kuidas rahakott taotleb ja saab väljastajalt tunnistuse. Üks väljastamine läbib mitu erinevat sammu, enne kui rahakotil on tegelikult kasutatav tunnistus, ja igal sammul on oma ebaõnnestumise viis. See leht käsitleb kogu seda elutsüklit algusest lõpuni, koos originaalsete läbitöötatud näidetega.

Kaks võimalust alustamiseks: eelautoriseeritud kood ja autoriseerimiskood

Väljastamine algab sageli väljastaja saadetud Credential Offer'ist ning selles nimetatud grant otsustab, kuidas rahakott autoriseeritakse. Rahakott saab väljastamise alustada ka ise, ilma pakkumiseta, kasutades autoriseerimiskoodi voogu. Mõlemad vood lõpevad samas kohas: rahakotil on juurdepääsutoken, mida ta saab kasutada tunnistuse taotlemiseks.

Eelautoriseeritud koodi voog

1. Väljastaja

Tunneb hoidjat juba, väljastab Credential Offer'i koos pre-authorized_code'iga

2. Rahakott

Lunastab koodi tokeni lõpp-punktis, valikuliselt koos tehingukoodiga

3. Rahakott

Taotleb tunnistust koos oma võtme valduse tõendiga

Autoriseerimiskoodi voog

1. Rahakott

Skannib Credential Offer'i, mis nimetab authorization_code granti, või alustab voogu ise ilma pakkumiseta

2. Autoriseerimisserver

Juhib hoidja läbi sisselogimise ja nõusoleku, seejärel väljastab koodi

3. Rahakott

Vahetab koodi tokeni vastu, seejärel taotleb tunnistust

Tunnistuse pakkumise kogu elutsükkel

Spetsifikatsioon ei määratle nimetatud olekuid, kuid väljastaja algatatud voogu, kus tunnistus väljastatakse kohe, on kõige lihtsam jälgida allpool oleva jadana. Iga samm võib ebaõnnestuda omal moel ja rahakoti rakendus peab käsitlema neid teid, mitte ainult õnnelikku teed.

Pakkumine loodud
QR-kood või link avab rahakoti
Pakkumine vastu võetud
grant lunastatud
Token saadud
nonce ja valduse tõend
Tunnistust taotletud
tunnistus loodud
Tunnistus väljastatud
rahakott valideerib ja salvestab
Tunnistus vastu võetud
Kus võib ebaõnnestuda, sammude täitmise järjekorras:
Kood aegus enne lunastamist
Tokeni taotlus tagasi lükatud
Tunnistuse taotlus tagasi lükatud
Tunnistust ei salvestatud

Läbitöötatud näide: sõidukite tehnoülevaatuse tunnistus veoettevõttele

Sõidukite ülevaatuse asutus väljastab tehnoülevaatuse tunnistuse veoettevõtte ärirahakotti pärast tavapärast ülevaatust. Ülevaataja oli sõidukipargi juhi ülevaatuspunktis juba autentinud, seega kasutab väljastaja eelautoriseeritud koodi voogu. Alltoodud sammud järgivad seda ühte väljastamist pakkumisest vastuvõetud tunnistuseni.

Näide kirjeldab OpenID4VCI põhiversiooni. Kõrge kindlustatuse juurutused, nagu EUDI Wallet, kasutavad selle peal HAIP profiili, mis lisab DPoP-iga seotud juurdepääsutokenid, rahakoti atesteerimise tokeni lõpp-punktis ja tunnistuse võtmete atesteerimise. Need on siin selguse huvides välja jäetud.

1. Tunnistuse pakkumine

Ülevaatusasutuse terminal kuvab QR-koodi. See sisaldab URI-t, mis algab openid-credential-offer://, ja mis kannab allpool olevat pakkumist URL-kodeerituna credential_offer parameetris, või credential_offer_uri väärtust, millelt rahakott selle toob. Rahakott skannib koodi ja loeb, milline tunnistus on pakkumisel ning kuidas seda saada.

Väljastaja

Kuvab QR-koodi koos Credential Offer'iga

Nimetab tunnistuse konfiguratsiooni ja pre-authorized_code granti

{
  "credential_issuer": "https://issuer.fleetinspect.example",
  "credential_configuration_ids": ["roadworthiness_certificate"],
  "grants": {
    "urn:ietf:params:oauth:grant-type:pre-authorized_code": {
      "pre-authorized_code": "fi-8f2c0b3a",
      "tx_code": {
        "length": 6,
        "input_mode": "numeric",
        "description": "Enter the code sent to your phone by text message"
      }
    }
  }
}

2. Väljastaja metaandmete avastamine

Enne mistahes taotlemist toob rahakott väljastaja metaandmed, et teada saada, mida roadworthiness_certificate sisaldab ja milliseid lõpp-punkte kutsuda. Metaandmed ei loetle eraldi autoriseerimisservereid, seega on väljastaja ise oma autoriseerimisserver ning rahakott loeb tokeni lõpp-punkti selle serveri metaandmetest.

Rahakott

GET /.well-known/openid-credential-issuer

Saab teada tunnistuse vormingu, väited ja aktsepteeritud tõendi tüübid, samuti nonce, tunnistuse, edasilükkamise ja teavituse lõpp-punktid

Tunnistuse väljastaja metaandmed (väljavõte)

{
  "credential_issuer": "https://issuer.fleetinspect.example",
  "nonce_endpoint": "https://issuer.fleetinspect.example/nonce",
  "credential_endpoint": "https://issuer.fleetinspect.example/credential",
  "deferred_credential_endpoint": "https://issuer.fleetinspect.example/deferred",
  "notification_endpoint": "https://issuer.fleetinspect.example/notify",
  "credential_configurations_supported": {
    "roadworthiness_certificate": {
      "format": "dc+sd-jwt",
      "vct": "https://fleetinspect.example/vct/roadworthiness",
      "cryptographic_binding_methods_supported": ["jwk"],
      "credential_signing_alg_values_supported": ["ES256"],
      "proof_types_supported": {
        "jwt": { "proof_signing_alg_values_supported": ["ES256"] }
      },
      "credential_metadata": {
        "claims": [
          { "path": ["vehicle_registration"] },
          { "path": ["inspection_result"] },
          { "path": ["valid_until"] }
        ]
      }
    }
  }
}

Autoriseerimisserveri metaandmed (väljavõte), lehelt /.well-known/oauth-authorization-server

{
  "issuer": "https://issuer.fleetinspect.example",
  "token_endpoint": "https://issuer.fleetinspect.example/token",
  "pre-authorized_grant_anonymous_access_supported": true
}

3. Tokeni taotlus

Rahakott lunastab eelautoriseeritud koodi tokeni lõpp-punktis koos tehingukoodiga, mille ülevaatusasutus saatis sõidukipargi juhi telefonile. Selle koodi saatmine teise kanali kaudu tähendab, et keegi, kes pildistab QR-koodi õla tagant, ei saa seda ikkagi lunastada.

Rahakott

POST /token

Saadab pre-authorized_code ja tx_code, saab juurdepääsutokeni, mis kehtib ainult selle pakkumise kohta

POST /token HTTP/1.1
Host: issuer.fleetinspect.example
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:pre-authorized_code
&pre-authorized_code=fi-8f2c0b3a
&tx_code=482913

Vastus

{
  "access_token": "fi-at-3d91e0",
  "token_type": "Bearer",
  "expires_in": 86400
}

4. Valduse tõend

Kuna metaandmed loetlevad nonce_endpoint'i, toob rahakott sealt kõigepealt värske c_nonce. Seejärel tõendab ta, et omab privaatvõtit, millega tunnistus seotakse, allkirjastades proof JWT väljastaja identifikaatori ja selle c_nonce peale.

Rahakott

POST /nonce, seejärel allkirjastab proof JWT võtmega, millega tunnistus seotakse

Seob tunnistuse selle võtmega, mitte ainult juurdepääsutokeni omanikuga

POST /nonce HTTP/1.1
Host: issuer.fleetinspect.example

Vastus

{
  "c_nonce": "fi-nonce-77aa"
}

Rahakott ehitab nüüd proof JWT kahest JSON-objektist, päisest ja sisust, ning allkirjastab need privaatvõtmega, millega tunnistus seotakse.

Päis: mis see JWT on ja milline võti selle allkirjastas

{
  "typ": "openid4vci-proof+jwt",
  "alg": "ES256",
  "jwk": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." }
}
  • typ: märgib selle OpenID4VCI võtme tõendiks, nii et seda ei saa segi ajada ühegi muu JWT liigiga
  • alg: allkirjastamisalgoritm, üks neist, mille väljastaja loetles proof_signing_alg_values_supported väärtuses
  • jwk: avalik võti, millega tunnistus seotakse; väljastaja kontrollib allkirja selle põhjal

Sisu: kelle jaoks tõend on ja millal see loodi

{
  "aud": "https://issuer.fleetinspect.example",
  "iat": 1789376400,
  "nonce": "fi-nonce-77aa"
}
  • aud: väljastaja identifikaator, nii et tõendit ei saa teise väljastaja juures uuesti kasutada
  • iat: tõendi loomise aeg, sekundites alates 1970. aastast
  • nonce: nonce lõpp-punktist saadud c_nonce, mis näitab, et tõend on värske

Allkirjastatud tulemus

Päis ja sisu on mõlemad base64url-kodeeritud ja ühendatud punktiga. Rahakott allkirjastab selle stringi oma privaatvõtmega ja lisab base64url-kodeeritud allkirja pärast teist punkti. Tulemuseks olev string on proof JWT, mille rahakott saadab tunnistuse taotluses sammus 5.

base64url(header) . base64url(payload) . base64url(signature)

eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIs...
  .eyJhdWQiOiJodHRwczovL2lzc3Vlci5mbGVldGluc3BlY3QuZXhhbXBsZSIs...
  .<ES256 signature>

5. Tunnistuse taotlus

Rahakott kutsub tunnistuse lõpp-punkti koos juurdepääsutokeni ja tõendiga ning väljastaja loob ja tagastab allkirjastatud tunnistuse.

Rahakott

POST /credential

Saadab juurdepääsutokeni, konfiguratsiooni ID ja proof JWT, saab allkirjastatud tunnistuse ja notification_id

POST /credential HTTP/1.1
Host: issuer.fleetinspect.example
Content-Type: application/json
Authorization: Bearer fi-at-3d91e0

{
  "credential_configuration_id": "roadworthiness_certificate",
  "proofs": {
    "jwt": ["<proof JWT from step 4>"]
  }
}

Vastus

{
  "credentials": [
    { "credential": "<issuer-signed SD-JWT VC>" }
  ],
  "notification_id": "fi-notif-9012"
}

Kogu voog ühe pilguga

See jadadiagramm ühendab näite viis sammu tervikuks, pakkumisest teavituseni. Pidevad nooled on taotlused, katkendlikud nooled on vastused ning punktiirnool on tehingukood, mis liigub protokollivälisel teel SMS-sõnumina.

Rahakott

Veoettevõtte ärirahakott

Autoriseerimisserver

Selles näites käitab väljastaja ise

Tunnistuse väljastaja

Sõidukite ülevaatuse asutus

  1. Tunnistuse väljastaja juurde Rahakott: Credential Offer, kuvatud QR-koodina
  2. Tunnistuse väljastaja juurde Rahakott: tx_code, saadetud SMS-iga sõidukipargi juhi telefonile
  3. Rahakott juurde Tunnistuse väljastaja: GET /.well-known/openid-credential-issuer
  4. Tunnistuse väljastaja juurde Rahakott: tunnistuse väljastaja metaandmed
  5. Rahakott juurde Autoriseerimisserver: GET /.well-known/oauth-authorization-server
  6. Autoriseerimisserver juurde Rahakott: autoriseerimisserveri metaandmed
  7. Rahakott juurde Autoriseerimisserver: POST /token: pre-authorized_code, tx_code
  8. Autoriseerimisserver juurde Rahakott: access_token
  9. Rahakott juurde Tunnistuse väljastaja: POST /nonce
  10. Tunnistuse väljastaja juurde Rahakott: c_nonce
  11. Rahakott: allkirjastab proof JWT
  12. Rahakott juurde Tunnistuse väljastaja: POST /credential: juurdepääsutoken, tõendid
  13. Tunnistuse väljastaja juurde Rahakott: credentials, notification_id
  14. Rahakott: valideerib ja salvestab
  15. Rahakott juurde Tunnistuse väljastaja: POST /notify: credential_accepted
  16. Tunnistuse väljastaja juurde Rahakott: 204 No Content

Kui tunnistus pole veel valmis: edasilükatud väljastamine

Ülaltoodud näide eeldab, et ülevaatuse tulemus on juba lõplik. Kui ülevaatusasutus peab hoopis eskaleerima piiripealse tulemuse vanemülevaatajale, ei saa tunnistuse lõpp-punkt tunnistust kohe tagastada, seega lükkab ta väljastamise edasi.

Viivitamatu väljastamine

Tunnistuse lõpp-punkt tagastab allkirjastatud tunnistuse samas vastuses kui taotlus.

Edasilükatud väljastamine

Tunnistuse lõpp-punkt vastab HTTP 202, transaction_id ja intervalliga tunnistuse asemel. Rahakott küsitleb deferred_credential_endpoint'i selle ID-ga, oodates taotluste vahel vähemalt intervalliga määratud arvu sekundeid, kuni tunnistus on valmis.

transaction_iddeferred_credential_endpoint'i küsitlemine

Edasilükatud vastus /credential'ist

HTTP/1.1 202 Accepted
Content-Type: application/json

{
  "transaction_id": "fi-tx-55c2",
  "interval": 900
}

/deferred küsitlemine, kuni see on valmis

POST /deferred HTTP/1.1
Host: issuer.fleetinspect.example
Content-Type: application/json
Authorization: Bearer fi-at-3d91e0

{ "transaction_id": "fi-tx-55c2" }

// While the review is open: 202 with the same transaction_id and interval.
// Once approved: 200 with the credentials, optionally with a notification_id.
// If the review rejects the result: a credential_request_denied error.

Ringi sulgemine: teavituse lõpp-punkt

Pärast väljastamist saab rahakott väljastajale öelda, mis tunnistusega juhtus, kasutades tunnistuse vastusest saadud notification_id'd. Rahakotid ei ole kohustatud neid teavitusi saatma ja kohaletoimetamine ei ole tagatud, seega ei saa väljastaja puuduva teavituse põhjal midagi järeldada.

Rahakott

Saadab sündmuse väljastaja notification_endpoint'ile saadud notification_id kohta, mis hõlmab kõiki selles vastuses olevaid tunnistusi

credential_accepted

Salvestatud rahakotti

credential_failure

Väljastamine ebaõnnestus mõnel muul põhjusel, näiteks tunnistus ei läbinud valideerimist

credential_deleted

Väljastamine ebaõnnestus hoidja tõttu, näiteks keeldus ta seda salvestamast

POST /notify HTTP/1.1
Host: issuer.fleetinspect.example
Content-Type: application/json
Authorization: Bearer fi-at-3d91e0

{
  "notification_id": "fi-notif-9012",
  "event": "credential_accepted"
}

Seotud mõisted

Korduma kippuvad küsimused

Kuidas rahakott teab, millist granti tüüpi kasutada?

Credential Offer nimetab granti oma grants-objektis. authorization_code on olemas, kui väljastaja soovib, et hoidja logiks voo osana sisse. pre-authorized_code on olemas, kui hoidja oli juba autenditud kanalil, kus pakkumine loodi, näiteks alltoodud näites ülevaataja poolt ülevaatuspunktis. Pakkumine võib loetleda mõlemad ja rahakott valib siis ühe. Kui pakkumisel pole grants-objekti üldse, otsib rahakott metaandmetest, milliseid granditüüpe autoriseerimisserver toetab.

Miks rahakott toob väljastaja metaandmed enne mistahes taotlemist?

Credential Offer nimetab ainult credential_configuration_ids väärtused, väljastaja URL-i ja grants. Väljastaja metaandmed, mida pakutakse tuntud tee kaudu, kirjeldavad iga konfiguratsiooni: selle vormingut, väiteid ja aktsepteeritud tõendi tüüpe, samuti nonce, tunnistuse, edasilükkamise ja teavituse lõpp-punkte. Need näitavad ka, millist autoriseerimisserverit kasutada, ja selle serveri enda metaandmed annavad tokeni lõpp-punkti. Ilma mõlemata ei teaks rahakott, kuidas ehitada kehtivaid taotlusi ega mida hoidjale enne nõusoleku andmist näidata.

Mida valduse tõend tegelikult tõendab?

See tõendab, et tunnistust taotlev rahakott omab privaatvõtit, millega tunnistus seotakse, mitte ainult seda, et tal on kehtiv juurdepääsutoken. Rahakott allkirjastab proof JWT väljastaja identifikaatori ja väljastaja nonce lõpp-punktist saadud värske c_nonce peale, kasutades seda võtit. Väljastaja lisab vastava avaliku võtme tunnistusse. Kontrollija, kes nõuab võtmega sidumist, palub hoidjal esitamisel uuesti sama võtmega allkirjastada, nii et kopeeritud tunnistus ilma võtmeta seda kontrolli ei läbi.

Miks väljastaja lükkaks väljastamise edasi, selle asemel et tunnistus kohe tagastada?

Mõned kontrollid, mida väljastaja teeb enne tunnistuse loomist, ei saa lõppeda ühe HTTP-taotluse jooksul, näiteks käsitsi ülevaatus või aeglase välise registri päring. Edasilükatud väljastamine võimaldab tunnistuse lõpp-punktil vastata kohe transaction_id'ga, selle asemel et ühendust blokeerida, ning rahakott küsitleb edasilükatud lõpp-punkti selle ID-ga, kuni kontroll lõpeb ja tunnistus on valmis kättesaamiseks.

Kas teavituse lõpp-punkt on väljastajale kohustuslik rakendada?

Ei. See on väljastajatele valikuline ja ka rahakotid ei ole kohustatud seda kasutama. Kui mõlemad seda toetavad, saab väljastaja teada, mis pärast väljastamist juhtus: tunnistused salvestati (credential_accepted), hoidja peatas väljastamise, näiteks keeldudes neid salvestamast (credential_deleted), või see ebaõnnestus mõnel muul põhjusel (credential_failure). Kohaletoimetamine ei ole tagatud, seega peaks väljastaja käsitlema teavitust kasuliku teabena, mitte kunagi usaldusväärse kirjena, ega tohi puuduva teavituse põhjal midagi järeldada.

Allikad

  1. OpenID for Verifiable Credential Issuance 1.0
  2. OpenID4VC High Assurance Interoperability Profile 1.0
  3. EUDI Wallet Architecture and Reference Framework

See leht on informatiivne ega kujuta endast õigusnõustamist. Ametliku juhise saamiseks pöörduge otse OpenID Foundationi ja Euroopa Komisjoni poole.

Rääkige meiega EUDI Wallet integratsioonist