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
andtask
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:
Object | What 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:
Variable | Required | Default | Description |
---|---|---|---|
type | true | null | Determines which of the supported technologies is used by the instance. |
display | true | null | A key which should resolve to something stored in the frontend. |
order | true | null | An integer passed to the frontend without interpretation to indicate the order in which instances appear in the UI. See the exception below. |
params | false | null | Define variables for an instance. |
enabled | false | true | Instances are enabled by default. Set this to false to disable an instance. |
app
has its own set of variables.keyAlgorithm
has notype
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, theorder
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.