Canton KMS
We provide a driver that lets you use Builder Vault as an external key management service (KMS) for a Canton 3.5 participant node. This means that cryptographic keys such as namespace signing keys, protocol signing keys, and encryption keys will be protected by Builder Vault MPC.
As explained here, a Canton node can use an external KMS in two ways:
- External keys The keys are fully protected by the external KMS. The keys are generated inside the KMS and never leave the KMS.
- Enveloping Keys are generated by the Canton node and live unencrypted in the node's memory. Keys are protected at rest by enveloping (wrapping) performed by the external KMS.
The Builder Vault Canton KMS driver supports both modes of operation.
We recommend external keys mode, since it provides stronger security. It also gives the best performance when running with Builder Vault Canton KMS.
While Canton 3.4 nodes can use AWS/GCP/Azure as external KMS, support for driver-based external KMS was first introduced in Canton 3.5. So Builder Vault only works with Canton 3.5 or later.
| Canton Node | Builder Vault KMS |
|---|---|
| Canton 3.5 | Builder Vault 73.3 LTS or later Builder Vault Canton KMS driver v73.4.0 Builder Vault Canton KMS Admin Tool v73.4.0 |
| Canton 3.4 | Not supported |
External Keys with Builder Vault Canton KMS
Builder Vault Canton KMS supports the external keys mode of operation with the following cryptographic keys and algorithms. These are a subset of the schemes used in Canton. The last column in the tables below shows which MPC protocol must be enabled in the Builder Vault MPC node configuration in order to support the given key/algorithm.
| Key Spec | Purpose | Builder Vault MPC Configuration |
|---|---|---|
| EC-P256 [ec-p-256] | Signing and encryption | [DKLs23] [SEPD20ECDH] |
| EC-P384 [ec-p-384] | Signing | [DKLs23] |
| EC-Secp256k1 [ec-secp-256k-1] | Signing | [DKLs23] |
| EC-Curve25519 [ec-curve-25519] | Signing | [SEPD19S] |
| RSA-2048 | Encryption | [ADN06] |
| Algorithm | Purpose | Supported Key Specs | Builder Vault MPC Configuration |
|---|---|---|---|
| Ed25519 [ed-25519] | Signing | EC-Curve25519 | [SEPD19S] |
| EC-DSA-SHA256 [ec-dsa-sha-256] | Signing | EC-P256, EC-Secp256k1 | [DKLs23] |
| EC-DSA-SHA384 [ec-dsa-sha-384] | Signing | EC-P384 | [DKLs23] |
| ECIES-HMAC-SHA256-AES128-CBC [ecies-hkdf-hmac-sha-256-aes-128-cbc] | Encryption | EC-P256 | [SEPD20ECDH] |
| RSA-OAEP-SHA256 [rsa-oaep-sha-256] | Encryption | RSA-2048 | [ADN06] |
Builder Vault does not support generating RSA-2048 keys, but it can use RSA-OAEP-SHA256 for encryption if you import an RSA-2048 key. However, we recommend that if you use Builder Vault for external keys, that you configure your Canton participant node to use ECIES for encryption and rotate any existing RSA keys to ECIES keys.
Installation
Testing with Canton LocalNetThe following explains how to install the Builder Vault Canton KMS in general.
Alternatively, you can follow the tutorial in our demo repository here. It show how to run a Canton participant node configured with Builder Vault KMS, all as local containers on your own machine.
You first need an instance of Builder Vault v73.3 LTS or later. For testing, you can deploy Builder Vault locally as explained here. Each MPC node in Builder Vault needs to be configured with API key authentication. See this for more on how to generate fresh API keys. It must also have the following features enabled:
[[Authentication.APIKeys]]
# The API key that the Builder Vault Canton KMS driver will use to connect to this
# MPC node. Use different API keys for each MPC node.
APIKey = < Insert base64 encoded Builder Vault SDK API key here >
ApplicationID = "canton-kms"
# Required for ECDSA signatures
[DKLS23.Features]
GenerateKey = true
Sign = true
PublicKey = true
ImportKey = true
# Required for Ed25519 signatures
[SEPD19S.Features]
GenerateKey = true
Sign = true
PublicKey = true
ImportKey = true
# Required for ECIES encryption
[SEPD20ECDH.Features]
GenerateKey = true
ComputeSecret = true
PublicKey = trueThe Canton artifacts can be downloaded the Blockdaemon repositories. Contact Blockdaemon to get the required Nexus credentials.
The Canton KMS driver can be included from the Sepior JNI Maven repository. This can be done in the Maven pom file with the following blocks:
<repositories>
<repository>
<id>sepior-server</id>
<url>https://nexus.sepior.net/repository/sepior-jni</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.blockdaemon.bv</groupId>
<artifactId>canton-kms-driver</artifactId>
<version>73.4.0</version>
</dependency>
</dependencies>The credentials can be defined in a settings.xml file that can be provided to the maven build with the -s option:
<settings>
<servers>
<server>
<id>sepior-server</id>
<username>${NEXUS_USER}</username>
<password>${NEXUS_PASSWORD}</password>
</server>
</servers>
</settings>In case the jar files are required, they can be downloaded using curl:
curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD \
-O https://nexus.sepior.net/repository/sepior-jni/com/blockdaemon/bv/canton-kms-driver/73.4.0/canton-kms-driver-73.4.0.jar \
-O https://nexus.sepior.net/repository/sepior-jni/com/sepior/tsm/sdkv2/sdkv2/73.3.0/sdkv2-73.3.0.jarThe administration tool can be downloaded from the Sepior binary repository with the following command:
curl -u $NEXUS_USERNAME:$NEXUS_PASSWORD \
-O https://nexus.sepior.net/repository/libtsmclient/canton-kms-admin-tool-73.4.0.zipThen configure your Canton participant node to use the Builder Vault Canton KMS driver in external key mode. This may look like the following. (See the Canton docs for more driver-based KMS configuration.)
canton.participants.your-participant.crypto {
provider = kms
signing.keys.default = "ec-p-256"
signing.algorithms.default = "ec-dsa-sha-256"
encryption.keys.default = "ec-p-256"
encryption.keys.algorithms.default = "ecies-hkdf-hmac-sha-256-aes-128-cbc"
kms {
type = driver
name = "builder-vault-kms"
config {
# One entry per MPC node in Builder Vault.
nodes = [
{ url = "https://bv-node-1:8000", api-key = "bv-node-1-api-key" }
{ url = "https://bv-node-2:8000", api-key = "bv-node-2-api-key" }
{ url = "https://bv-node-3:8000", api-key = "bv-node-3-api-key" }]
}
}
}The above configuration assumes that your Builder Vault contains three MPC nodes, and that you want a security threshold of two. You can run with other configurations, for example with two MPC nodes and security threshold one.
Finally, run your Canton participant node with the above jar files on the classpath:
java \
-cp canton-kms-driver-73.4.0.jar:sdkv2-73.3.0.jar:jna-5.13.0.jar:canton.jar \
com.digitalasset.canton.CantonCommunityApp \
-c canton.conf # further canton argumentsBuilder Vault Java SDK requires jna-5.13.0.jar on the classpath as well. You can fetch this from the central Maven repository:
curl -O https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.13.0/jna-5.13.0.jarEnveloping with Builder Vault Canton KMS
As an alternative to external keys mode, Builder Vault can be configured for enveloping mode as follows.
You first need an instance of Builder Vault v73.3 LTS or later and you need to fetch the Builder Vault Canton KMS driver and Builder Vault Java SDK jar files, as described in the previous section.
The only difference is that instead of [DKLs13], [SEPD19S], and [SEPD20ECDH], each MPC node in Builder Vault now needs to be configured with these features enabled:
[MRZ15.AESFeatures]
GenerateKey = true
GCMEncrypt = true
GCMDecrypt = true
ImportKey = trueAnd your Canton participant node must have this configuration:
canton.participants.your-participant.crypto {
provider = jce
private-key-store {
encryption {
type = kms
}
}
kms {
# ... same as above
}
}Then restart your Canton node as above, making sure to add the jars to the classpath:
java \
-cp canton-kms-driver-73.4.0.jar:sdkv2-73.3.0.jar:jna-5.13.0.jar:canton.jar \
com.digitalasset.canton.CantonCommunityApp \
-c canton.conf # further canton argumentsThe Canton node will then generate an AES-GCM key in Builder Vault and use that key to envelope its namespace, signing, and encryption keys.
Migration
We refer to the official Canton documentation for information about how to migrate your Canton node to or from Builder Vault Canton KMS. In summary:
- External Keys Restarting your node with the external KMS enabled doesn't migrate your existing keys to the KMS. Only new keys will be generated in the KMS. To migrate existing keys to Builder Vault, you must set up a new participant with Builder Vault KMS enabled, then recreate parties and manually migrate DARs, contracts, etc., to the new participant.
- Enveloping works more seamless. Just restart your node with Builder Vault configured for enveloping. Then the node will automatically envelope all existing keys, including the root namespace key. You can migrate in the reverse direction by restarting with this special flag set in the configuration: private-key-store.encryption.reverted = true. The node will then remove the enveloping.
Admin Tool
The KMS driver ships with an admin utility that lets you do operations directly in Builder Vault. You can for example use the utility tool to rotate an existing signing key in your Canton participant node to a signing key in Builder Vault:
$ java -jar canton-kms-admin-tool-73.4.0.jar \
--config bv-admin.conf generate-key --key-id signing-v2 --type signing --curve p256Then use the canton console to rotate to the external key:
val signingFingerprint = participant1.keys.secret.list()
.find(_.publicKeyWithName.name.exists(_.unwrap == "signing"))
.map(_.publicKeyWithName.publicKey.id.unwrap)
.get
participant1.keys.secret.rotate_kms_node_key(
fingerprint = signingFingerprint,
newKmsKeyId = "signing-v2",
name = "signing"
)You can use the admin tool to validate the fingerprint of the new signing key:
$ java -jar canton-kms-admin-tool-73.4.0.jar \
--config bv-admin.conf get-public-key --key-id signing-v2 --format fingerprint
1220471744be672129c42e0c29ed898c712dd525cc8e3e62e2efbae57faf35c07986Use --help for a full list of operations:
Builder Vault Admin CLI
Usage: java -jar canton-kms-admin-tool-<version>.jar [--config <file>] <command> [options]
Global options:
--config <file> HOCON config file (default: kms-admin-tool.conf)
Commands:
generate-key Generate a new key pair in Builder Vault
--key-id <id> Key ID (name) to assign in Builder Vault [required]
--type <type> Key type: signing, encryption, symmetric [required]
--curve <curve> Curve for signing/encryption keys [default: p256]
signing: p256, p384, secp256k1, ed25519
encryption: p256
get-public-key Export the public key for an existing key
--key-id <id> Key ID [required]
--format <fmt> Output format: pem, der-hex, fingerprint [default: pem]
key-exists Check whether a key exists in Builder Vault
--key-id <id> Key ID [required]
delete-key Delete a key from Builder Vault
--key-id <id> Key ID [required]
import-key Import an external private or symmetric key into Builder Vault
--key-id <id> Key ID to assign in Builder Vault [required]
--type <type> Key type [required]
p256, p384, secp256k1: ECDSA private key scalar via --private-key-hex
ed25519: private scalar via --private-key-hex, or RFC 8032 seed via --seed-hex
aes128: 128-bit AES key (16 bytes) via --key-hex
rsa: 2048-bit RSA key in PKCS #8 format via --private-key-hex
--private-key-hex Private key scalar as hex [ECDSA; ed25519 raw scalar, RSA (PKCS #8)]
--seed-hex RFC 8032 seed as hex (derives scalar + pubkey internally) [ed25519]
--key-hex Raw AES key as hex [aes128]
Example: pre-create a rotation target for Canton key rotation:
java -jar bv-admin.jar --config bv.conf generate-key \\
--key-id signing-v2 --type signing --curve p256
Then in Canton:
`app-provider`.topology.owner_to_key_mappings.rotate_key(...)The bv-admin.conf is a configuration file containing the same as the "config" part in the "kms" section of the participant node. For example:
nodes = [
{ url = "http://tsm-node-0", api-key = "apikey0" }
{ url = "http://tsm-node-1", api-key = "apikey1" }
{ url = "http://tsm-node-2", api-key = "apikey2" }
]Updated about 9 hours ago
