Caution
The Curity Identity Server support for verifiable credential issuance is experimental and should not be used in production scenarios. The described capabilities, configuration model, and associated behavior may change between releases of the Curity Identity Server in a way that is not backward compatible.
The Curity Identity Server supports verifiable credential issuance (VCI), as defined by OpenID for Verifiable Credential Issuance (draft 11), henceforth identified as OpenID4VCI. For the moment being, this support is being added to the Curity Identity Server for experimentation and evaluation purposes only. By default the verifiable credential issuance functionality is disabled. Run the Curity Identity Server with the se.curity.verifiable-credentials.enable system property set to true to enable it.
se.curity.verifiable-credentials.enable
true
The verifiable credential issuance behavior is mostly configured in the verifiable-credentials setting, added to the Token Service profile configuration. It is comprised by two main child settings:
Each verifiable-credentials/verifiable-credential contains both generic settings, applicable to all credential formats, as well as settings that are specific to the format used by that credential kind.
The following sections provide more information about this configuration model.
The OpenID for Verifiable Credential Issuance (draft 11) specification aims to support multiple verifiable credential formats and associated data models. In the current version, the Curity Identity Server supports the jwt_vc_json format, where verifiable credentials follow the W3C Verifiable Credential Data Model 1.1 and are packaged inside signed JSON Web Tokens. Future versions may add support for other signature packaging methods or different verifiable credential data models.
In the W3C data model, “the type property is used to uniquely identify the type of the verifiable credential in which it appears, i.e., to indicate which set of claims the verifiable credential contains”. the Curity Identity Server follows this guidance by having a configuration model where:
The verifiable credential issuance functionality adds the oauth-verifiable-credential endpoint type. Endpoints of this type are responsible for receiving credential requests and producing credential responses, containing the issued verifiable credentials, as defined by the OpenID4VC draft specification.
oauth-verifiable-credential
A Token Service profile can have zero or more verifiable credential endpoints, which are created, configured, and deployed like any other endpoint of the profile.
If enabled, the verifiable credential issuance functionality will expose the Credential Issuance Metadata in a subpath of the anonymous endpoint, namely in the well known path /.well-known/openid-credential-issuer (see verifiable-credentials/expose-metadata). The full path depends on the configuration details such as base URL, service role and anonymous endpoint. See verifiable-credentials/expose-metadata for more information. Each entry in the credentials_supported array of the Credential Issuer Metadata corresponds to a verifiable-credentials/verifiable-credential entry.
/.well-known/openid-credential-issuer
Each oauth-verifiable-credential endpoint can be configured to use a token procedure, allowing the programmatic customization of credential responses, analogously to what is possible for other Token Service endpoints. These procedures can be implemented by scripts or by SDK token procedure plugins.
The Curity Identity Server supports the generic credential request parameters format and proof, as defined by the OpenID4VCI generic credential request. In addition, it also supports the format-specific parameters types and credentialSubject, as defined by the OpenID4VCI jwt_vc_json credential request:
format
proof
types
credentialSubject
format (mandatory) - must have the value jwt_vc_json, which is currently the only format supported by the Curity Identity Server.
jwt_vc_json
proof (mandatory) - must contain a proof of possession for the key material associated to the subject DID (Decentralized Identifier). The specified type must be jwt. Currently, the issued verifiable credentials need to have a DID as the credential subject identifier. The credential request needs to prove that the requester does hold the private key material associated to that DID. Consequently, the proof parameter must include a JWT with the following properties:
A mandatory kid header property, holding a DID URL pointing to the subject’s verification key. When issuance is successful, the issued verifiable credential will use the DID from this DID URL as the credential’s subject identifier. An optional jwk header property, containing the subject’s verification key. This property is only needed when the used DID method does not provide enough information to fully retrieve the key (e.g. EBSI Natural Person DID).
kid
jwk
types (mandatory) - must contain the types of the issued credential, according to what is defined by the W3C data model. The request types must exactly match what is configured by a verifiable-credential configuration entry, otherwise the issuance will be denied. The supported combination of types is present in the exposed metadata.
credentialSubject (optional) - can contain the optional subject claims that also should be included in the issued verifiable credential. By default only the mandatory claims for the requested set of types is included in the issued verifiable credential. By using this parameter, the client/wallet can ask for the inclusion of additional optional claims. The claims for each set of types, as well if they are mandatory or optional, are described in the exposed metadata.
The supported DID methods for subject identification are configured by the verifiable-credentials/verifiable-credential/w3c-vc/allowed-subject-did-methods setting. It is expected that the Curity Identity Server in the future will support more DID methods for subject identification.
Any DID method is supported for issuer identification, as long as the key used by the token issuer has a external-id containing a DID URL.
The signature and issuance of verifiable credentials with the jwt_vc_json format is done by custom token issuers with the verifiable-credential purpose, which is currently only allowed for token issuers with the jwt type. Each verifiable credential kind (i.e. each verifiable-credentials/verifiable-credential entry) can use a distinct token issuer.
verifiable-credential
jwt
A credential request needs to include an access token granting:
A way for a client/wallet to obtain such an access token is by using the OAuth 2.0 authorization_code grant. The authorization request, used to obtain that authorization code, needs to specify the above access token requirements by using scopes, as partially defined by OpenID4VCI. For that, the scope parameter needs to:
authorization_code
scope
openid_credential
This section contains a brief summary of the verifiable issuance configuration model.
verifiable-credentials - Root for the verifiable credentials issuance configuration.
name - Name for the verifiable credential issuer, used on the issuer metadata. expose-metada - Used to enable and configure the exposure of verifiable credential issuance metadata. w3c - Root for the shared settings that are specific to the W3C VC data model. type - Each type list entry defines a W3C data model type, characterized by a simple name (e.g. UniversityDegreeCredential), a fully qualified name (e.g. https://example.org/examples#UniversityDegreeCredential) and the set of subject claims that should be added to verifiable credentials with this type, defined via references to claims or scopes. verifiable-credential - Each verifiable-credential list entry defines an issuance template for a kind of verifiable credential, i.e., defines how that credential kind should be created. credential-ttl - Defines the validity duration of the verifiable credential. data-model/w3c-vc - Contains configuration settings specific to verifiable credentials that follow the W3C verifiable credential data model. context - Defines the contents of the @context verifiable credential property. schema - Defines the contents of the credentialSchema verifiable credential property. token-issuer - Defines the token issuer used to sign the verifiable credential. The token issuer purpose must be verifiable_credential and its type defines how the verifiable credential is signed. Currently, the only supported type is jwt, meaning that the verifiable credential will be contained inside a JSON Web Token, i.e., have the jwt_vc_json format. issuer - Defines the value of the issuer verifiable credential property, containing the issuer identifier, which can be: The same as the Token Service issuer. An explicitly defined URI. The URI infered from the token issuer’s Key ID (KID) identifiying the cryptographic key used to sign the verifiable credential, applicable when that KID is a DID URL. On the Curity Identity Server, this KID can be defined by using the key’s external-id. allowed-subject-did-methods - Defines the DID methods allowed for the subject identification.
name - Name for the verifiable credential issuer, used on the issuer metadata.
name
expose-metada - Used to enable and configure the exposure of verifiable credential issuance metadata.
w3c - Root for the shared settings that are specific to the W3C VC data model.
type - Each type list entry defines a W3C data model type, characterized by a simple name (e.g. UniversityDegreeCredential), a fully qualified name (e.g. https://example.org/examples#UniversityDegreeCredential) and the set of subject claims that should be added to verifiable credentials with this type, defined via references to claims or scopes.
type
UniversityDegreeCredential
https://example.org/examples#UniversityDegreeCredential
verifiable-credential - Each verifiable-credential list entry defines an issuance template for a kind of verifiable credential, i.e., defines how that credential kind should be created.
credential-ttl - Defines the validity duration of the verifiable credential. data-model/w3c-vc - Contains configuration settings specific to verifiable credentials that follow the W3C verifiable credential data model. context - Defines the contents of the @context verifiable credential property. schema - Defines the contents of the credentialSchema verifiable credential property. token-issuer - Defines the token issuer used to sign the verifiable credential. The token issuer purpose must be verifiable_credential and its type defines how the verifiable credential is signed. Currently, the only supported type is jwt, meaning that the verifiable credential will be contained inside a JSON Web Token, i.e., have the jwt_vc_json format. issuer - Defines the value of the issuer verifiable credential property, containing the issuer identifier, which can be: The same as the Token Service issuer. An explicitly defined URI. The URI infered from the token issuer’s Key ID (KID) identifiying the cryptographic key used to sign the verifiable credential, applicable when that KID is a DID URL. On the Curity Identity Server, this KID can be defined by using the key’s external-id. allowed-subject-did-methods - Defines the DID methods allowed for the subject identification.
credential-ttl - Defines the validity duration of the verifiable credential.
credential-ttl
data-model/w3c-vc - Contains configuration settings specific to verifiable credentials that follow the W3C verifiable credential data model.
context - Defines the contents of the @context verifiable credential property. schema - Defines the contents of the credentialSchema verifiable credential property. token-issuer - Defines the token issuer used to sign the verifiable credential. The token issuer purpose must be verifiable_credential and its type defines how the verifiable credential is signed. Currently, the only supported type is jwt, meaning that the verifiable credential will be contained inside a JSON Web Token, i.e., have the jwt_vc_json format. issuer - Defines the value of the issuer verifiable credential property, containing the issuer identifier, which can be: The same as the Token Service issuer. An explicitly defined URI. The URI infered from the token issuer’s Key ID (KID) identifiying the cryptographic key used to sign the verifiable credential, applicable when that KID is a DID URL. On the Curity Identity Server, this KID can be defined by using the key’s external-id. allowed-subject-did-methods - Defines the DID methods allowed for the subject identification.
context - Defines the contents of the @context verifiable credential property.
@context
schema - Defines the contents of the credentialSchema verifiable credential property.
credentialSchema
token-issuer - Defines the token issuer used to sign the verifiable credential. The token issuer purpose must be verifiable_credential and its type defines how the verifiable credential is signed. Currently, the only supported type is jwt, meaning that the verifiable credential will be contained inside a JSON Web Token, i.e., have the jwt_vc_json format.
token-issuer
verifiable_credential
issuer - Defines the value of the issuer verifiable credential property, containing the issuer identifier, which can be:
issuer
The same as the Token Service issuer. An explicitly defined URI. The URI infered from the token issuer’s Key ID (KID) identifiying the cryptographic key used to sign the verifiable credential, applicable when that KID is a DID URL. On the Curity Identity Server, this KID can be defined by using the key’s external-id.
external-id
allowed-subject-did-methods - Defines the DID methods allowed for the subject identification.
Note
The access to the root verifiable-credentials configuration setting is hidden by default in the bin/idsh command line interface tool, since the verifiable credential issuance feature is still experimental. Running the command unhide verifiable-credentials on the bin/idsh shell will make the verifiable-credentials configuration setting usable on that shell.
bin/idsh
This section illustrates the verifiable credential issuance configuration model via a brief example, which:
signing-key
purpose-type
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
<config xmlns="http://tail-f.com/ns/config/1.0"> <facilities xmlns="https://curity.se/ns/conf/base"> <crypto> <signing-keys> <!-- Defining the key used to sign the verifiable credential --> <signing-key> <id>esbi-1</id> <keystore>...the key contents...</keystore> <curve-name>P-256</curve-name> <type>elliptic-curve</type> <external-id>...the DID URL of the key...</external-id> </signing-key> </signing-keys> </crypto> </facilities> <profiles xmlns="https://curity.se/ns/conf/base"> <profile> <id>oauth-dev</id> <type xmlns:as="https://curity.se/ns/conf/profile/oauth">as:oauth-service</type> <token-issuers> <!-- Defining the custom token issuer used to create and sign the verifiable credential --> <custom-token-issuer> <id>jwt-vc-issuer-1</id> <issuer-type>jwt</issuer-type> <purpose-type>verifiable_credential</purpose-type> <data-sources> <tokens-data-source-id>...</tokens-data-source-id> </data-sources> <jwt> <algorithm>ES256</algorithm> <!-- the ID of the key previously created --> <signing-key-id>esbi-1</signing-key-id> </jwt> </custom-token-issuer> </token-issuers> <settings> <authorization-server xmlns="https://curity.se/ns/conf/profile/oauth"> <!-- Defining the subject claims, using the normal way of defining claims in Curity Identity Server --> <claims> <claim> <name>givenName</name> ... </claim> <claim> <name>familyName</name> ... </claim> <claim> <name>middleName</name> ... </claim> <claim> <name>degreeSchool</name> ... </claim> <claim> <name>degreeType</name> ... </claim> </claims> <scopes> <!-- Defining a scope as a group of claims --> <scope> <id>UniversityDegreeCredentialScope</id> <time-to-live>3600</time-to-live> <claims>givenName</claims> <claims>middleName</claims> <claims>familyName</claims> <claims>degreeType</claims> <claims>degreeSchool</claims> </scope> <scope> <!-- This special scope needs to be created because it will be required on the credential endpoint --> <id>openid_credential</id> </scope> </scopes> <verifiable-credentials> <name>Development Verifiable Credentials Issuer</name> <w3c> <!-- Defining a W3C type with the required claims --> <type> <id>https://example.org/examples#UniversityDegreeCredential</id> <simple-name>UniversityDegreeCredential</simple-name> <!-- Claims from the UniversityDegreeCredentialScope scope can included in a credential of this type but are not mandatory --> <scope>UniversityDegreeCredentialScope</scope> <!-- Claims from the address scope can included in a credential of this type but are not mandatory --> <scope>address</scope> <claim> <name>givenName</name> <mandatory>true</mandatory> </claim> <claim> <name>familyName</name> <mandatory>true</mandatory> </claim> <claim> <name>degreeType</name> <mandatory>true</mandatory> </claim> <claim> <name>degreeSchool</name> <mandatory>true</mandatory> </claim> <!-- claim middleName is included on UniversityDegreeCredentialScope but is not mandatory --> </type> </w3c> <!-- Defining a particular kind of verifiable credential, by using the type defined above --> <verifiable-credential> <id>university-degree-credential</id> <name>University Degree Credential</name> <description>A verifiable credential with your degree completion information.</description> <logo>...</logo> <!-- Defining data specific to the W3C data model --> <w3c-vc> <context> <id>W3C example</id> <uri>https://www.w3.org/2018/credentials/examples/v1</uri> </context> <!-- the reference to the type creared above--> <type>https://example.org/examples#UniversityDegreeCredential</type> <schema> <!-- example taken from https://www.w3.org/TR/vc-data-model/#data-schemas --> <id>https://example.org/examples/degree.json</id> <type>JsonSchemaValidator2018</type> </schema> <token-issuer>jwt-vc-issuer-1</token-issuer> <issuer> <!-- the issuer ID should be infered from the DID URL present in the signature key external-id --> <infer-from-kid /> </issuer> <allowed-subject-did-methods> <method>ebsi</method> </allowed-subject-did-methods> </w3c-vc> <credential-ttl>31536000</credential-ttl> </verifiable-credential> </verifiable-credentials> <client-store> <config-backed> <client> <!-- The client that will be requesting credentials --> <id>client-one</id> <scope>openid</scope> <scope>profile</scope> <scope>UniversityDegreeCredentialScope</scope> <!-- Needs to have this special scope --> <scope>openid_credential</scope> </client> </config-backed> </client-store> </authorization-server> </settings> </profile> </profiles> </config>