Skip to main content

Configuration

Learn how to customize and deploy solutions for your use case.

Procivis One offers numerous options for configuring your solution to meet the requirements of different identity ecosystems and IT systems. Use this page to understand how configuration works, how to read configuration files, and how to create and modify your own configuration files.

For complete reference documentation of all configuration options and their values, see the separate Configuration reference page.

After mastering these core principles of configuration, explore our specific configuration guides for:

How configuration works

To configure the system, build .yml files creating instances of the components you want to use and your desired parameters, and pass these files to cargo as an argument in the makefile.toml:

[tasks.run]
args = [
"run",
"-p",
"example-server",
"--",
"--config",
"config/base-config.yml",
"--config",
"config/override-config.yml",
]
command = "cargo"

In the example above, we start the server and then pass a base configuration as an argument to the program, followed by an override configuration. Using multiple configurations allows you to set environment-specific configurations and maintain deployment flexibility.

The configuration is exposed via the API in a limited way:

  • The configuration is read-only via the API.
  • Private parameters are not exposed via the API.
  • The app and task root-level objects are not exposed via the API.
  • The API version of the configuration returns capabilities, reports that reflect properties of instances in the configuration. These capabilities are neither directly modifiable nor visible in the configuration files, but they are useful for integration.

Related guide: Configuration in the API

Configuration templates

To get started, you have several options:

  • Use the base configuration: config-procivis-base.yml from the one-core. This includes nearly every supported component.
  • Use a simpler example configuration. This is recommended if you just want to try out issuing and verifying and aren't looking for any particular tech stack.
  • Build your own configuration from scratch.

Configuration override

The base configuration does not provide encryption keys to encrypt sensitive data such as private keys and tokens. Create a .yml file and provide encryption keys for each instance of an OpenID4VC issuance protocol and internal key storage:

  • issuanceProtocol.[instanceName].type: 'OPENID4VCI_DRAFT13'
  • keyStorage.[instanceName].type: 'INTERNAL'

Encryption keys must be a 32 byte hex-encoded value. Use:

openssl rand -hex 32

or another qualified tool to generate a cryptographically-secure key. For each instance, put its encryption key in params.private.encryption of the override configuration.

Your override configuration file should look something like this:

issuanceProtocol:
OPENID4VCI_DRAFT13:
params:
private:
encryption: '93d9182795...'
keyStorage:
INTERNAL:
params:
private:
encryption: 'd783157dac...'

Alternatively you can put your encryption keys in environment variables.

Environment variables

Set environment variables using the following naming pattern:

ONE_path__to__variable

Examples:

ONE_app__databaseUrl: 'mysql...'
ONE_keyStorage__INTERNAL__params__private__encryption: 'd783157dac...'

Build a configuration

The following is a sample entry:

exampleRootObject:
instanceName:
type:
display:
order:
params:
enabled:

The next sections explain each of the components of entries.

Define root-level objects

The following are root-level configuration objects:

ObjectWhat it configures
format: {}Credential formats for issuing, holding and verifying.
issuanceProtocol: {}Exchange protocols for credential issuance.
verificationProtocol: {}Exchange protocols for presentation verification.
revocation: {}Revocation methods for credential status.
did: {}DID methods used for identifying agents.
keyAlgorithm: {}Key algorithms used for signatures.
keyStorage: {}How keys are stored.
datatype: {}Data types for claim validation.
task: {}Maintenance tasks typically run at intervals.
trustManagement: {}Trust management solutions.
transport: {}Transport protocols over which to communicate.
cacheEntities: {}Entities held in temporary storage.
openidProvider: {}OpenID provider management and credential login. Desk API-only.
app: {}Server settings of a deployed solution.

For any given component of the solution, its root-level object must be in the configuration and have at least one instance enabled in order to function.

Modularity

The system is modular. For example, you could have only did in your configuration if you only wanted to resolve DIDs. You could then add keyAlgorithm and keyStorage to enable key and DID creation, and so on.

