Vydávání pověření OpenID4VCI vysvětleno: od nabídky k přijatému pověření
OpenID4VCI, OpenID for Verifiable Credential Issuance, definuje, jak peněženka žádá o pověření od vydavatele a jak jej získává. Jedno vydání prochází několika odlišnými kroky, než peněženka skutečně získá použitelné pověření, a každý z nich má svůj vlastní způsob selhání. Tato stránka prochází celý tento životní cyklus, s původními názornými příklady.
Dva způsoby zahájení: předautorizovaný kód a autorizační kód
Vydávání často začíná od Credential Offer zaslané vydavatelem, a grant, který uvádí, rozhoduje o tom, jak bude peněženka autorizována. Peněženka může vydávání zahájit i sama, bez jakékoli nabídky, pomocí toku s autorizačním kódem. Oba toky končí na stejném místě: peněženka má přístupový token, který může použít k vyžádání pověření.
Tok s předautorizovaným kódem
1. Vydavatel
Již zná držitele, vydá Credential Offer s pre-authorized_code
2. Peněženka
Uplatní kód na tokenovém endpointu, volitelně s transakčním kódem
3. Peněženka
Požádá o pověření s důkazem držení svého klíče
Tok s autorizačním kódem
1. Peněženka
Naskenuje Credential Offer, která uvádí grant authorization_code, nebo zahájí tok sama bez nabídky
2. Autorizační server
Provede držitele přihlášením a souhlasem, poté vydá kód
3. Peněženka
Vymění kód za token a poté požádá o pověření
Celý životní cyklus nabídky pověření
Specifikace nedefinuje pojmenované stavy, ale tok zahájený vydavatelem, ve kterém je pověření vydáno rovnou, se nejsnáze sleduje jako sekvence níže. Každý krok může selhat svým vlastním způsobem a implementace peněženky musí zvládnout i tyto cesty, nejen tu úspěšnou.
Názorný příklad: osvědčení o technické způsobilosti pro dopravní flotilu
Stanice technické kontroly vozidel vydá osvědčení o technické způsobilosti do firemní peněženky dopravní společnosti po rutinní kontrole. Inspektor už vedoucího vozového parku ověřil na místě kontroly, takže vydavatel použije tok s předautorizovaným kódem. Následující kroky sledují toto jediné vydání od nabídky až po přijaté pověření.
Příklad ukazuje základní OpenID4VCI. Nasazení s vysokou úrovní záruky, jako je EUDI Wallet, na něm staví profil HAIP, který přidává přístupové tokeny vázané na DPoP, atestaci peněženky na tokenovém endpointu a atestaci klíčů pro klíče pověření. Ty jsou zde kvůli srozumitelnosti každého kroku vynechány.
1. Nabídka pověření
Terminál stanice technické kontroly zobrazí QR kód. Obsahuje URI začínající openid-credential-offer://, který nese níže uvedenou nabídku zakódovanou v URL v parametru credential_offer, nebo credential_offer_uri, ze kterého si ji peněženka stáhne. Peněženka kód naskenuje a přečte, jaké pověření je nabízeno a jak jej získat.
Vydavatel
Zobrazí QR kód s Credential Offer
Uvádí konfiguraci pověření a grant pre-authorized_code
{
"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. Zjišťování metadat vydavatele
Než o cokoli požádá, peněženka si stáhne metadata vydavatele, aby zjistila, co obsahuje roadworthiness_certificate a jaké endpointy volat. Metadata neuvádí žádné samostatné autorizační servery, takže vydavatel je svým vlastním autorizačním serverem, a peněženka si tokenový endpoint přečte z metadat tohoto serveru.
Peněženka
GET /.well-known/openid-credential-issuer
Zjistí formát pověření, tvrzení a přijímané typy důkazů, a také endpointy pro nonce, pověření, odložení a notifikace
Metadata vydavatele pověření (výňatek)
{
"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"] }
]
}
}
}
}Metadata autorizačního serveru (výňatek), z /.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. Žádost o token
Peněženka uplatní předautorizovaný kód na tokenovém endpointu spolu s transakčním kódem, který stanice technické kontroly zaslala na telefon vedoucího vozového parku. Odeslání tohoto kódu druhým kanálem znamená, že ten, kdo vyfotí QR kód přes rameno, jej stále nemůže uplatnit.
Peněženka
POST /token
Odešle pre-authorized_code a tx_code, obdrží přístupový token omezený na tuto nabídku
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
Odpověď
{
"access_token": "fi-at-3d91e0",
"token_type": "Bearer",
"expires_in": 86400
}4. Důkaz držení
Protože metadata uvádějí nonce_endpoint, peněženka si odtud nejprve stáhne čerstvý c_nonce. Poté dokáže, že vlastní soukromý klíč, ke kterému bude pověření vázáno, tím, že podepíše proof JWT nad identifikátorem vydavatele a tímto c_nonce.
Peněženka
POST /nonce, poté podepíše proof JWT klíčem, ke kterému bude pověření vázáno
Váže pověření k tomuto klíči, nikoli pouze k tomu, kdo drží přístupový token
POST /nonce HTTP/1.1 Host: issuer.fleetinspect.example
Odpověď
{
"c_nonce": "fi-nonce-77aa"
}Peněženka nyní sestaví proof JWT ze dvou JSON objektů, hlavičky a payloadu, a podepíše je soukromým klíčem, ke kterému bude pověření vázáno.
Hlavička: co tento JWT je a jaký klíč jej podepsal
{
"typ": "openid4vci-proof+jwt",
"alg": "ES256",
"jwk": { "kty": "EC", "crv": "P-256", "x": "...", "y": "..." }
}typ: označuje toto jako důkaz klíče OpenID4VCI, takže jej nelze zaměnit s jiným typem JWTalg: podpisový algoritmus, jeden z těch, které vydavatel uvedl v proof_signing_alg_values_supportedjwk: veřejný klíč, ke kterému bude pověření vázáno; vydavatel proti němu ověřuje podpis
Payload: pro koho je důkaz určen a kdy vznikl
{
"aud": "https://issuer.fleetinspect.example",
"iat": 1789376400,
"nonce": "fi-nonce-77aa"
}aud: identifikátor vydavatele, díky kterému nelze důkaz přehrát u jiného vydavateleiat: čas vytvoření důkazu, v sekundách od roku 1970nonce: c_nonce z nonce endpointu, který ukazuje, že důkaz je čerstvý
Podepsaný výsledek
Hlavička a payload jsou každý zakódovány v base64url a spojeny tečkou. Peněženka tento řetězec podepíše svým soukromým klíčem a připojí za druhou tečku podpis zakódovaný v base64url. Výsledný řetězec je proof JWT, který peněženka odesílá v žádosti o pověření v kroku 5.
base64url(header) . base64url(payload) . base64url(signature) eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIs... .eyJhdWQiOiJodHRwczovL2lzc3Vlci5mbGVldGluc3BlY3QuZXhhbXBsZSIs... .<ES256 signature>
5. Žádost o pověření
Peněženka volá endpoint pověření s přístupovým tokenem a důkazem, a vydavatel vytvoří a vrátí podepsané pověření.
Peněženka
POST /credential
Odešle přístupový token, identifikátor konfigurace a proof JWT, obdrží podepsané pověření a 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>"]
}
}Odpověď
{
"credentials": [
{ "credential": "<issuer-signed SD-JWT VC>" }
],
"notification_id": "fi-notif-9012"
}Celý tok na jeden pohled
Tento sekvenční diagram spojuje pět kroků názorného příkladu dohromady, od nabídky až po notifikaci. Plné šipky jsou požadavky, přerušované šipky jsou odpovědi a tečkovaná šipka je transakční kód putující mimo protokol formou textové zprávy.
Peněženka
Firemní peněženka dopravní společnosti
Autorizační server
V tomto příkladu provozovaný samotným vydavatelem
Vydavatel pověření
Stanice technické kontroly vozidel
- Vydavatel pověření komu Peněženka: Credential Offer, zobrazená jako QR kód
- Vydavatel pověření komu Peněženka: tx_code, zaslaný SMS zprávou na telefon vedoucího vozového parku
- Peněženka komu Vydavatel pověření: GET /.well-known/openid-credential-issuer
- Vydavatel pověření komu Peněženka: metadata vydavatele pověření
- Peněženka komu Autorizační server: GET /.well-known/oauth-authorization-server
- Autorizační server komu Peněženka: metadata autorizačního serveru
- Peněženka komu Autorizační server: POST /token: pre-authorized_code, tx_code
- Autorizační server komu Peněženka: access_token
- Peněženka komu Vydavatel pověření: POST /nonce
- Vydavatel pověření komu Peněženka: c_nonce
- Peněženka: podepisuje proof JWT
- Peněženka komu Vydavatel pověření: POST /credential: přístupový token, důkazy
- Vydavatel pověření komu Peněženka: credentials, notification_id
- Peněženka: ověří a uloží
- Peněženka komu Vydavatel pověření: POST /notify: credential_accepted
- Vydavatel pověření komu Peněženka: 204 No Content
Když pověření ještě není připraveno: odložené vydání
Výše uvedený příklad předpokládá, že výsledek kontroly je již konečný. Pokud musí stanice technické kontroly místo toho eskalovat hraniční výsledek na staršího inspektora, endpoint pověření nemůže pověření vrátit hned, takže vydání odloží.
Okamžité vydání
Endpoint pověření vrátí podepsané pověření ve stejné odpovědi jako požadavek.
Odložené vydání
Endpoint pověření odpoví kódem HTTP 202, hodnotou transaction_id a intervalem místo pověření. Peněženka dotazuje deferred_credential_endpoint s tímto ID a čeká mezi požadavky alespoň tolik sekund, kolik udává interval, dokud pověření není připraveno.
Odložená odpověď z /credential
HTTP/1.1 202 Accepted
Content-Type: application/json
{
"transaction_id": "fi-tx-55c2",
"interval": 900
}Dotazování /deferred, dokud není připraveno
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.Uzavření smyčky: notifikační endpoint
Po vydání může peněženka vydavateli sdělit, co se s pověřením stalo, pomocí notification_id z odpovědi na pověření. Peněženky nejsou povinny tyto notifikace odesílat a doručení není zaručeno, takže vydavatel nesmí chybějící notifikaci nijak interpretovat.
Peněženka
Odešle událost na notification_endpoint vydavatele pro přijaté notification_id, které pokrývá každé pověření v dané odpovědi
Uloženo v peněžence
Vydání selhalo z jiného důvodu, například pověření neprošlo validací
Vydání selhalo kvůli držiteli, například odmítl pověření uložit
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"
}Související pojmy
Často kladené otázky
Jak peněženka pozná, jaký typ grantu má použít?
Credential Offer uvádí grant ve svém objektu grants. authorization_code je přítomen, pokud vydavatel chce, aby se držitel v rámci toku přihlásil. pre-authorized_code je přítomen, pokud byl držitel již ověřen na kanálu, kde nabídka vznikla, například inspektorem na místě kontroly v následujícím příkladu. Nabídka může uvádět oba a peněženka si pak jeden vybere. Pokud nabídka nemá objekt grants vůbec, peněženka vyhledá v metadatech, jaké typy grantů autorizační server podporuje.
Proč si peněženka stahuje metadata vydavatele dřív, než o cokoli požádá?
Credential Offer uvádí pouze credential_configuration_ids, URL adresu vydavatele a grants. Metadata vydavatele, poskytovaná na dobře známé cestě, popisují každou konfiguraci: její formát, tvrzení a přijímané typy důkazů, a také endpointy pro nonce, pověření, odložení a notifikace. Uvádí také, který autorizační server použít, a metadata tohoto serveru poskytují tokenový endpoint. Bez obojího by peněženka nevěděla, jak sestavit platné požadavky ani co ukázat držiteli před udělením souhlasu.
Co důkaz držení vlastně dokazuje?
Dokazuje, že peněženka žádající o pověření vlastní soukromý klíč, ke kterému bude pověření vázáno, nikoli pouze to, že má platný přístupový token. Peněženka podepíše proof JWT nad identifikátorem vydavatele a čerstvým c_nonce z nonce endpointu vydavatele pomocí tohoto klíče. Vydavatel vloží odpovídající veřejný klíč do pověření. Ověřovatel, který vyžaduje vázání na klíč, požádá držitele, aby při předložení znovu podepsal stejným klíčem, takže zkopírované pověření bez klíče touto kontrolou neprojde.
Proč by vydavatel odkládal vydání místo toho, aby pověření vrátil hned?
Některé kontroly, které vydavatel provádí před vytvořením pověření, se nemohou dokončit v rámci jediného HTTP požadavku, například ruční přezkum nebo dotaz na pomalý externí registr. Odložené vydání umožňuje endpointu pověření odpovědět okamžitě hodnotou transaction_id místo blokování spojení, a peněženka dotazuje odložený endpoint s tímto ID, dokud kontrola neskončí a pověření není připraveno k vyzvednutí.
Je notifikační endpoint pro vydavatele povinný k implementaci?
Ne. Pro vydavatele je volitelný a peněženky jej rovněž nemusí používat. Pokud jej podporují obě strany, vydavatel se dozví, co se stalo po vydání: pověření byla uložena (credential_accepted), držitel vydání zastavil, například odmítnutím jejich uložení (credential_deleted), nebo selhalo z jiného důvodu (credential_failure). Doručení není zaručeno, takže by vydavatel měl notifikaci považovat za užitečnou informaci, nikdy za spolehlivý záznam, a z chybějící notifikace nesmí nic vyvozovat.
Zdroje
Tato stránka má informativní charakter a nepředstavuje právní poradenství. Pro závazné poučení se obraťte přímo na OpenID Foundation a Evropskou komisi.