Credential schemas
The Credential schemas resource exposes functionality to create, delete, and retrieve credential schemas.
When a credential is issued, it is issued using a credential schema. A credential schema is essentially a set of attributes that defines the content and the format of the credential to be issued.
For instance, if the system is being used to issue both a driver's license credential and a certificate of residency credential, there might be a "Driver's License" credential schema with one set of attributes (for example, certification of passing the driving test, address, types of vehicles a driver is allowed to operate, and so forth) and a "Certificate of Residency" credential schema with a different set of attributes (for example, residence address and name). If the configuration supports multiple credential formats, the first credential schema could be defined to issue credentials with one format and the second with another.
The system supports the creation of as many credential schemas as is needed.
Credential formats
Choose a credential format to determine how the credential data should be formatted and secured.
The following table shows what kind of credential corresponds to each type
in the
format
object of the system configuration.
The configuration determines which credential formats are available for use. The
instance name of the credential type
is the value used when creating and retrieving
credentials of that type. This could differ from the type
value itself, so check
the configuration.
Each credential schema uses one and only one credential format.
Revocation methods
A revocation method can be chosen, enabling the issuer to revoke an issued credential.
The configuration determines which revocation methods are available for use. See the revocation
object
of the configuration. Each type
of revocation method has its own property name*
. The property name*
can be
unique to the configuration and is the value used when creating and retrieving credential schemas using that
type of revocation method.
See the configuration guide for more on reading the configuration.
LVVC
One method of handling credential revocation in a privacy-preserving manner is to give the credential a short lifespan, requiring the holder's agent to update the credential on a regular basis. One benefit of this method is that it doesn't require interaction between the verifier and the issuer, thus preserving the holder's privacy. One drawback to this method is scalability: repeated transmission of large credentials takes up memory and bandwidth.
LVVC is based on this method of updating credentials with one key difference: when a credential with LVVC revocation is first issued, an extra credential is issued, the "LVVC". The LVVC is linked to the original credential and is small, containing only basic information about the issuer and the issuance time. This LVVC has a short lifespan, and the holder's agent (that is, wallet) must request a new LVVC when it needs one. When the issuer revokes the credential, the LVVC is updated to revoked status and no further LVVCs are created for that credential. This process eliminates the need for the verifier to connect to the issuer in any way to check revocation status, preserving privacy for the holder.
For more information on the LVVC revocation method, see the initial draft.
Verify LVVC credentials
The verifier can specify the age of the LVVC which they still consider to be valid at
the proof schema level. When creating a proof schema, specify the duration (in seconds) in the
validityConstraint
field of the proofInputSchemas
object.
Each LVVC credential has an lvvcIssuanceDate
; if the time since a credential lvvcIssuanceDate
exceeds the validityConstraint
of the proof request, the credential will not be validated.
Issue LVVC credentials
The issuer's system configuration determines the "expiration" of credentials issued with LVVC revocation
method. If the holder's wallet checks the revocation status after the credential has expired, assuming
the credential has not been revoked, the system issues a new LVVC with a new lvvcIssuanceDate
.
Example configuration:
LVVC:
display: 'revocation.lvvc'
order: 2
type: 'LVVC'
params:
private:
credentialExpiry: 3600 // Time, in seconds, after which an issued LVVC expires
Hold LVVC credentials
The holder's wallet can check the revocation status via the /api/credential/v1/revocation-check
endpoint.
Claims object
A credential is an assertion about a subject. The claims
object of the credential schema defines the kind of
data being asserted when issuing a credential. It is an array defining the set of attributes about which the issuer
will be making claims.
For example, if an issuer is issuing "Certificate of Residency" credentials, the credential schema might consist
of an array of two items: name and address. In this case the key
s could simply be "Name" and "Address", with both
items required: true
and datatype: STRING
. Anytime the issuer uses this credential schema to issue a credential,
strings must be provided for the name and address fields of the credential subject.
The claims
object returned when retrieving proof requests by ID includes the additional element of the claim being
asserted (that is, the actual value submitted for "Name" and "Address") when a valid proof has been submitted for that
proof request.
For the path
value of the claims
object, see the claimValues guide.
Some credential formats (JSON-LD, for example) disallow certain strings as keys for claims, to avoid collision with other fields of the credential.
When retrieving the configuration through the API, the forbiddenClaimNames
capability of credential formats lists any restricted claim keys.
Datatypes
When creating a credential schema, you must specify a datatype for each
claim in your claims
object. These datatypes determine how the claim
data will be validated during credential issuance and verification.
How datatypes work
The system configuration defines specific datatype instances with validation rules. For example:
- The
EMAIL
datatype instance might be aSTRING
with a specific regex pattern. - The
MDL_PICTURE
datatype instance might be aFILE
that accepts only jpeg and usesencodeAsMdlPortrait
to ensure correct encoding for an ISO Mobile Driving License.
- The
When creating a credential schema, reference these configured datatypes for each claim.
During issuance, when an issuer makes claims about a subject, the claim values are validated against the rules defined in the corresponding datatype.
Suppose you retrieve the configuration and it includes the following for
the datatype
object:
"datatype": {
"BIRTH_DATE": {
"type": "DATE",
"display": "datatype.birth_date",
"order": 310,
"params": {
"min": "1900-01-01",
"max": "NOW",
"error": {
"de": "Bitte wählen Sie ein Datum zwischen 1900-1-1 und heute",
"en": "Please choose a date between 1900-1-1 and today"
}
}
},
"EMAIL": {
"type": "STRING",
"display": "datatype.email",
"order": 110,
"params": {
"autocomplete": true,
"placeholder": "abc@abc.com",
"pattern": "^[\\w\\-\\.]+@([\\w\\-]+\\.)+[\\w\\-]{2,4}$",
"error": {
"de": "Bitte geben Sie eine gültige E-Mail Adresse ein",
"en": "Please provide a valid email address"
}
}
},
"POSTAL_CODE": {
"type": "NUMBER",
"display": "datatype.postal_code",
"order": 200,
"params": {
"min": "5",
"max": "5",
}
},
"STRING": {
"type": "STRING",
"display": "datatype.string",
"order": 100
},
},
Using this hypothetical configuration, here's an example call that uses:
- The
BIRTH_DATE
datatype that restricts valid dates to 1900-01-01 and after with amin
param. - The
EMAIL
datatype that ensures the proper regex pattern. - The
POSTAL_CODE
datatype that restricts entries to numbers with exactly five digits.
"claims": [
{
"array": false,
"claims": [],
"datatype": "STRING",
"key": "Name",
"required": true
},
{
"array": false,
"claims": [],
"datatype": "EMAIL",
"key": "Email",
"required": true
},
{
"array": false,
"claims": [
{
"array": false,
"claims": [],
"datatype": "STRING",
"key": "Street",
"required": true
},
{
"array": false,
"claims": [],
"datatype": "STRING",
"key": "City",
"required": true
},
{
"array": false,
"claims": [],
"datatype": "POSTAL_CODE",
"key": "Postal code",
"required": true
}
],
"datatype": "OBJECT",
"key": "Address",
"required": true
},
{
"array": false,
"claims": [],
"datatype": "BIRTH_DATE",
"key": "Birthdate",
"required": true
}
],
Check the datatype
object of the configuration for the supported
datatypes. See the datatypes reference
for details on available types and their parameters.
Nested claims
Use the OBJECT
datatype to create nested claims (that is, claims within claims). A claim with type OBJECT
must contain
at least one other claim (of any data type) within it and can contain one or more objects. Otherwise, claims with type
OBJECT
behave as other claims: they have a name and they are either required or not. All claims within the object are
placed within the claims
array for that claim. For claims of other data types, the claims
array is empty.
Consider the following structure:
-
Claim 1 (object)
-
Claim 2
-
Claim 3 (object)
- Claim 4
-
Claim 1 is an object that contains all the other claims in the structure, including claim 3, which is itself an object containing claim 4.
The API call to create a credential schema with this structure:
{
"claims": [
{
"array": false,
"claims": [
{
"array": false,
"claims": [],
"datatype": "STRING",
"key": "Claim 2",
"required": true
},
{
"array": false,
"claims": [
{
"array": false,
"claims": [],
"datatype": "STRING",
"key": "Claim 4",
"required": true
}
],
"datatype": "OBJECT",
"key": "Claim 3",
"required": true
}
],
"datatype": "OBJECT",
"key": "Claim 1",
"required": true
}
],
"format": "SDJWT",
"layoutType": "CARD",
"name": "Nested claims example",
"revocationMethod": "BITSTRINGSTATUSLIST",
"walletStorageType": "SOFTWARE"
}
Arrays
Claims can be made into arrays so multiple values can be input for the same key during issuance.
In the following example, a credential schema makes a claim of a phone number and
passes true
for the optional array
value.
"claims": [
{
"array": true,
"claims": [],
"datatype": "NUMBER",
"key": "Phone number(s)",
"required": true
},
]
When issuing a credential with this schema, the issuer can add multiple phone numbers within the same claim.
Request a wallet storage type
As an issuer, you can request that the holder's wallet use a key stored with a particular technology to sign the credential during issuance.
The type of key storage used by the holder's wallet influences the security of the credential and the assurance the verifier has that the credential being presented is securely bound to the person presenting it. It also impacts user convenience.
Use the walletStorageType
param to specify which type of storage the
wallet should use.
Wallet behavior
For wallets supporting this feature:
-
If no value is passed, the wallet is free to choose a key to sign the issuance.
-
If a value is passed, the wallet will only accept and sign the issuance with the specified wallet storage type. If the specified type is not enabled in the wallet then the credential issuance will fail. This could be because the holder's device is not equipped with the needed hardware or because the storage type is not enabled in the wallet's configuration.
Options
You can request:
SOFTWARE
- Keys are stored and managed by the wallet software, and protected by standard encryption.
- Easy to deploy and manage. Keys can be backed up, recovered, and transferred to new devices.
- Vulnerable to software attacks, and to physical attacks if attacker has access to the device.
HARDWARE
- Keys are stored on and protected by tamper-resistant hardware on the holder's device.
- Resistant to software attacks.
- Keys are bound to one device. The verifier can be assured the credential was issued to the same device that is presenting it.
- If the holder loses their device or upgrades to a new device, the credentials must be reissued to the new device.
REMOTE_SECURE_ELEMENT
- Keys are stored on and protected by tamper-resistant hardware in a data center.
- A secure link is established between the holder's device and the HSM. The user must input a PIN code or use biometrics each time they use a key.
- If the holder loses their device or upgrades to a new device, the data is still protected in the HSM and a link to a new device can be established, recovering the holder's data.
Consider the required level of security and assurance needed for the use case, and balance against cost and convenience.
Limitations
- This feature is not part of a standard protocol and is not necessarily enforced by other wallets. Wallets from other vendors could ignore the requirement for a certain key type.
- During proof schema creation, the system does not allow combining
credentials which use different key storage types. This is because the
holder's wallet signs the presentation with one key and that key must match
the key used to sign the credential during issuance. For proof requests with
multiple credentials, all credentials must have the same
walletStorageType
. See the proof schemas guide for more information.
credentialSchema property
The credentialSchema
field of W3C VCs is optional according to the
specification but is useful
for defining the structure of the credential and providing verifiers with a means to check if
the data of a credential conforms to the schema published by the issuer. All credentials in
Procivis One utilize this property.
In the specification, a credentialSchema
consists of two items: its type
and an id
consisting of a URI that identifies the schema file. In Procivis One, these values are
found in the schemaType
and schemaId
fields, respectively. The values of these fields
are specified in the following sections.
schemaType
The system assigns a schema type, described below.
ISO mdoc
Whether creating a schema or receiving credentials, all mdoc credentials are
assigned schema type mdoc
.
All other formats
When creating a schema, the system assigns ProcivisOneSchema2024
as the schema type.
When receiving a credential, the system looks for the schema type as defined by
the issuer. If the system finds the schema type, it uses it. In cases where the
system is unable to find the schema type, it assigns FallbackSchema2024
.
schemaId
The schema ID is an important field for passing on or storing information on the schema of the credential.
Depending on the credential format, the schema ID is either assigned by the system or
specified by the user. Credential formats requiring a user-defined schema ID have
capabilities: features: REQUIRES_SCHEMA_ID
in their configuration.
The following describes what the system does with the schema ID in schema creation (issuance and verification) and in receiving credentials as a wallet, for different credential formats.
ISO mdoc
Whether creating a schema or receiving credentials, the schema ID is the DocType
of the credential. To issue ISO standard mDLs, for example, pass
org.iso.18013.5.1.mDL
as the schema ID during schema creation.
For more on DocTypes, see the mdocs guide.
SD-JWT VC
The vct
field of an SD-JWT VC is used to specify the type of VC.
When creating a schema, the schema ID is used to create the vct
as a
retrievable URL with the following format:
{base_url_of_system}/ssi/v1/vct/{schemaId}
When receiving a credential, the vct
is saved as the schema ID.
VC barcodes
For the verification of W3C VC Barcodes, the credential types are pre-defined by the draft specification:
UtopiaEmploymentDocument
UtopiaDrivingLicense
IdentityCard
Specify which type of credential is to be verified by passing one of the types as the schema ID during schema creation.
For more on verifying physical credentials, see the guide.
All other formats
When creating a schema for credential formats which do not require a schema ID, the system generates a globally unique URI for each credential schema.
When receiving a credential, the system looks for the schema ID as defined by the issuer. If the system finds the schema ID, it uses it. If no schema ID is found, one is generated.
Credentials designer
When creating credential schemas, use layoutType
and layoutProperties
to design the visual appearance
of the resulting credentials.
The design properties are embedded into the credential itself. The following specifies where the design properties are found within the credential itself:
- W3C VCs - in the
metadata
of the credential. - ISO mdocs - embedded in their own namespace,
ch.procivis.mdoc_layout.1
. - SD-JWT VCs - the system supports the
simple
render method, including background color and text color; all other supported design elements are found in the layout properties at the root level. The SVG template rendering method is not supported.
For any given credential format, credential design must be enabled in the configuration or the design
properties will not be passable. The embedLayoutProperties
param of credential formats defaults to
false
.
Creating a credential design is optional; if no design values are passed, a
design of type card
is auto-generated from the credential name. The credential schema of issued
credentials, including this design information, is published and the resulting URL is available in the
credentialSchema
field of the credential. This allows for digital wallets to obtain and display the
credential with the desired appearance.
Layout type
The layout type determines both the structure of how the credential will appear and the options available
in layoutProperties
for further customization.
Supported layout types:
-
CARD
- Default layout type if no value is passed; credentials with this layout type resemble a physical credential one would find in a physical wallet. -
DOCUMENT
* - Credentials with this layout type resemble a paper document with structured text fields and list elements. -
SINGLE_ATTRIBUTE
* - Credentials with this layout type display a credential name and a single attribute in a simple tab.
* (in development)
Layout properties - Card
-
background
- Choose one of:-
color
- Choose a solid color for the background of the credential; accepts any HTML value (hex, predefined, or rbga format). -
image
- Choose an image for the background of the credential; accepts.jpg
or.png
. Optimized size: 722x440 px.
-
-
logo
- Choose one of:-
backgroundColor
andfontColor
- Choose a solid color for the background of the logo and a font color for the logo text; accepts any HTML value (hex, predefined, or rbga format). Logo text is an auto-generated shortened version of the credential name. -
image
- Choose an image for the square logo of the credential; accepts.jpg
or.png
. Optimized size: 88x88 px.
-
-
primaryAttribute
- Specify a primary attribute for the credential. The primary attribute is displayed directly underneath the credential name in both credential list and credential detail views. -
secondaryAttribute
- Specify a second attribute from the credential to be shown alongside the primary attribute. -
pictureAttribute
- Display a picture from the credential. Specify the attribute of the picture. -
code
- Display a scannable code from the credential. Specify the attribute to encode and the type of code to display. Note that this encoding is not verifiable, but can still be useful for some implementations such as bridging legacy systems.- Supported code types: [
BARCODE
,MRZ
,QR_CODE
]
- Supported code types: [
Importing credential schemas
Credential schemas can be imported to mobile verifiers, enabling mobile verifiers to create their own proof schemas.
Call the Share credential schema endpoint (for Core or Desk) to generate a URL. The mobile verifier then makes an HTTP request to preview the credential schema. Call the Import credential schema (for Core) to import the credential schema.
Proof schemas can also be imported directly by mobile verifiers. See the importing proof schemas guide.