While our base configuration has been thoroughly tested, we encourage users implementing custom component combinations to conduct appropriate validation testing in their environment to ensure optimal performance.

Revocation

If you are issuing credentials you must have at least one instance of a revocation method configured and enabled. This is because you must name a revocation method during credential schema creation.

If you want to issue credentials with no revocation method, ensure you have an instance of type: "NONE" enabled in the configuration:

revocation:
NONE:
display: 'revocation.none'
order: 0
type: 'NONE'
params: null

Then reference this instance when you create your credential schema.

Conversely, if you do not want to allow credentials to be issued without a revocation method you have two options:

  • Configure the type: "NONE" and disable it:
revocation:
NONE:
display: 'revocation.none'
order: 0
type: 'NONE'
params: null
enabled: false
  • Have no revocation method of type: "NONE" configured. Ensure there is at least one supported revocation method enabled or you will not be able to create a credential schema.

Name the instance

The instance name is how you invoke a configured instance of a solution component. This allows for flexibly configuring different instances of the same type of technology.

For example, here is a sample configuration of two instances of FILE in the datatype object. Because the ISO 18013-5 standard specifies particular requirements for the format and encoding of portraits, we use two different instances for picture datatypes:

datatype:
PICTURE:
display: 'datatype.picture'
type: 'FILE'
order: 400
params:
public:
accept:
- image/jpeg
- image/png
fileSize: 4194304
showAs: IMAGE
MDL_PICTURE:
display: 'datatype.mdlPicture'
type: 'FILE'
order: 402
params:
public:
accept:
- image/jpeg // only jpeg is allowed for mDL portraits
fileSize: 4194304
showAs: IMAGE
encodeAsMdlPortrait: true // this param ensures proper encoding for mDL standard

When we create a credential schema for an ISO mdoc that meets the mDL standards, we use MDL_PICTURE as the datatype for the portrait claim. This provides datatype validation when we create and issue a credential using this schema.

When we create a credential schema for some other format, and no longer need to meet ISO 18013-5 mDL standards, we use PICTURE for the portrait claim.

Configure the instance

Most configuration entries have the following variables:

VariableRequiredDefaultDescription
typetruenullDetermines which of the supported technologies is used by the instance.
displaytruenullA key which should resolve to something stored in the frontend.
ordertruenullAn integer passed to the frontend without interpretation to indicate the order in which instances appear in the UI. See the exception below.
paramsfalsenullDefine variables for an instance.
enabledfalsetrueInstances are enabled by default. Set this to false to disable an instance.
Exceptions
  • app has its own set of variables.
  • keyAlgorithm has no type variable. The type information is taken directly from the instance name, which must match the supported names exactly.
  • For the transport provider on configurations of mobile devices, the order determines the preferences for which transport protocol to use during exchanges where multiple transport protocols are supported.

See the relevant section of the configuration reference for details on each root-level object.

Disable an instance

Instances are enabled by default. Use enabled: false to disable an instance to:

  • Test and debug components.
  • Stop new entities from being created while still allowing existing entities to function.

Disabling a component allows for soft transitions to new technologies. For example, suppose you use did:web to create DIDs and issue and verify credentials with those DIDs. If you want to stop using did:web you can disable it in the configuration. You will still be able to issue and verify credentials using existing did:web DIDs but you will no longer be able to create new did:web DIDs.

If you instead delete the did:web instance from the configuration, you will no longer be able to use those did:web DIDs. The DIDs will still exist in the database but will return an error if used for operations.

Configure parameters

Parameters are the primary means of defining variables for instances in the system. All params entries are split into public and private:

params:
public:
exampleParam: 100
private:
exampleParam: 3000

Public params are exposed in the API while private params can only be seen in the configuration files.

Parameters are specific to each root-level object and type.

See the configuration reference for the complete list of available parameters.