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 13 - Implementer’s Draft 1), 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 data models, as well as settings that are specific to the data model used by that credential type.
The following sections provide more information about this configuration model.
The OpenID for Verifiable Credential Issuance (draft 13 - Implementer’s Draft 1) specification aims to support multiple verifiable credential formats and associated data models. In the current version, the Curity Identity Server supports two formats:
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:
In the SD-JWT VC data model, “A type is associated with rules defining which claims may or must appear in the Unsecured Payload of the SD-JWT VC and whether they may, must, or must not be selectively disclosable”.
The Curity Identity Server follows this guidance by having a configuration model where:
Each claim referenced by an SD-JWT VC data model type has two extra configuration settings, defining:
Two different SD-JWT VC data model types may define different mandatory or selective disclosure settings for the same claim.
If a claim is configured as being selectively disclosable and the claim value is an object, then it is also possible to configure which inner properties are selectively disclosable. As an example, consider an address claim, whose value is an object composed by the street_address and country properties.
address
street_address
country
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 credential_configurations_supported object 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:
format
proof
jwt_vc_json
vc+sd-jwt
Both the proof JWT content and the remaining credential request parameters depend on the credential format
When using the jwt_vc_json format, the proof parameter must include a JWT with the following characteristics:
kid
jwk
The jwt_vc_json format also defines the credential_definition mandatory credential endpoint request parameter, which is an object with two properties:
credential_definition
type
credentialSubject
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.
When using the vc+sd-jwt format, the proof parameter must include a JWT with the following characteristics:
The vc+sd-jwt format also defines the following specific credential endpoint request parameters:
vct
claims
The signature and issuance of verifiable credentials with the jwt_vc_json format (i.e. the W3C data model) is done by custom token issuers with the verifiable-credential purpose and the jwt type.
verifiable-credential
jwt
The signature and issuance of verifiable credentials with the vc+sd-jwt format (i.e. SD-JWT VC data model) is done by custom token issuers with the verifiable-credential purpose and the sd-jwt type.
sd-jwt
Each verifiable credential kind (i.e. each verifiable-credentials/verifiable-credential entry) can use a distinct token issuer.
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 defined by OpenID4VCI. For that, the scope parameter needs to:
authorization_code
scope
openid_credential
It is also possible to use the authorization_details authorization request parameter, as defined by RFC 9396 - OAuth 2.0 Rich Authorization Requests specification. Each authorization_details item should have the type property set to openid_credential. The remaining properties are documented in OpenID4VCI usage of authorization_details and in the OpenID4VCI credential format profiles.
authorization_details
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. vc-sd-jwt - Root for the shared settings that are specific to the SD-JWT VC data model. type - Each type list entry defines a SD-JWT VC data model type, characterized by the type identifier and the set of subject claims that should be added to verifiable credentials with this type, defined via references to claims. 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 inferred from the token issuer’s Key ID (KID) identifying 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. data-model/w3c-vc - Contains configuration settings specific to verifiable credentials that follow the SD-JWT VC data model. type - Defines the SD-JWT VC type to use for this verifiable credential. token-issuer - Defines the token issuer used to sign the verifiable credential. The token issuer purpose must be verifiable_credential and its type must be sd-jwt.
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.
UniversityDegreeCredential
https://example.org/examples#UniversityDegreeCredential
vc-sd-jwt - Root for the shared settings that are specific to the SD-JWT VC data model.
type - Each type list entry defines a SD-JWT VC data model type, characterized by the type identifier and the set of subject claims that should be added to verifiable credentials with this type, defined via references to claims.
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 inferred from the token issuer’s Key ID (KID) identifying 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. data-model/w3c-vc - Contains configuration settings specific to verifiable credentials that follow the SD-JWT VC data model. type - Defines the SD-JWT VC type to use for this verifiable credential. token-issuer - Defines the token issuer used to sign the verifiable credential. The token issuer purpose must be verifiable_credential and its type must be sd-jwt.
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 inferred from the token issuer’s Key ID (KID) identifying 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 inferred from the token issuer’s Key ID (KID) identifying 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.
data-model/w3c-vc - Contains configuration settings specific to verifiable credentials that follow the SD-JWT VC data model.
type - Defines the SD-JWT VC type to use for this verifiable credential. token-issuer - Defines the token issuer used to sign the verifiable credential. The token issuer purpose must be verifiable_credential and its type must be sd-jwt.
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
<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> <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 created 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 inferred 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>