Hjem  >  lommebok

Protokoll-flyt for å motta bevis

På denne sida forsøker me å forklara flyten du må følgje som brukastad når du ynskjer at innbyggeren skal presentere eit bevis til deg.

Protokollen som vert nytta heiter OpenID for Verifiable Presentations (OpenID4VP). (https://openid.github.io/OpenID4VP/openid-4-verifiable-presentations-wg-draft.html).

Sidan protokollen vert nytta av ulike økosystem over heile verda, er den ganske generell, den er til dømes heilt agnostisk både ovanfor bevisformat og tillistrammeverk. For å skape eit interoperabelt økosystem er det difor naudsynt å profilere protokollen. For EU-lommeboka skjer dette i fleire steg:

  1. OpenID4VP
  2. HAIP er ein profil utgitt av OpenID Foundation for bruksområde med høge krav til sikkerheit.
  3. ETSI 119 472-2 er den europeiske profilen som igjen bygger på HAIP.

Flyt

Sjølve flyten er enkel, og består av fylgjande steg:

  1. Brukerstaden konstruerer ein sokalla VP-request og sender denne til lommeboka.
  2. Brukaren opnar lommeboka og godkjenner presentasjon av beviset.
  3. Lommeboka sender bevis-presentasjonen (VP-response) attende til brukerstaden.
sequenceDiagram actor U as Sluttbruker participant W as Lommebok participant V as Brukersted U-->>V: interaksjon V->>W: VP-request med DCQL-query U-->>W: samtykker W->>V: vp_token

Oppsett og registrering

Alle brukerstader skal vere registrert på førehand. For sandkassen er dette skildra under registrering av brukarstad

Steg 1: Lage ein VP-request

Brukarstaden lagar ein VP-request for å fortelje kva bevis/attributt den ynskjer å motta frå lommeboka.

Du må ta stilling til fleire tema når du bygger opp VP-requesten din:

  • kva bevis-typar eller enkelt-attributter treng du ?
  • kva sikkerheitskrav og tillitsrammeverk gjeld for desse ?
  • ynskjer du at brukaren skal ta stilling til transaksjons-spesifikke data ved godkjenninga ?
  • teknisk skildring av brukarstaden din.
  • korleis ynskjer du å transportere request og respons?

Me skal sjå nærare på kvart av desse temane, men fyrst vil me berre gje eit døme på ein VP-request med dei claima som me meiner er viktigast:

{
  "typ": "oauth-authz-req+jwt",
  "alg": "ES256",
  "x5c": ["MIIDVDCC...."]
}.{
  "aud": "https://self-issued.me/v2", 
  "iss":  "https://client.example.org",
  "client_id": "x509_hash:Xxx...xxx",

  "response_uri": "https://client.example.org/post",
  "response_type": "vp_token",
  "response_mode": "direct_post.jwt",

  "dcql_query": {...},

  "transaction_data": {...},

  "client_metadata": {...},

  "nonce": "n-0S6_WzA2Mj",
  "state": "eyJhb...6-sVA"
  "jti": "0123..."

Tema 1.a: Kva data treng eg ?

Du må kjenne identifikatoren på beviset du ynskjer.

For “høgverdige” bevis som digital grunnidentitet (den sokalla “PID’en”) eller digitalt førarkort (mobile driver licence - mDL) so vil EU publisere sokalla rulebooks der bevis-typane vert definert. EU skal også bygge opp ein sentral katalog over bevis og attributter (sokalla “catalogue of attestations” og “catalogue of schemes”, ref utkast til rettsakt.

Ofte vil du vite kva verksemd som er utstedar av beviset, eller du kan finne det frå innsynstjenesten til sandkassa. Du kan då sjekke metadata-endepunktet til Credential Issueren for å finne kva bevistypar ‘ar som er støtta.

Merk at det kan vere ganske forvirrande at bevistypar i metadata er identifisert ved ein generisk credential_configuration_id , men dette er berre ein intern teknisk identifikator, den bevistype-definisjonen som du er på jakt etter heiter anten doctype eller vct.

Eit bevis kan vere utsted på 3 ulike kvalitetsnivå. Det høgaste nivået er sokalla kvalifiserte bevis (QEAA), so er det ein mellomnivå for offentleg sektor som heiter Pub-EAA, medan resten av bevisa er ikkje-kvalifiserte. På ikkje-kvalifisert nivå er det valfritt å verte registrert i dei sentrale katalogane, som betyr at du kan måtte skaffe deg kjennskap om eksistensen av slike bevis på anna måtar (til dømes via dokumentasjon).

Iallefall, når du kjenner type-identifikatoren på beviset, kan du konstruere den tilhøyrande DQCL-spørringa. Merk at du brukar bevistypen-identifikatoren som ein referanse i meta delen av DCQL-spørringa, og ikkje i id-claimet.

Enkel døme på DCQL-query som ber om mobilt førarkort i mdoc-format:

"dcql_query" = {
  "credentials": [
    {
      "id": "førarkort",
      "format": "mso_mdoc",
      "meta": { "doctype_value": "org.iso.18013.5.1.mDL" }
    }]}

Døme på aldersverifisering med ein samansett spørring, der anten mobilt førarkort eller PID kan nyttast som datagrunnlag:

"dcql_query" = {
  "credentials": [
    {
      "id": "mdl",
      "format": "mso_mdoc",
      "meta": {
        "doctype_value": "org.iso.18013.5.1.mDL"
      },
      "claims": [  {"id": "age_over_18", "path": ["org.iso.18013.5.1", "age_over_18"] }      ]
    },{
      "id": "pid",
      "format": "dc+sd-jwt",
      "meta": {
        "vct_values": "urn:eudi:pid:1"
      },
      "claims": [ {"id": "age_over_18", "path": ["age_equal_or_over", "18"]  }  ]
    }
  ],
  "credential_sets": [
    { "options": [ "mdl", "pid"] }
  ] }

Sjå døme i spec’en for meir inspirasjon.

Tema 1.b: Sikkerheitskrav / rammeverk

Dette vil avhenge av kva økosystem du brukar. For EU-lommebok er det primært bruk av X.509-baserte PKIar som gjeld.

På ikkje-kvalifisert sikkerheitsnivå er det derimot tillatt med alternative tillitsrammeverk, men me kjenner per nå ikkje til korleis dette skal kunne byggast.

Tema 1.c: Transaksjonsspesifikke data

Spec’en opnar for at brukaren skal kunne ta samtykke til transaksjonsspesifikke data som ikkje er del av eit bevis. Transaksjonsdataene blir då signert av lommeboka, medan beviset som vanleg er signert av utstedaren. Dei transaksjonsspesifikke detaljane lyt inkluderast i førespurnaden i claimet transaction_data, og det vil vere ein type som definerer ein tilhøyrande datamodell.

Døme på eit tenkt tilfelle der norsk banksektor har blitt samde om ein type og tilhøyrande bevistype som mogeleggjer betaling av mindre beløp i kiosk:

"transaction_data": {
  "type": "kiosksalg",
  "credential_ids": [ "urn:no:smaa_betaling_bevis"],
  "vare":  "1 pølse i brød",
  "beløp": 45
}

Tema 1.d: Skildre brukerstaden din

VP-spec’en bygger på Oauth2, der brukstaden opptrer som oauth-klient, og lommeboka spelar rolla som autorisasjonsserver. Ulikt Oauth2 so skal dei tekniske eigenskapane til brukarstaden ikkje registrerast på førehand, men må derimot verte overført runtime som del av VP-requesten i claimet client_metadata. Gjennom å signere VP-requesten med tilgangssertifikatet (RPAC) so kan lommeboka ha tiltru til at klient-metadata er rette.

vp_formats_supported er eit viktig metadata som er lurt å sende for hjelpe lommeboka til å velge rett format på bevisa.

Ein annan viktig skilnad til Oauth2, er at client_id er bygd opp på ein spesiell måte med bruk av prefixar foran eit kolon (:)

  • x509_hash
  • x509_san_dns
  • redirect_uri
  • openid-federation
  • decentralized_identifier
  • verifier_attestation

Prefixa fortel kva type tillitsprotokollar som vert nytta av ulike økosystem. For EU-lommeboka, iallefall for grensekryssande bruk, trur med at det vil verte den første, x509_hash, som blir mest aktuell å bruka. Dette sidan tilgangssertifikata (RPAC) skal vere utstedt av ein Access Certificate Authority som skal plasserast på ein Trust List. Ref. ARF 3.18, og det ser ut som tradisjonelle PKIar basert på x.509 og ETSI-baserte trustlister er det som EU-kommisjonen legg opp til. Digdir har dog lyst å sjå på bruk av openid-federation nasjonalt, ta gjerne kontakt med oss for å vere med på utprøving av dette.

nonce blir normalt brukt til å linke request og respons. Men dersom brukarsteden ikkje ynkjer holder binding, må state nyttast til dette istaden.

Tema 1.e: Transport: korleis du vil sende VP-requesten ?

Ein VP-førespurnad er ein modifisert OpenID-connect autorisasjonsførespurnad. Brukarstaden er vanlegvis ei browserbasert web-teneste, og den vil normalt rendre VP-requesten som ein QR-kode, som brukaren so anten scanner med lommeboka (cross-device) eller lommeboka vert opna direkte (same-device).

Sidan VP-requestar fort kan bli store risikerer du også at QR-kodane kan bli vanskeleg å lese. Det er difor mogeleg å sende ein VP-request på ulike måtar til lommeboka:

  1. Redirect: Her lagar du ein komplett VP-request basert på query-parametre, som du så redirecter direkte til lommeboka.
  2. Request Object via redirect: Som over, men du pakkar requesten inn i ein JWT slik at den blir eit Request Object ihht RFC9101
  3. Referert Request Object via GET: Du lagar VP-requesten som ein JWT og tilgjengleggjer på ein unik url, og ber lommeboka om å laste den ned derifrå.
  4. Referert Request Object via POST: Som #3, men her kan lommeboka samstundes POSTe inn sine tekniske kapabiliteter, som mogeleggjer at du synkront kan laga ein tilpassa VP-request.

Alternativ #1 er det enklaste å realisere, medan alternativ #4 nok er det mest robuste. Merk at ikkje alle lommebøker er påkrevd å støtte POST, så om du går for #4, må du vurdere å implementere #3 som fallback.

Det er også mogeleg å sende requesten over det nye W3C Digital Credentials APIet som vil gje betre brukaropplevelse, spesielt i cross-device brukstilfelle eller scenario der brukaren har fleire lommebok-appar innstallert på telefonen, men her er det førebels veldig lav støtte i browsere for denne protokollen. Sjå Appendix A i OpenID4VP for detaljar.

Alternativ Kva parametre styrer oppførsel?
#1: Direkte redirect (ingen)
#2: Request Object via redirect request=<jwt>
#3: Referert Request Object via GET request_uri=https://verifier.example.com/request_objects/1234-1234-1234-1234
#4: Referert Request Object via POST request_uri_method=POST&request_uri=https://verifier.example.com/request_objects/1234-1234-1234-1234

Steg 1.f: Transport: kvar vil du ha responsen tilbake frå lommeboka ?

Reponsen frå lommeboka er ein ny type token, det sokalla vp_token-et. Sjå meir om dette nedanfor.

Sidan VP-spec’en bygger på Oauth2, har du også fleire valg for korleis du ynskje å motta VP-responsen frå lommeboka:

  1. Redirect: Lommeboka redirecter vp_tokenet attende til deg gjennom nettlesar som eit fragment på oppgitt redirect_uri.
  2. direct_post: Lommeboka POSTer vp_tokenet til oppgitt response_uri. Deretter må du instruere lommeboka kvar den skal redirekte brukaren vidare frå lommebok til brukarstaden i nettlesaren.
Alternativ Kva parametre styrer oppførsel?
#1: Redirect reponse_type=vp_token&response_mode=fragment
#2: direct_post reponse_type=vp_token&response_mode=direct_post

Døme på bruk av direct.post:

#1: lommeboka postar responsen
POST https://verifier.example.com/post HTTP/1.1

  vp_token=...&
  state=eyJhb...6-sVA

#2: verifier svarar med redirect-uri:
HTTP/1.1 200 OK

{
  "redirect_uri": "https://verifier.example.org/cb#response_code=091535f699ea575c7937fa5f0f454aee"
}

#3: lommeboka hoppar over til nettlesar og sender brukaren til oppgjeve redirect_uri

Det er også mogeleg å få responsen kryptert, då brukar du ein variant som heiter `direct_post.jwt.

Sidan VP-specen er basert på Oauth2 er det teoretisk mogeleg for ein brukastad å førespørje ein kombinasjon av vp_tokenet med å motta id_token og access_token, men dette virkar lite hensiktsmessig.

Steg 2: Validere vp_token

Når brukaren har samtykka til deling av bevis, og evt. transaksjonsdata, og send tilbake responsen slik som du spesifiserte i VP-requesten, so vil du til slutt ende opp med eit vp_token.

vp_tokenet inneheld dei bevisa du ba om, til dømes slik:

{
  "førarkort": ["eyJhbGci...QMA"]
}

Du må validere at vp_tokenet er korrekt. Aktuelle valideringspunkt:

  • validere WUA slik at du veit responsen kjem frå ei anerkjend lommebok
  • validere signeringssertifikat på beviset (for kvart bevis)
  • validere signatur på beviset (for kvart bevis)
  • sjekke bevis-katalog om utstedaren har lov til å utstede bevis av denne type
  • validere holder binding ?

Sjå også kap 8.6 i VP-specen for valideringskrav.