Documentation Index
Fetch the complete documentation index at: https://docs.canton.network/llms.txt
Use this file to discover all available pages before exploring further.
Canton KMS Driver developer guide
Introduction
The Canton protocol relies on cryptographic operations such as asymmetric encryption and digital signatures. To maximize the operational security of a Canton node the corresponding private keys should not be stored or processed in cleartext. A Key Management System (KMS) or Hardware Security Module (HSM) allows you to perform such cryptographic operations where the private key resides securely inside the KMS/HSM. All nodes in Canton can make use of a KMS. AWS KMS and Google Cloud KMS are supported as of Canton v2.7. To broaden the support of other KMSs and HSMs, Canton v2.9 introduced a plug-in approach, called KMS Drivers, which allows the implementation of custom integrations. This document explains the APIs that must be implemented for a KMS Driver, provides a guide on the implementation, and describes how to configure Canton to run with a KMS Driver. Currently, the KMS Driver is only available in a Scala implementation. You can find a “mock” KMS Driver implementation built on a software-based crypto library in the Canton community repository.KMS Driver API
The two main APIs that are required for a KMS Driver are:- Driver Factory: Implements how a driver is instantiated; and the main entry point for Canton to load a driver.
- KMS Driver: Offers cryptographic operations based on the KMS.
KMS Driver Factory API v1
The factory consists of two interfaces: a generic v1 DriverFactory and a specific v1 KmsDriverFactory. Thev1.DriverFactory defines the following aspects for a generic driver:
- The type of the driver
- A name that uniquely identifies the driver
- The version of the API the driver implements and optional build information (driver version number or commit hash)
- A driver-specific configuration object with configuration parser and writer
- A create method that instantiates a driver with that factory
v1.KmsDriverFactory is a specialization of the generic DriverFactory which defines the driver type as a KmsDriver and the API version as 1.
Driver Configuration Reading & Parsing
Canton uses pureconfig configuration library to read its configuration. Given that the configuration of the driver can be embedded inside a Canton configuration file, the factory of the driver needs to specify the type of configuration, as well as configuration readers and writers. AConfigType can be a case class or as basic as a Map[String, String]. In the latter case, the config reader and writer can be defined as:
val configReader = pureconfig.ConfigReader.mapReader[String]val configWriter = pureconfig.ConfigWriter.mapWriter[String]
KMS Driver API v1
The main part of the API is thev1.KmsDriver API that defines the following operations for a KMS Driver:
- Key Generation: Asymmetric signing and encryption key pairs as well as symmetric encryption keys
- Supported Key and Algorithm Specifications: The specs supported by the driver, for example, RSA 2048 keys and RSA OAEP SHA256 asymmetric encryption.
- Signing: Sign data with a key from the KMS and the specified algorithm.
- Asymmetric Decryption: Decrypt a ciphertext with a private key from the KMS and the specified algorithm.
- Symmetric Encryption and Decryption: Encrypt or decrypt with a symmetric encryption key from the KMS. The default symmetric encryption algorithm of the KMS is used.
- Key Management: Get the public key of a private key stored in the KMS, check if a key exists, and delete a key.
- Health: Return the health of the KMS Driver instance.
Error Handling and Health
In case the driver experiences an error theFuture of the operation should be failed with a KmsDriverException. When the exception’s flag retryable is true the caller side, (that is, Canton) performs a retry with exponential backoff. This behavior is suitable for transient errors, such as network issues, resource exhaustion, etc.
In case of permanent errors, a non-retryable exception should be thrown, which either fails the current operation from where the cryptographic operation is called or causes a fatal error in the Canton node.
The driver should report its health through the health method. A Canton node periodically queries the health of the driver and reports it as part of the node’s overall health.
Develop and Test a KMS Driver
Set Up API Dependency
The Canton KMS Driver API is published as an artifact on Digital Asset’s JFrog Artifactory: https://digitalasset.jfrog.io/ui/repos/tree/General/canton-kms-driver-api You must have a Canton enterprise license and account to access the artifact. You may need to configure your build system to authenticate with a personal access token towards JFrog Artifactory. In your build system of choice, you need to depend on the API as a regular Maven-style artifact with:- organization: com.digitalasset.canton
- artifact: kms-driver-api
- version: the Canton release version, e.g., 3.3.0
Implement the API and Build the Driver
Implement thev1.KmsDriverFactory by specifying the driver’s name, configuration type with readers/writers, and the create method to instantiate a driver by creating a new class instance of your KmsDriver implementation. Specify the fully qualified name of the factory class in the file:
src/main/resources/META-INF/services/com.digitalasset.canton.crypto.kms.driver.api.v1.KmsDriverFactory
and in the following file for the base driver factory (without v1):
src/main/resources/META-INF/services/com.digitalasset.canton.crypto.kms.driver.api.KmsDriverFactory
The major part of the implementation is the v1.KmsDriver specific to the KMS/HSM to be integrated with. The supported key and algorithm specifications can be defined statically depending on the capabilities of the underlying KMS/HSM. To ensure the best compatibility with other Canton nodes, all currently specified key and algorithm specifications should be supported.
Any credentials required by the underlying KMS/HSM can either be passed through the Canton configuration file as part of the driver-specific configuration, where secrets can be resolved from the environment, or retrieved by the driver directly from the environment or any other driver-specific means.
Bundle your driver into a self-contained jar, that is, with all required libraries included in the jar. That way you only need a single driver jar when starting Canton with your KMS Driver.
KMS Driver Testing
The reusable test suite for KMS Drivers is published at canton-kms-driver-testing. Configure your build system to depend on this maven artifact in the test scope of your project (e.g. for sbt append % Test to limit the dependency to the test scope).KmsDriverTest
The main part of the test suite is theKmsDriverTest that tests the functionality of a driver against the KmsDriver API.
In the simplest form the specific driver test class extends the KmsDriverTest and allows the generation of new keys as part of the test:
KmsDriverFactoryTest
The test suite for the KMS Driver factory is structured similarly to the above:KmsDriverFactory can write the driver-specific configuration with a confidential flag being true, which means any sensitive information in the configuration such as credentials should be omitted from the written configuration. A specific test case should be added if your driver-specific configuration contains any confidential information, asserting that the sensitive information is omitted.
Run Canton with a KMS Driver
Configure Canton to run with a KMS Driver, for example, for a participant participant1:java -cp driver.jar:canton.jar com.digitalasset.canton.CantonEnterpriseApp -c canton.conf # further canton arguments
Where canton.jar depends on the Canton version, e.g., lib/canton-enterprise-3.3.3.jar. The canton.conf is a configuration file that needs to configure at least one of the nodes to use the driver KMS as outlined above. Run a ping for example with participant1.health.ping(participant1) to validate that the participant can use the configured KMS and driver.