Internet-Draft | VC Issuer | October 2024 |
Steele | Expires 18 April 2025 | [Page] |
This document describes a protocol for issuing Verifiable Credentials using HTTP.¶
This note is to be removed before publishing as an RFC.¶
The latest revision of this draft can be found at https://OR13.github.io/draft-steele-vc-issuer/draft-steele-vc-issuer.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-steele-vc-issuer/.¶
Source for this draft and an issue tracker can be found at https://github.com/OR13/draft-steele-vc-issuer.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 18 April 2025.¶
Copyright (c) 2024 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
The Verifiable Credentials (VC) data model is described in [W3C-VC], and securing mechanisms based on JOSE and COSE are described in [Secure-VC].¶
Although HTTP based protocols exist for issuing Verifiable Credentials, such as [OpenID4VC], they are encumbered by the conventions and history of OAuth and the experience needed to deploy OpenID successfully.¶
This document describes an HTTP API for VC Issuers, that provides interoperability while limiting normative dependencies, optionality and excessive cryptographic agility.¶
The API this document specifies is designed with priority for use by organizations or businesses that need to request credentials from other organizations or governments.¶
Although this API describes HTTP resources which require authentication, a specific authentication mechanism is not specified.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
The terms issuer, subject and holder are defined in [W3C-VC].¶
The terms iat
, exp
, iss
, sub
, aud
, are defined in [RFC7519].¶
The term nonce
is defined in [RFC9449].¶
The term cnf
is defined in [RFC7800].¶
The term ES256
is a digital signature algorithm described in Section 3.4 of [RFC7518].¶
This document uses "..." to ellide text in examples for readability.¶
Although [Secure-VC] describes several different media types, and each media type can be secured with many different signing or encryption algorithms, this documents specifies the following as mandatory to implement:¶
The following media types MUST be supported as JWT Claim Sets in the request body of the issuance API:¶
application/vc
¶
The following media types MUST be supported in the response body of the issuance and read APIs:¶
application/vc+jwt
¶
The following JSON Web Signature algorithms MUST be supported:¶
ES256¶
This document might be updated in the future to support additional media types or signing algorithms.¶
The /credentials
resource describes the collection of verifiable credentials associated with an issuer.¶
This collection supports creating, and retrieving resources.¶
Creating a verifiable credential requires several individual steps to be completed.¶
The server MUST validate the request body, ensuring the JSON object is conformant to [W3C-VC].¶
The server MAY reject credentials that do not match specific schemas.¶
The server SHOULD confirm any relationships between the claims requested and the identity of the subject initiating the request. For example, if Bob is requesting a name credential, the server should ensure that Bob is not able to receive a credential with the name Alice. A detailed analysis and set of recommendations regarding binding claims about subjects to credentials is beyond the scope of this document.¶
The server MAY retrieve or compute additional claims related to the validity period of the credential and its status update mechanisms. For example, a Driver's License credential has a fixed validity period with a start and end date, and can be suspended or revoked. Other credentials might never expire, or might not support any status update claims.¶
The server MUST validate the credential after applying all server side changes, to ensure it remains conformant to [W3C-VC].¶
The server MUST sign the response token with ES256.¶
The server MAY overwrite any member of the request body.¶
The server MAY inject additional JWT claims, such as iat
, exp
, iss
, sub
, and cnf
, before securing the credential as a JWT.¶
The server SHOULD assign an id
value that is globally unique, such as a UUID as described in Section 5.4 of [RFC9562].¶
The server MAY create credentials related to the issuance request, such as credentials which support status assertions or status lists.¶
The following informative example demonstrates how HTTP resources and media types are related to the credential issuance process.¶
An important step in the issuance of a credential is for the issuer to confirm the subject of the credential controls a public key or cryptographic identifier the credential will be bound to.¶
Confirmation methods are described in detail in [RFC7800].¶
This section describes a simple HTTP API for convincing an issuer to accept a confirmation claim in a requested credential issuance.¶
The holder first obtains a nonce
from the issuer, and then presents a confirmation token, that proves possession of a given key or cryptographic identifier, to a given audience, as part of a credential issuance request.¶
The following informative example demonstrates one way this can be accomplished:¶
To create the confirmation token, the holder signs a key or key reference in the protected header, and the nonce and an audience in the payload:¶
Note that the typ
value in the protected header can be different or absent.¶
The aud
, iat
and nonce
claims MUST be present in the payload.¶
Additional claims MAY be present, and MUST be ignored when not understood.¶
The confirmation token is then passed as a query parameter in the credential issuance request us the cnft
query parameter.¶
A server processes the cnft
query parameter by verifying the signature on the confirmation token in the protected header, and then validating the nonce
.
Validating the nonce
can be handled different ways, including lookups in a stateful database or checking digital signatures.
A detailed description of nonce production and consumption is beyond the scope of this document, see [OpenID4VC] for a description of one way that nonces can be used during credential issuance.
Once the issuer is satisfied that the nonce is sufficiently fresh, the issuer checks that either the public key used to sign the confirmation token, or its thumbprint, is included in the credential.¶
The server MUST return a 400 error in the case that a cnft
query parameter is sent, but no corresponding confirmation claim exists in the request body.¶
Retrieving a verifiable credential requires several steps to be completed.
The server MUST determine if the credential with the given id
is available.
Some credentials types SHOULD require authorization, and other credential types SHOULD support anonymous access.
If the credential does not support anonymous access, the server MUST ensure the client making the request is authorized to read the credential.
A detailed analys of credential types and their associated requirements is beyond the scope of this document.¶
The following informative example demonstrates how HTTP resources and media types are related to resolving or retrieving credentials.¶
There are many different ways to discover the cryptographic keys used to verify credentials signed by an issuer.¶
Issuer's that are required to issue credentials with web based decentralized identifiers, as described in [W3C-DID] MUST host special JSON documents called DID Documents under specific paths.¶
For example, to create a web based decentralized identifier for https://vendor.example
a JSON document needs to exist at https://vendor.example/.well-known/did.json
¶
To create a decentralized identifier for https://vendor.example/suppliers/123
a JSON document needs to exiist at https://vendor.example/suppliers/123/did.json
¶
The resource at this location SHOULD be served with media type application/json
, but MAY be served with the more specific media type application/did+json
.¶
If a credential has a header such as:¶
{ "typ": "vc+jwt", "alg": "ES256", "kid": "did:web:vendor.example#0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I" }¶
Then the resource at https://vendor.example/.well-known/did.json
should look like:¶
{ "id": "did:web:vendor.example", "verificationMethod": [{ "id": "did:web:vendor.example#0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I", "type": "JsonWebKey", "publicKeyJwk": { "kty": "EC", "alg": "ES256", "crv": "P-256", "x": "nUWAoAv3XZith8E7i19OdaxOLYFOwM-Z2EuM02TirT4", "y": "HskHU8BjUi1U9Xqi7Swmj8gwAK_0xkcDjEW_71SosEY" } }] }¶
Additional properties MAY be present, when not understood they MUST be ignored.¶
There are many different ways to describe the requirements associated a credential type, but one way is to use JSON Schema ([Json-Schema]).¶
Issuer's host the JSON Schema files at a specific url, for example: https://vendor.example/credentials/schema/trade-license.schema.json
¶
The resource at the URL resolves to a JSON document, for example:¶
{ "$id": "https://vendor.example/credentials/schema/trade-license.schema.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Trade License", "type": "object", "properties": { ...¶
The resource at this location SHOULD be served with media type application/json
, but MAY be served with the more specific media type application/schema+json
.¶
Schemas MUST be cached locally prior to their use, and MUST NOT be resolved over the network just in time, after verification.¶
Schema checks MUST be performed after credential verification, but before any business processing or policy decisions are made based on the credential claims.¶
It is important to protect the signing key used to issue credentials, as well as any confirmation keys associated with the credentials. It is RECOMMENDED that all private keys be initialized such that they cannot be exported.¶
This document has no IANA actions.¶
TODO acknowledge.¶