Configure External Key Storage with GCP KMS¶
Important
Daml Enterprise license required
The following section describes the steps needed to enable External Key Storage in Canton using GCP KMS. These steps include configuring GCP KMS, as well as configuring this particular mode of operation.
GCP KMS Configuration¶
To start using this feature you must first enable a KMS for Canton.
–Configure GCP KMS for Canton–
The following IAM permissions are required:
- cloudkms.cryptoKeyVersions.create
- cloudkms.cryptoKeyVersions.useToDecrypt
- cloudkms.cryptoKeyVersions.useToSign
- cloudkms.cryptoKeyVersions.get
- cloudkms.cryptoKeyVersions.viewPublicKey
When you are using cross-account keys, you do not need the cloudkms.cryptoKeyVersions.create permission.
External Key Storage Configuration¶
External key storage support can be enabled for a new installation (i.e., during the node bootstrap) or for an existing deployment. Be aware that if a node has already been deployed you need to perform a node migration. Simply adding the following configuration is not enough.
In the example below, you configure a Canton participant node (called participant1
) to generate and
store private keys in an external GCP KMS. The same configuration is applicable for all other node entities, including the domain manager,
mediators, and sequencers.
canton.participants.participant1.crypto.provider = kms
An example configuration that puts together both KMS and external storage configuration is shown below:
canton.participants.participant1.crypto.provider = kms
canton.participants.participant1.crypto.kms {
type = gcp
location-id = us-east1
project-id = gcp-kms-testing
key-ring-id = canton-test-keys-2023
}
Setup with Pre-Generated Keys¶
In the previous example, Canton creates its own keys on startup and initializes the identity of the nodes automatically. To use pre-generated keys, you need to manually initialize the identity of the nodes by adding the following to each node’s configuration:
<node>.init.auto-init = false
This is only applicable for participant
and domain/domain-manager
nodes.
Afterwards, we need to register the keys in Canton by running the key registration command on each node.
For example for a participant
you would run:
val identityKey = participant.keys.secret
.register_kms_signing_key(namespaceKmsKeyId, name = participant.name + "-namespace")
val signingKey = participant.keys.secret
.register_kms_signing_key(signingKmsKeyId, name = participant.name + "-signing")
val encryptionKey = participant.keys.secret
.register_kms_encryption_key(encryptionKmsKeyId, name = participant.name + "-encryption")
where xyzKmsKeyId is the GCP KMS identifier for a specific key (e.g. KMS Key ARN).
Here is a reminder of the initial keys that each node owns:
Keys | Domain | Domain-Manager | Sequencer | Mediator | Participant |
---|---|---|---|---|---|
(Signing) Namespace Key | x | x | x | ||
Signing Key | x | x | x | x | x |
(Asymmetric) Encryption Key | x |
Depending on the key purpose and the default signing and encryption schemes defined in Canton, you need to pre-generate the corresponding GCP KMS keys with the correct settings:
Provider | SIGNING | ENCRYPTION |
---|---|---|
GCP |
|
|
Below are links to guides on how to manually initialize participant and domain nodes. In those guides, keys are generated using console commands such as:
val identityKey = participant.keys.secret.generate_signing_key(name = participant.name + "-namespace")
Make sure to replace those commands with the ones shown above with which you registered your existing keys instead of generating new ones.