Credential Schemas
Learn how to work with credential schemas.
A credential schema is like a template for credentials: it defines the structure and key components that make a credential a certain kind of credential. Whether you are issuing or verifying credentials you will create credential schemas. Here you will learn how to create and work with credential schemas.
Credential schemas in Procivis One
A credential schema represents a type of credential and includes components such as:
- How the credential data is formatted and secured.
- The method used for future suspension and revocation, if any.
- The kind of claims asserted during issuance, in the form
of keys such as
NameorBirthdateand datatypes for validating the claims made. - Design and layout properties of the credential, so wallets know how to render the credential visually for the holder.
- Issuer requests about the properties of the wallet, such as whether the wallet should use software- or hardware-based keys for signing the credential on issuance.
If you are issuing
Create a schema for each kind of credential you want to issue. With each issuance you assert claims about the subject and the system then ensures that each credential created from the schema matches the desired type.
If you are verifying
Create a schema for each kind of credential you want to request information from. Then you will later create proof schemas representing more precisely the information you want to request.
For example, if you want information from a Driver's License and from a Passport, you will create a credential schema for each. Then you will create a proof schema that specifies which attributes from which credential you want to make in your request.
Related guide: Proof schemas
If you are holding
You will consume schemas to gain information about how to display the credential in the wallet and what sort of keys to use to sign during issuance and presentation.
Create a credential schema
A credential schema consists of the following components:
- Schema name
- Credential format
- Revocation method
- Claims object
- (Mandatory for certain credential formats)
- Schema ID or "Document type"
- (Optional)
- Transaction code
- Credential design
- Key security level
- Allow suspension flag
Schema name
This should be something like:
- "Driver License"
- "Employment Authorization"
- "Passport"
- "Residence Permit"
Each name must be unique but you can create as many credential schemas as you need.
Credential format
The credential format determines how the data is bundled and secured. In most cases your choice of format will be driven by the ecosystem in which you operate:
- eIDAS uses IETF SD-JWT VC and ISO mdoc
- Swiss E-ID uses IETF SD-JWT VC
- Some U.S. States are using ISO mdoc
Check the format object of your configuration for your options. When you
create your schema, be sure to reference the instance name of your chosen
format, rather than the type; multiple instances of a single credential
format could be configured.
format: {
MDOC_MOD_1: { # Reference this
type: "MDOC", # Not this
{{distinct params and capabilities}}
},
MDOC_MOD_2: { # Reference this
type: "MDOC", # Not this
{{distinct params and capabilities}}
},
}
For the complete list of natively supported credential formats, see the reference.
Revocation method
The revocation method determines the mechanism by which credentials issued
using your schema can be revoked. Your chosen credential format, along with
other configuration details, may dictate your choice of revocation method.
Check the configuration of your chosen format for
capabilities.revocationMethods for a list of all compatible revocation
methods.
Choosing a revocation method is optional. If no revocation method is chosen, issued credentials cannot be revoked.
Allow suspension flag
In addition to permanent revocation, some methods allow for temporary
suspension. For your chosen revocation method, check the
capabilities.operations for a complete list of supported operations.
If your method allows for suspension and you would like credentials issued
with your schema to allow for suspension, pass "allowSuspension": true,
during schema creation.
Claims object
A crucial part of your schema is the set of attributes about which you will be making assertions. These are all the fields typically seen on credentials such as:
- Name
- Age
- Birthdate
- Address
- and so on...
When you create your schema you must specify all of the attributes about which claims will later be asserted. Here's an example claims object for a simple credential schema:
"claims": [
{
"array": false,
"claims": [],
"datatype": "STRING",
"key": "Name",
"required": true
},
{
"array": false,
"claims": [],
"datatype": "BIRTH_DATE",
"key": "Birthdate",
"required": false
},
{
"array": true,
"claims": [],
"datatype": "STRING",
"key": "Address",
"required": true
}
],
For each claim we assign:
- Key, or claim name
- Whether the claim is required
- The datatype of the claim
- Whether the claim allows an array to be passed for this claim during issuance
- If the datatype of the claim is an
OBJECT, the nested claims go in theclaimsarray. Otherwise, leave this empty.
Claim key
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.
Required flag
If the claim is required and no value is passed during credential issuance the credential will fail to be created.
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
EMAILdatatype instance might be aSTRINGwith a specific regex pattern. - The
MDL_PICTUREdatatype instance might be aFILEthat accepts only jpeg and usesencodeAsMdlPortraitto 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_DATEdatatype that restricts valid dates to 1900-01-01 and after with aminparam. - The
EMAILdatatype that ensures the proper regex pattern. - The
POSTAL_CODEdatatype 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",
"keyStorageSecurity": "BASIC"
}
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.
Schema ID or "Document type"
For certain credential formats, the schema ID transmits information about
the schema of a credential. You can either specify a custom schemaId
during schema creation or let the system auto-generate one.
Check the configuration of your chosen credential format for
capabilities.features: SUPPORTS_SCHEMA_ID. For formats that support
schema IDs, further guidance is provided below.
ISO mdoc
Use the schemaId field to specify the credential's DocType. To issue ISO
standard mDLs, for example, pass org.iso.18013.5.1.mDL as the schema ID
during schema creation.
If you don't specify a schema ID, the system uses the credential schema's UUID as the DocType.
For more on DocTypes, see the mdocs guide.
SD-JWT VC
Use schemaId to specify the vct value. According to the SD-JWT-VC specification:
the
vctvalue must be a case-sensitive StringOrURI (see [RFC7519]) value serving as an identifier for the type of the SD-JWT VC
The system always constructs a URL for the vct and publishes it so that
type metadata can be retrieved by external consumers of the credential:
{{base_url_of_system}}/ssi/v1/vct/{{organizationId}}/{{schemaId}}
If you specify a schemaId, that value is used in the URL. If you don't
specify one, the system auto-generates an identifier (the credential
schema's UUID) and uses that in the URL instead.
Schema ID uniqueness
Core enforces uniqueness for schema IDs within an organization — you
cannot create multiple schemas with the same schemaId.
When using Procivis One Desk, if you attempt to create a schema with
an existing schemaId, the interface will link you to the existing
schema.
Ecosystem schema IDs
Some credential formats include a list of recognized ecosystem schema
IDs in their configuration under capabilities.ecosystemSchemaIds.
These are identifiers for credentials from known ecosystems, for example:
org.iso.18013.5.1.mDL(mobile Driving License)- EU PID identifiers
When using Procivis One Desk, if you specify one of these recognized schema IDs, the interface will warn you that this is a known schema identifier. This helps ensure that credentials using these IDs conform to the expected structure and requirements for that ecosystem standard.
VC barcodes
For the verification of W3C VC Barcodes, the credential types are pre-defined by the draft specification:
UtopiaEmploymentDocumentUtopiaDrivingLicenseIdentityCard
Specify which type of credential is to be verified by passing one of the types
as the schemaId during schema creation.
For more on verifying physical credentials, see the VC Barcodes 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.
Transaction codes
Transaction codes provide an additional security layer during credential issuance by requiring holders to submit a one-time code to complete the exchange. When you include transaction code settings in a credential schema, the system automatically generates and validates codes during issuance flows.
Configuration options:
- Type:
NUMERICorALPHANUMERIC— determines the character set used for generated codes - Length: Integer from 4 to 10 — specifies how many characters the code will contain
- Description: Optional text up to 300 characters — provides context to holders about the transaction code (e.g., "Enter the code displayed on your confirmation screen")
Transaction codes are supported for OpenID4VCI issuance flows on compatible
credential formats. Check the capabilities object for a credential format
to confirm SUPPORTS_TX_CODE availability before configuring this feature.
When a credential schema includes transaction code settings, every credential
issued from that schema will require the holder to provide the generated code
to complete issuance. The system generates a unique code for each issuance
attempt and returns it in the response to POST /api/credential/v1/{id}/share.
Credential design
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
metadataof the credential. - ISO mdocs - embedded in their own namespace,
ch.procivis.mdoc_layout.1. - SD-JWT VCs - the system supports the
simplerender 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.jpgor.png. Optimized size: 722x440 px.
-
-
logo- Choose one of:-
backgroundColorandfontColor- 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.jpgor.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: [
Key storage security requirements
As an issuer, you can require holders to use specific key storage types when receiving credentials. This ensures credentials are protected at an appropriate security level for your use case.
Use the keyStorageSecurity parameter when creating a credential schema
to specify one or more acceptable key storage security levels. The wallet
must prove it can meet at least one of these requirements before the
credential is issued.
How it works
When you specify key storage security levels:
Issuer requests - You define which security levels are acceptable for your credential in the schema
Wallet responds - The wallet checks its available key storage options and selects one that matches your requirements
Attestation - The wallet provides cryptographic proof through wallet unit attestation that it meets the security requirements
Issuance - If the wallet meets your requirements, the credential is issued using a key from the appropriate storage
If the wallet cannot meet any of the specified security levels (for example, the device lacks required hardware or the levels are not configured), the issuance fails.
Available security levels
The keyStorageSecurity parameter accepts an array of one or more of these
values:
BASICENHANCED_BASICMODERATEHIGH
These levels correspond to the ISO/IEC 18045 security levels referenced
in the OpenID4VCI 1.0 specification and are constructed in your configuration.
Refer to keySecurityLevel for how configured key storage options are mapped
to these values.
Example schema creation:
{
"name": "MyDriverLicense",
"keyStorageSecurity": ["MODERATE", "HIGH"],
// ... other schema properties
}
Credentials issued using this example schema require the wallet to use
either MODERATE or HIGH key storage security levels.
Selecting multiple levels
When you specify multiple security levels, you're defining acceptable alternatives. The wallet will select any one of the specified levels that it supports and can provide.
This approach allows issuance to succeed across different wallet implementations and hardware capabilities while maintaining your minimum security requirements.
Standards compliance
Key storage security levels are part of the OpenID4VCI 1.0 specification. Any wallet implementing this standard can parse and respond to these requirements appropriately.
Secure Element and device compatability
Security level MODERATE as it is currently defined in the OpenID4CI 1.0
specification requires Secure Element, a hardware security feature not
present in all devices.
This is particularly true for Android devices, where hardware security support varies significantly across manufacturers and models.
Before deploying schemas requiring Secure Element, test with representative devices from your target user base to ensure they can complete the issuance flow.
Import credential schemas to mobile verifiers
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.