| openid-4-verifiable-credential-issuance | September 2022 | |
| Lodderstedt, et al. | Standards Track | [Page] |
This specification defines an API and corresponding OAuth 2.0-based authorization mechanisms for the issuance of verifiable Credentials.¶
This specification defines an API designated as Credential Endpoint and corresponding OAuth 2.0-based authorization mechanisms (see [RFC6749]) for the issuance of verifiable Credentials, supporting W3C formats as well as other Credential formats. This allows existing OAuth 2.0 deployments and OpenID Connect OPs (see [OpenID.Core]) to extend their service and become Credential issuers. It also allows new applications built using Verifiable Credentials to utilize OAuth 2.0 as integration and interoperability layer.¶
Verifiable Credentials are very similar to identity assertions, like ID Tokens in OpenID Connect, in that they allow an Issuer to assert End-User claims. However, in contrast to the identity assertions, a verifiable Credential follows a pre-defined schema (the Credential type) and is typically bound to key material allowing the End-User to prove the legitimate possession of the Credential. This allows secure direct presentation of the Credential from the End-User to the RP, without involvement of the Credential issuer. This specification caters for those differences.¶
Credential¶
A set of one or more claims made by an issuer (see [VC_DATA]). Note that this definition differs from that in [OpenID.Core].¶
Verifiable Credential (VC)¶
A verifiable Credential is a tamper-evident Credential that has authorship that can be cryptographically verified. Verifiable Credentials can be used to build verifiable presentations, which can also be cryptographically verified (see [VC_DATA]).¶
Presentation¶
Data derived from one or more verifiable Credentials, issued by one or more issuers, that is shared with a specific verifier (see [VC_DATA]).¶
Verified Presentation (VP)¶
A verifiable presentation is a tamper-evident presentation encoded in such a way that authorship of the data can be trusted after a process of cryptographic verification. Certain types of verifiable presentations might contain data that is synthesized from, but do not contain, the original verifiable Credentials (for example, zero-knowledge proofs) (see [VC_DATA]).¶
Deferred Credential Issuance¶
Issuance of Credentials not directly in the response to a Credential issuance request, but following a period of time that can be used to perform certain offline business processes.¶
Wallet¶
Entity that receives, stores, presents, and manages Credentials and key material of the End-User. There is no single deployment model of a Wallet: Credentials and keys can both be stored/managed locally by the end-user, or by using a remote self-hosted service, or a remote third party service. In the context of this specification, the Wallet acts as an OAuth 2.0 Client (see [RFC6749]) towards the Credential Issuer.¶
Verifier¶
Entity that verifies the Credential to make a decision regarding providing a service to the End-User. Also called Relying Party (RP) or Client. During presentation of Credentials, Verifier acts as an OAuth 2.0 Client towards the Wallet acting as an OAuth 2.0 Authorization Server.¶
Credential Issuer¶
Entity that issues verifiable Credentials. Also called Issuer. In the context of this specification, the Credential Issuer acts as OAuth 2.0 Authorization Server (see [RFC6749]).¶
Base64url Encoding¶
Base64 encoding using the URL- and filename-safe character set defined in Section 5 of [RFC4648], with all trailing '=' characters omitted (as permitted by Section 3.2 of [RFC4648]) and without the inclusion of any line breaks, whitespace, or other additional characters. Note that the base64url encoding of the empty octet sequence is the empty string. (See Appendix C of [RFC7515] for notes on implementing base64url encoding without padding.)¶
This is a non-exhaustive list of sample use cases.¶
While browsing the university's home page, the user finds a link "request your digital diploma". User clicks on this link and is being redirected to a digital Wallet application. The Wallet notifies the user that an issuer offered to issue a diploma Credential. User confirms this inquiry and is taken to the university's Credential issuance service's user experience. After authenticating at the university and consenting to the issuance of a digital diploma, the user is sent back to the Wallet, where she can check the successful creation of the digital diploma.¶
The user is starting a job at a new employer. An employer has requested the user to upload certain documents to the employee portal. A few days later, the user receives an email from the employer notifying her that the employee Credential is ready and asking her to scan a QR code to retrieve it. User scans the QR code with her smartphone, which opens her Wallet. Meanwhile, the user has received a text message with a PIN code to her smartphone. After entering that PIN code in the Wallet for security reasons, the user confirms the Credential issuance, and receives Credential into the Wallet.¶
The user wants to obtain a digital criminal record. She visits the local administration's office and requests the issuance of the official criminal record as a digital Credential. After presenting her ID document, she is asked to scan a QR code with her wallet. She is being told that the actual issuance of the Credential will take some time due to necessary background checks by the authority.¶
In the Wallet, the user sees an indication that issuance of the digital record is under way. A few days later, the user receives a notification from her Wallet app that requested Credential was successfully issued. When the user opens the Wallet, she is asked whether she wants to download the Credential. She confirms, and the new Credential is retrieved and stored in the Wallet.¶
A user comes across a verifier app that is requesting the user to present a Credential, e.g., a driving license. The Wallet determines the requested Credential type(s) from the Credential presentation request and notifies the user that there is currently no matching Credential in the Wallet. The Wallet determines an issuer capable of issuing the lacking Credential and upon user consent sends the user to the issuer's user experience (web site or app). Upon being authenticated and providing consent to issue the Credential into her Wallet, the user is sent back to the Wallet. The Wallet informs the user Credential was successfully issued into the Wallet and is ready to be presented to the verifier app that originally requested presentation of that Credential.¶
A user comes across a verifier app that is requesting the user to present a Credential, e.g., a university diploma. The Wallet determines the requested Credential type(s) from the Credential presentation request and notifies the user that there is currently no matching Credential in the Wallet. The Wallet then offers the user a list of issuers, which might be based on an issuer list curated by the Wallet provider. The user picks the university she graduated from and is sent to that university's user experience (web site or app).¶
The user logs in to the university, which determines that the respective user account is not verified yet. Among multiple identification options, the user chooses to present identity Credential from her Wallet. The user is sent back to the Wallet where she consents to share requested Credential(s) to the university. The user is sent back to the university user experience. Based on the presented Credential, the university completes the user verification, looks up user data in its database, and offers to issue a diploma as a verifiable Credential.¶
Upon providing consent, the user is sent back to the Wallet. The Wallet informs the user Credential was successfully issued into the Wallet and is ready to be presented to the verifier app that originally requested presentation of that Credential.¶
This specification defines the following mechanisms to allow Wallet applications used by the End-User to request Credential issuers to issue Verifiable Credentials via the Credential Endpoint:¶
A newly defined Credential Endpoint from which Credentials can be issued. See Section 9.¶
An optional mechanism for the Issuer to initiate the issuance. See Section 6.¶
An extended Authorization Request that allows to request authorization to request issuance of Credentials of specific types. See Section 7.1.¶
An optional ability to bind an issued Credential to a cryptographic key material. The Credential request therefore allows to convey a proof of posession for the key material. Multiple proof types are supported. See Section 9.2.¶
A mechanism for the Deferred Credential Issuance. See Section 10.¶
A mechanism for the Issuer to publish metadata about the Credential it is capable of issuing. See Section 11.2¶
A mechanism that allows issuance of multiple Credentials of same or different type. See Section 8.2 and Section 9.3.¶
The Wallet sends one Credential Request per individual Credential. The wallet MAY use the same access token to send multiple Credential Requests to request issuance of - multiple Credentials of different types bound to the same proof, or - multiple Credentials of the same type bound to different proofs¶
The Issuer MAY also request Credential presentation as means to authenticate or identify the User during the Issuance Flow as illustrated in a use case in Section 3.5.¶
Note that the issuance can have multiple characteristics, which can be combined depending on the use-cases:¶
Authorization Code Flow or Pre-Authorized Code Flow: whether the Issuer obtains user information to turn into a verifiable Credential using user authentication and consent at the Issuer's Authorization Endpoint (Authorization Code Flow), or using out of bound mechanisms outside of the issuance flow (pre-authorized code flow)¶
Wallet initiated or Issuer initiated: whether the issuance request from the Wallet is sent to the Issuer without any gesture from the Issuer (Wallet Initiated), or following the communication from the Issuer (Issuer Initiated).¶
Same-device or Cross-device: whether the Wallet to which the Credential is issued and the Issuer's user experience (website or an app) reside on the same device, or on different devices.¶
Just-in-time or Deferred: whether the Issuer can issue the Credential directly in response to the Credential Request (just-in-time), or requires time and needs the Wallet to come back to retrieve Credential (deferred).¶
This specification defines new endpoints as well as additional parameters to existing OAuth 2.0 endpoints required to implement the protocol outlined in the previous section. It also introduces a new authorization details type according to [I-D.ietf-oauth-rar] to convey the details about the Credentials the Wallet wants to obtain. Aspects not defined in this specification are expected to follow [RFC6749]. It is RECOMMENDED to use PKCE as defined in [RFC7636] to prevent authorization code interception attacks.¶
Newly defined endpoints are the following:¶
Issuance Initiation Endpoint: An endpoint exposed by the Wallet that allows an issuer to initiate the issuance flow.¶
Credential Endpoint: An OAuth 2.0-protected endpoint exposed by the Issuer and used to issue verifiable Credentials.¶
Deferred Credential Endpoint: this endpoint is used for deferred issuance of verifiable Credentials.¶
Existing OAuth 2.0 mechanisms are extended as following:¶
Client Metadata: new metadata parameter is added to allow a Wallet (acting as OAuth 2.0 client) to publish its issuance initiation endpoint.¶
Server Metadata: New metadata parameters are added to allow the client to determine what types of verifiable Credentials a particular OAuth 2.0 Authorization Server is able to issue along with additional information about formats and prerequisites.¶
Authorization Endpoint: The authorization_details parameter is extended to allow clients to specify types of the Credentials when requesting authorization for issuance. These extension can also be used via the Pushed Authorization Endpoint, which is recommended by this specification.¶
Token Endpoint: optional parameters are added to the token endpoint to provide the client with a nonce to be used for proof of possession of key material in a subsequent request to the Credential endpoint.¶
ToDo: potentially add a section that explains basics of OAuth 2.0 (perhaps an addendum).¶
This endpoint is used by an issuer in case it is already in an interaction with a user that wishes to initate a Credential issuance. It is used to pass available information relevant for the Credential issuance to ensure a convenient and secure process.¶
The Issuer sends the request as a HTTP GET request or a HTTP redirect to the Issuance Initiation Endpoint URL defined in Section 11.1.¶
The following request parameters are defined:¶
issuer: REQUIRED. The issuer URL of the Credential issuer, the Wallet is requested to obtain one or more Credentials from.¶
credential_type: REQUIRED. A JSON string denoting the type of the Credential the Wallet shall request.¶
pre-authorized_code: CONDITIONAL. The code representing the issuer's authorization for the Wallet to obtain Credentials of a certain type. This code MUST be short lived and single-use. MUST be present in a pre-authorized code flow.¶
user_pin_required: OPTIONAL. Boolean value specifying whether the issuer expects presentation of a user PIN along with the Token Request in a pre-authorized code flow. Default is false. This PIN is intended to bind the pre-authorized code to a certain transaction in order to prevent replay of this code by an attacker that, for example, scanned the QR code while standing behind the legit user. It is RECOMMENDED to send a PIN via a separate channel.¶
op_state: OPTIONAL. String value created by the Credential Issuer and opaque to the Wallet that is used to bind the sub-sequent authentication request with the Credential Issuer to a context set up during previous steps. If the client receives a value for this parameter, it MUST include it in the subsequent Authentication Request to the Credential Issuer as the op_state parameter value. MUST NOT be used in Authorization Code flow when pre-authorized_code is present.¶
The Wallet MUST consider the parameter values in the initiation request as not trustworthy since the origin is not authenticated and the message integrity is not protected. The Wallet MUST apply the same checks on the issuer that it would apply when the flow is started from the Wallet itself since the issuer is not trustworthy just because it sent the initiation request. An attacker might attempt to use an initation request to conduct a phishing or injection attack.¶
The Wallet MUST NOT accept Credentials just because this mechanism was used. All protocol steps defined in this draft MUST be performed in the same way as if the Wallet would have started the flow.¶
The Wallet MUST be able to process multiple occurences of the URL query parameters credential_type. Multiple occurences MUST be treated as multiple values of the respective parameter.¶
The Issuer MUST ensure the release of any privacy-sensitive data is legally based.¶
Below is a non-normative example of an Issuance Initiation Request in an authorization code flow:¶
GET /initiate_issuance?
issuer=https%3A%2F%2Fserver%2Eexample%2Ecom
&credential_type=https%3A%2F%2Fdid%2Eexample%2Eorg%2FhealthCard
&op_state=eyJhbGciOiJSU0Et...FYUaBy
¶
Below is a non-normative example of an Issuance Initiation Request in a pre-authorized code flow:¶
GET /initiate_issuance?
issuer=https%3A%2F%2Fserver%2Eexample%2Ecom
&credential_type=https%3A%2F%2Fdid%2Eexample%2Eorg%2FhealthCard
&pre-authorized_code=SplxlOBeZQQYbYS6WxSbIA
¶
The Issuer MAY also render a QR code containing the request data that can be scanned by the user using a Wallet app, or a deeplink that the user can click.¶
The following is a non-normative example of such a request that can be included in a QR code or a deeplink:¶
openid-initiate-issuance://?
issuer=https%3A%2F%2Fserver%2Eexample%2Ecom
&credential_type=https%3A%2F%2Fdid%2Eexample%2Eorg%2FhealthCard
&pre-authorized_code=SplxlOBeZQQYbYS6WxSbIA
&user_pin_required=true
¶
The Wallet is not supposed to create a response. UX control stays with the Wallet after completion of the process.¶
The Token Endpoint issues an Access Token and, optionally, a Refresh Token in exchange for the authorization code that client obtained in a successful Authorization Response. It is used in the same manner as defined in [RFC6749] and follows the recommendations given in [I-D.ietf-oauth-security-topics].¶
Upon receiving a successful Authorization Response, a Token Request is made as defined in Section 4.1.3 of [RFC6749].¶
The following are the extension parameters to the Token Request used in a pre-authorized code flow:¶
pre-authorized_code: CONDITIONAL. The code representing the authorization to obtain Credentials of a certain type. This parameter is required if the grant_type is urn:ietf:params:oauth:grant-type:pre-authorized_code.¶
user_pin: OPTIONAL. String value containing a user PIN. This value MUST be present if user_pin_required was set to true in the Issuance Initiation Request. The string value MUST consist of maximum 8 numeric characters (the numbers 0 - 9). This parameter MUST only be used, if the grant_type is urn:ietf:params:oauth:grant-type:pre-authorized_code.¶
Below is a non-normative example of a Token Request in an authorization code flow:¶
POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW grant_type=authorization_code &code=SplxlOBeZQQYbYS6WxSbIA &code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk &redirect_uri=https%3A%2F%2FWallet.example.org%2Fcb¶
Below is a non-normative example of a Token Request in a pre-authorized code flow:¶
POST /token HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW grant_type=urn:ietf:params:oauth:grant-type:pre-authorized_code &pre-authorized_code=SplxlOBeZQQYbYS6WxSbIA &user_pin=493536¶
Token Requests are made as defined in [RFC6749].¶
In addition to the response parameters defined in [RFC6749], the AS MAY return the following parameters:¶
c_nonce: OPTIONAL. JSON string containing a nonce to be used to create a proof of possession of key material when requesting a Credential (see Section 9.2).¶
c_nonce_expires_in: OPTIONAL. JSON integer denoting the lifetime in seconds of the c_nonce.¶
authorization_pending: OPTIONAL. JSON Boolean. In pre-authorized code flow, the Token Request is still pending as the issuer is waiting for the end user interaction to complete. The client SHOULD repeat the Token Request. Before each new request, the client MUST wait at least the number of seconds specified by the "interval" response parameter. ToDo: clarify boolean.¶
interval: OPTIONAL. The minimum amount of time in seconds that the client SHOULD wait between polling requests to the token endpoint in pre-authorized code flow. If no value is provided, clients MUST use 5 as the default.¶
Upon receiving pre-authorized_code, the issuer MAY decide to interact with the end-user in the course of the Token Request processing, which might take some time. In such a case, the issuer SHOULD respond with the error authorization_pending and the new return parameter interval.¶
Below is a non-normative example of a Token Response:¶
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp..sHQ",
"token_type": "bearer",
"expires_in": 86400,
"c_nonce": "tZignsnFbp",
"c_nonce_expires_in": 86400
}
¶
If the Token Request is invalid or unauthorized, the Authorization Server constructs the error response as defined as in Section 5.2 of OAuth 2.0 [RFC6749].¶
Below is a non-normative example Token Error Response:¶
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error": "invalid_request"
}
¶
The Credential Endpoint issues a Credential as approved by the End-User upon presentation of a valid Access Token representing this approval.¶
Communication with the Credential Endpoint MUST utilize TLS.¶
The client can request issuance of a Credential of a certain type multiple times, e.g., to associate the Credential with different DIDs/public keys or to refresh a certain Credential.¶
If the access token is valid for requesting issuance of multiple Credentials, it is at the client's discretion to decide the order in which to request issuance of multiple Credentials requested in the Authorization Request.¶
Issued Credential SHOULD be cryptographically bound to the identifier of the End-User who possesses the Credential. Cryptographic binding allows the Verifier to verify during presentation that the End-User presenting a Credential is the same End-User to whom it was issued. For non-cryptographic type of binding and Credentials issued without any binding, see Implementations Considerations sections Section 13.1 and Section 13.2.¶
Note that claims in the Credential are usually about the End-User who possesses it, but can be about another entity.¶
For cryptographic binding, the Client has the following options to provide cryptographic binding material for a requested Credential as defined in Section 9.2:¶
A Client makes a Credential Request to the Credential Endpoint by sending the following parameters in the entity-body of an HTTP POST request using the "application/json" media type.¶
type: REQUIRED. Type of a Credential being requested. It corresponds to a type property in a Issuer metadata.¶
format: OPTIONAL. Format of the Credential to be issued. If not present, the issuer will determine the Credential
format based on the client's format default.¶
proof OPTIONAL. JSON Object containing proof of possession of the key material the issued Credential shall be
bound to. The proof object MUST contain the following proof_type element which determines its structure:¶
proof_type: REQUIRED. JSON String denoting the proof type.¶
This specification defines the following values for proof_type:¶
jwt: objects of this type contain a single jwt element with a JWS [RFC7515] as proof of possession. The JWT MUST contain the following elements:¶
kid: CONDITIONAL. JWT header containing the key ID. If the Credential shall be bound to a DID, the kid refers to a DID URL which identifies a particular key in the DID Document that the Credential shall be bound to. MUST NOT be present if jwk or x5c is present.¶
jwk: CONDITIONAL. JWT header containing the key material the new Credential shall be bound to. MUST NOT be present if kid or x5c is present.¶
x5c: CONDITIONAL. JWT header containing a certificate or certificate chain corresponding to the key used to sign the JWT. This element may be used to convey a key attestation. In such a case, the actual key certificate will contain attributes related to the key properties. MUST NOT be present if kid or jwk is present.¶
iss: REQUIRED (string). The value of this claim MUST be the client_id of the client making the credential request.¶
aud: REQUIRED (string). The value of this claim MUST be the issuer URL of credential issuer.¶
iat: REQUIRED (number). The value of this claim MUST be the time at which the proof was issued using the syntax defined in [RFC7519].¶
nonce: REQUIRED (string). The value type of this claim MUST be a string, where the value is a c_nonce provided by the credential issuer.¶
Note: if both jwk and x5c are present, the represented signing key MUST be the same in both.¶
The proof element MUST incorporate a c_nonce value generated by the Credential issuer and the Credential issuer's identifier (audience) to allow the Credential issuer to detect replay. The way that data is incorporated depends on the proof type. In a JWT, for example, the c_nonce is conveyd in the nonce claims whereas the audience is conveyed in the aud claim. In a Linked Data proof, for example, the c_nonce is included as the challenge element in the proof object and the issuer (the intended audience) is included as the domain element.¶
The Issuer MUST validate that the proof is actually signed by a key identified in kid parameter.¶
Below is a non-normative example of a proof parameter (line breaks for display purposes only):¶
{
"proof_type": "jwt",
"jwt": "eyJraWQiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEva2V5cy8
xIiwiYWxnIjoiRVMyNTYiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzNkJoZFJrcXQzIiwiYXVkIjoiaHR
0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLCJpYXQiOiIyMDE4LTA5LTE0VDIxOjE5OjEwWiIsIm5vbm
NlIjoidFppZ25zbkZicCJ9.ewdkIkPV50iOeBUqMXCC_aZKPxgihac0aW9EkL1nOzM"
}
¶
where the JWT looks like this:¶
{
"alg": "ES256",
"kid":"did:example:ebfeb1f712ebc6f1c276e12ec21/keys/1"
}.
{
"iss": "s6BhdRkqt3",
"aud": "https://server.example.com",
"iat": 1659145924,
"nonce": "tZignsnFbp"
}
¶
Here is another example JWT not only proving possession of a private key but also providing key attestation data for that key:¶
{
"alg": "ES256",
"x5c":[<key certificate + certificate chain for attestation>]
}.
{
"iss": "s6BhdRkqt3",
"aud": "https://server.example.com",
"iat": 1659145924,
"nonce": "tZignsnFbp"
}
¶
Below is a non-normative example of a Credential Request:¶
POST /credential HTTP/1.1
Host: server.example.com
Content-Type: application/json
Authorization: BEARER czZCaGRSa3F0MzpnWDFmQmF0M2JW
{
"type": "https://did.example.org/healthCard"
"format": "ldp_vc",
"proof": {
"proof_type": "jwt",
"jwt": "eyJraWQiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEva2V5cy8
xIiwiYWxnIjoiRVMyNTYiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzNkJoZFJrcXQzIiwiYXVkIjoiaHR
0cHM6Ly9zZXJ2ZXIuZXhhbXBsZS5jb20iLCJpYXQiOiIyMDE4LTA5LTE0VDIxOjE5OjEwWiIsIm5vbm
NlIjoidFppZ25zbkZicCJ9.ewdkIkPV50iOeBUqMXCC_aZKPxgihac0aW9EkL1nOzM"
}
}
¶
Credential Response can be Synchronous or Deferred. The Issuer may be able to immediately issue a requested Credential and send it to the Client. In other cases, the Issuer may not be able to immediately issue a requested Credential and would want to send a token to the Client to be used later to receive a Credential when it is ready.¶
The following claims are used in the Credential Response:¶
format: REQUIRED. JSON string denoting the Credential's format¶
credential: OPTIONAL. Contains issued Credential. MUST be present when acceptance_token is not returned. MAY be a JSON string or a JSON object, depending on the Credential format. See the table below for the format specific encoding requirements.¶
acceptance_token: OPTIONAL. A JSON string containing a token subsequently used to obtain a Credential. MUST be present when credential is not returned.¶
c_nonce: OPTIONAL. JSON string containing a nonce to be used to create a proof of possession of key material when requesting a Credential (see Section 9.2).¶
c_nonce_expires_in: OPTIONAL. JSON integer denoting the lifetime in seconds of the c_nonce.¶
The following table defines how issued Credential MUST be returned in the credential claim in the Credential Response based on the Credential format and the signature scheme. This specification does not require any additional encoding when Credential format is already represented as a JSON object or a JSON string.¶
| Credential Signature Format | Credential Format Identifier | Signature Scheme | Need for encoding when returning in the Credential Response |
|---|---|---|---|
| JWS Compact Serialization |
jwt_vc, mdl_iso_json, mid_iso_json
|
Credential conformant to the W3C Verifiable Credentials Data Model, ISO/IEC 18013-5:2021 mobile driving licence (mDL) data model, or ISO/IEC 23220-4 mobile eID document data model (not yet published), and signed as a JWS Compact Serialization. | MUST be a JSON string. Credential is already a sequence of base64url-encoded values separated by period characters and MUST NOT be re-encoded. |
| JWS JSON Serialization |
jwt_vc, mdl_iso_json, mid_iso_cbor
|
Credential conformant to the W3C Verifiable Credentials Data Model, ISO/IEC 18013-5:2021 mobile driving licence (mDL) data model, or ISO/IEC 23220-4 mobile eID document data model (not yet published), and signed as a JWS JSON Serialization. | MUST be a JSON object. MUST NOT be re-encoded. |
| Data Integrity |
ldp_vc
|
Credential conformant to the W3C Verifiable Credentials Data Model and signed with Data Integrity Proofs. | MUST be a JSON object. MUST NOT be re-encoded. |
| CL-Signatures |
ac_vc
|
Credential conformant to the AnonCreds format as defined in the Hyperledger Indy project and signed using CL-signature scheme. | MUST be a JSON object. MUST NOT be re-encoded. |
| COSE |
mdl_iso_cbor
|
Credential conformant to the ISO/IEC 18013-5:2021 mobile driving licence (mDL) data model, encoded as CBOR and signed as a COSE message. | MUST be a JSON string that is the base64url-encoded representation of the issued Credential |
Credential formats expressed as binary formats MUST be base64url-encoded and returned as a JSON string.¶
Note that this table might be superceded by a registry in the future. Meanwhile, for interoperability, implementers MUST follow the requirements defined in the table above.¶
Below is a non-normative example of a Credential Response in a synchronous flow:¶
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"format": "jwt_vc"
"credential" : "LUpixVCWJk0eOt4CXQe1NXK....WZwmhmn9OQp6YxX0a2L",
"c_nonce": "fGFF7UkhLa",
"c_nonce_expires_in": 86400
}
¶
Below is a non-normative example of a Credential Response in a deferred flow:¶
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"acceptance_token": "8xLOxBtZp8",
"c_nonce": "wlbQc6pCJp",
"c_nonce_expires_in": 86400
}
¶
Note: Consider using CIBA Ping/Push OR SSE Poll/Push. Another option would be the Client providing client_notification_token to the Issuer, so that the issuer sends a Credential response upon successfully receiving a Credential request and then no need for the client to bring an acceptance token, the Issuer will send the Credential once it is issued in a response that includes client_notification_token. (consider SSE options)¶
Upon receiving a Credential Request, the Credential issuer MAY require the client to send a proof of possession of the key material it wants a Credential to be bound to. This proof MUST incorporate a nonce generated by the Credential issuer. The Credential issuer will provide the client with a nonce in an error response to any Credential Request not including such a proof or including an invalid proof.¶
Below is a non-normative example of a Credential Response when the Issuer is requesting a Wallet to provide in a subsequent Credential Request a proof that is bound to a c_nonce:¶
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error": "invalid_or_missing_proof"
"error_description":
"Credential issuer requires proof element in Credential Request"
"c_nonce": "8YE9hCnyV2",
"c_nonce_expires_in": 86400
}
¶
ToDo - 400 might not be a right answer.¶
This endpoint is used to issue a Credential previously requested at the Credential endpoint in case the Issuer was not able to immediately issue this Credential.¶
This is an HTTP POST request, which accepts an acceptance token as the only parameter. The acceptance token MUST be sent as access token in the HTTP header as shown in the following example.¶
POST /credential_deferred HTTP/1.1 Host: server.example.com Content-Type: application/x-www-form-urlencoded Authorization: BEARER 8xLOxBtZp8¶
The deferred Credential Response uses the format and credential parameters as defined in Section 9.3.¶
This specification defines the following new Client Metadata parameter in addition to [RFC7591] for Wallets acting as OAuth client:¶
initiate_issuance_endpoint: OPTIONAL. URL of the issuance initation endpoint of a Wallet.¶
If the issuer is unable to perform discovery of the Issuance Initiation Endpoint URL, the following claimed URL is used: openid-initiate-issuance://.¶
This section extends the server metadata [RFC8414] to allow the RP to obtain information about the Credentials an OP is capable of issuing.¶
This specification defines the following new Server Metadata parameters for this purpose:¶
credential_endpoint: REQUIRED. URL of the OP's Credential Endpoint. This URL MUST use the https scheme and MAY contain port, path and query parameter components.¶
The following parameter MUST be used to communicates the specifics of the Credential that the issuer supports issuance of:¶
credentials_supported: REQUIRED. A JSON object containing a list of key value pairs, where the key is a string serving as an abstract identifier of the Credential. This identifier is RECOMMENDED to be collision resistant - it can be globally unique, but does not have to be when naming conflicts are unlikely to arise in a given use case. The value is a JSON object. The JSON object MUST conform to the structure of the Section 11.2.1.¶
credential_issuer: OPTIONAL. A JSON object containing display properties for the Credential issuer.¶
display: OPTIONAL. An array of objects, where each object contains display properties of a Credential issuer for a certain language. Below is a non-exhaustive list of valid parameters that MAY be included:¶
name: OPTIONAL. String value of a display name for the Credential issuer.¶
locale: OPTIONAL. String value that identifies language of this object represented as language tag values defined in BCP47 [RFC5646]. There MUST be only one object with the same language identifier¶
This section defines the structure of the object that appears as the value to the keys inside the object defined for the credentials_supported metadata element.¶
display: OPTIONAL. An array of objects, where each object contains display properties of a certain Credential for a certain language. Below is a non-exhaustive list of parameters that MAY be included. Note that the display name of the Credential is obtained from display.name and individual claim names from claims.display.name values.¶
name: REQUIRED. String value of a display name for the Credential.¶
locale: OPTIONAL. String value that identifies language of this display object represented as language tag values defined in BCP47 [RFC5646]. Multiple display objects may be included for separate languages. There MUST be only one object with the same language identifier.¶
logo: OPTIONAL. A JSON object with information about the logo of the Credential with a following non-exhaustive list of parameters that MAY be included:¶
url: OPTIONAL. URL where the Wallet can obtain a logo of the Credential issuer.¶
alt_text: OPTIONAL. String value of an alternative text of a logo image.¶
description: OPTIONAL. String value of a description of the Credential.¶
background_color: OPTIONAL. String value of a background color of the Credential represented as numerical color values defined in CSS Color Module Level 37 [CSS-Color].¶
text_color: OPTIONAL. String value of a text color of the Credential represented as numerical color values defined in CSS Color Module Level 37 [CSS-Color].¶
formats: REQUIRED. A JSON object containing a list of key value pairs, where the key is a string identifying the format of the Credential. Below is a non-exhaustive list of valid key values defined by this specification:¶
Claim Format Designations defined in [DIF.PresentationExchange], such as jwt_vc and ldp_vc¶
mdl_iso: defined in this specification to express a mobile driving licence (mDL) Credential compliant to a data model and data sets defined in ISO/IEC 18013-5:2021 specification.¶
ac_vc: defined in this specificaiton to express an AnonCreds Credential format defined as part of the Hyperledger Indy project [Hyperledger.Indy].¶
The value in a key value pair is a JSON object detailing the specifics about the support for the Credential format with a following non-exhaustive list of parameters that MAY be included:
* types: REQUIRED. Array of strings representing a format specific type of a Credential. This value corresponds to type in W3C [VC_DATA] and a doctype in ISO/IEC 18013-5 (mobile Driving License).
* cryptographic_binding_methods_supported: OPTIONAL. Array of case sensitive strings that identify how the Credential is bound to the identifier of the End-User who possesses the Credential as defined in Section 9.1. A non-exhaustive list of valid values defined by this specification are did, jwk, and mso.
* cryptographic_suites_supported: OPTIONAL. Array of case sensitive strings that identify the cryptographic suites that are supported for the cryptographic_binding_methods_supported. Cryptosuites for Credentials in jwt_vc format should use algorithm names defined in IANA JOSE Algorithms Registry. Cryptosuites for Credentials in ldp_vc format should use signature suites names defined in Linked Data Cryptographic Suite Registry.¶
claims: REQUIRED. A JSON object containing a list of key value pairs, where the key identifies the claim offered in the Credential. The value is a JSON object detailing the specifics about the support for the claim with a following non-exhaustive list of parameters that MAY be included:¶
mandatory: OPTIONAL. Boolean which when set to true indicates the claim MUST be present in the issued Credential. If the mandatory property is omitted its default should be assumed to be false.¶
namespace: OPTIONAL. String value of a namespace that the claim belongs to. Relevant for ISO/IEC 18013-5 (mobile Driving License) specification.¶
value_type: OPTIONAL. String value determining type of value of the claim. A non-exhaustive list of valid values defined by this specification are string, number, and image media types such as image/jpeg as defined in IANA media type registry for images (https://www.iana.org/assignments/media-types/media-types.xhtml#image).¶
display: OPTIONAL. An array of objects, where each object contains display properties of a certain claim in the Credential for a certain language. Below is a non-exhaustive list of valid parameters that MAY be included:¶
name: OPTIONAL. String value of a display name for the claim.¶
locale: OPTIONAL. String value that identifies language of this object represented as language tag values defined in BCP47 [RFC5646]. There MUST be only one object with the same language identifier.¶
It is dependent on the Credential format where the requested claims will appear.¶
The following example shows a non-normative example of the relevant entries in the OP metadata defined above¶
HTTP/1.1 200 OK
Content-Type: application/json
{
"credential_endpoint": "https://server.example.com/credential",
"credentials_supported": {
"university_degree": {
"display": [{
"name": "University Credential",
"locale": "en-US",
"logo": {
"url": "https://exampleuniversity.com/public/logo.png",
"alternative_text": "a square logo of a university"
},
"background_color": "#12107c",
"text_color": "#FFFFFF"
},
{
"name": "在籍証明書",
"locale": "jp-JA",
"logo": {
"url": "https://exampleuniversity.com/public/logo.png",
"alternative_text": "大学のロゴ"
},
"background_color": "#12107c",
"text_color": "#FFFFFF"
}
],
"formats": {
"ldp_vc": {
"types": ["VerifiableCredential", "UniversityDegreeCredential"],
"cryptographic_binding_methods_supported": ["did"],
"cryptographic_suites_supported": ["Ed25519Signature2018"]
}
},
"claims": {
"given_name": {
"mandatory": false,
"display": [{
"name": "Given Name",
"locale": "en-US"
},
{
"name": "名前",
"locale": "jp-JA"
}
]
},
"last_name": {},
"degree": {},
"gpa": {
"mandatory": false,
"value_type": "number",
"display": [{
"name": "GPA"
}]
}
}
},
"WorkplaceCredential": {
"formats": {
"jwt_vc": {
"types": ["VerifiableCredential", "WorkplaceCredential"],
"cryptographic_binding_methods_supported": ["did"],
"cryptographic_suites_supported": ["ES256K"]
}
}
}
},
"credential_issuer": {
"display": [{
"name": "Example University",
"locale": "en-US"
},
{
"name": "サンプル大学",
"locale": "jp-JA"
}
]
}
}
¶
Note: The Client MAY use other mechanisms to obtain information about the verifiable Credentials that an Issuer can issue.¶
Credential Issuers often want to know what Wallet they are issuing Credentials to and how private keys are managed for the following reasons:¶
The issuer may wants to ensure that private keys are properly protected from exfiltration and replay in order to prevent an adversary from impersonating the legitimate Credential holder by presenting her Credential.¶
The issuer may also want to ensure that the Wallet managing the Credentials adheres to certain policies and, potentially, was audited and approved under a certain regulatory and/or commercial scheme.¶
The following mechanisms in concert can be utilized to fulfill those objectives:¶
Key attestation is a mechanism where the device or security element in a device asserts the key management policy to the application creating and using this key. The Android Operating System, for example, provides apps with a certificate including a certificate chain asserting that a particular key is managed, for example, by an hardware security module [ref]. The Wallet can provide this data along with the proof of possession in the Credential Request (see Section 9.2 for an example) to allow the issuer to validate the key management policy. This indeed requires the issuer to rely on the trust anchor of the certificate chain and the respective key management policy. Another variant of this concept is the use of a Qualified Electronic Signature as defined by the eIDAS regulation [ref]. This signatures won't reveal the concrete properties of the associated private key to the issuer. However, due to the regulatory regime of eIDAS the issuer can deduce that the signing service manages the private keys according to this regime and fulfills very high security requirements. As another example, FIDO2 allows RPs to obtain an attestation along with the public key from a FIDO authenticator. That implicitly asserts the key management policy since the assertion is bound to a certain authenticator model and its key management capabilities.¶
App Attestation: Key attestation, however, does not establish trust in the application storing the Credential and producing presentation of that Credential. App attestation as provided by mobile operating systems, e.g. iOS's DeviceCheck or Android's Safetynet, allows a server system to ensure it is communicating to a legitimate instance of its genuine app. Those mechanisms can be utilized to validate the internal integrity of the Wallet (as a whole).¶
Device Attestation: Device Attestation attests the health of the device, on which the Wallet application is running, as a whole. It prevents compromises such as a malicious third party application tampering with a Wallet application managing keys and Credentials, which cannot be captured only by obtaining app attestation of a Wallet application.¶
Client authentication allows a Wallet to authenticate with an issuer. In order to securely authenticate, the Wallet needs to utilize a backend component managing the key material and processing the secure communication with the Credential issuer. The issuer may establish trust with the Wallet based on its own auditing or a trusted 3rd party attestation of the conformance of the Wallet to a certain policy.¶
Directly using key, app and/or device attestations to proof certain capabilities towards an issuer is an obvious option. However, this at least requires platform mechanisms that issue signed assertions that 3rd parties can evaluate, which is not always the case (e.g. iOS's DeviceCheck). Also, such an approach creates dependencies on platform specific mechanisms, trust anchors, and platform specific identifiers (e.g. Android apkPackageName) and it reveals information about the internal design of a Wallet app. Implementers should take that consequences into account.¶
The approach recommended by this specification is that the issuer relies on the OAuth 2.0 client authentication to establish trust in the Wallet and leaves it to the Wallet to ensure its internal integrity using app and key attestation (if required). This establishes a clean separation between the different hemispheres and a uniform interface irrespectively of the Wallet's architecture (e.g. native vs web Wallet). Client authentication can be performed with Credentials registered with the issuer or with assertions issued to the Wallet by a 3rd party the issuer trusts for the purpose of client authentication.¶
The issuer is supposed to be responsible for the lifecycle of its Credentials. This means the issuer will invalidate Credentials if it deems appropriate, e.g. if it detects fraudulent behavior.¶
The Wallet is supposed to detect signs of fraudulant behavior related to the Credential management in the Wallet (e.g. device rooting) and to act upon such signals. Options include Credential revocation at the issuer and/or invalidation of the key material used to cryptographically bind Credential to the identifier of the End-User possessing that Credential.¶
Credential not cryptographically bound to the identifier of the End-User possessing it (see Section 9.1), should be bound to the End-User possessing the Credential based on the claims included in that Credential.¶
In claim-based binding, no cryptographic binding material is provided. Instead, the issued Credential includes user claims that can be used by the Verifier to verify possession of the Credential by requesting presentation of existing forms of physical or digial identification that includes the same claims (e.g., a driver's license or other ID cards in person, or an online ID verification service).¶
Some Issuers might choose issuing bearer Credentials without either cryptographic binding nor claim-based binding, because they are meant to be presented without proof of possession.¶
One such use case is low assurance Credentials such as coupons or tickets.¶
Another use case is when the Issuer uses cryptographic schemes that can provide binding to the End-User possessing that Credential without explicit cryptographic material being supplied by the application used by that End-User. For example, in the case of the BBS Signature Scheme, the issued Credential itself is a secret and only derivation of a Credential is presented to the Verifier. Effectively, Credential is bound to the Issuer's signature on the Credential, which becomes a shared secret transferred from the Issuer to the End-User.¶
The Credential Endpoint can be accessed multiple times by a Wallet using the same Access Token, even for the same credential_type. The Issuer determines if the subsequent successful requests will return the same or an updated Credential, such as having a new expiration time or using the most current End-User claims.¶
The Issuer may also decide that the current Access Token is longer be valid and a re-authentication or Token Refresh (see [RFC6749]) may be required under the Issuer's discretion. The policies between the Credential Endpoint and the Authorization Server that may change the behavior of what is returned with a new Access Token are beyond the scope of this specification (see [RFC6749]).¶
The action leading to the Wallet performing another Credential Request can also be triggered by a background process, or by the Issuer using an out-of-band mechanism (SMS, email, etc.) to inform the End-User.¶
register "urn:ietf:params:oauth:grant-type:pre-authorized_code"¶
We would like to thank David Chadwick, John Bradley, Mark Haine, Alen Horvat, Michael B. Jones, and David Waite for their valuable contributions to this specification.¶
Copyright (c) 2022 The OpenID Foundation.¶
The OpenID Foundation (OIDF) grants to any Contributor, developer, implementer, or other interested party a non-exclusive, royalty free, worldwide copyright license to reproduce, prepare derivative works from, distribute, perform and display, this Implementers Draft or Final Specification solely for the purposes of (i) developing specifications, and (ii) implementing Implementers Drafts and Final Specifications based on such documents, provided that attribution be made to the OIDF as the source of the material, but that such attribution does not indicate an endorsement by the OIDF.¶
The technology described in this specification was made available from contributions from various sources, including members of the OpenID Foundation and others. Although the OpenID Foundation has taken steps to help ensure that the technology is available for distribution, it takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this specification or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any independent effort to identify any such rights. The OpenID Foundation and the contributors to this specification make no (and hereby expressly disclaim any) warranties (express, implied, or otherwise), including implied warranties of merchantability, non-infringement, fitness for a particular purpose, or title, related to this specification, and the entire risk as to implementing this specification is assumed by the implementer. The OpenID Intellectual Property Rights policy requires contributors to offer a patent promise not to assert certain patent claims against other contributors and against implementers. The OpenID Foundation invites any interested party to bring to its attention any copyrights, patents, patent applications, or other proprietary rights that may cover technology that may be required to practice this specification.¶
[[ To be removed from the final specification ]]¶
-08¶
reworked use of OAuth scopes to be more flexible for implementers¶
added text on scope related error handling¶
changed media type of a Credential Request to application/json from application/x-www-form-urlencoded¶
-07¶
restructured the entire specification as following:¶
-06¶
added issuer metadata¶
made Credential Response more flexible regarding Credential encoding¶
changed file name to match specification name¶
renamed specification to reflect OAuth 2.0 being the base protocol¶
-05¶
-04¶
added support for requesting Credential authorization with scopes¶
removed support to pass VPs in the Authorization Request¶
reworked "proof" parameter definition and added "jwt" proof type¶
-03¶
-02¶
Adopted as WG document¶
-01¶
-00¶
initial revision¶