Configure External Key Storage with AWS KMS

Important

Daml Enterprise license required

The following section describes the steps needed to enable External Key Storage in Canton using AWS KMS. These steps include configuring AWS KMS, as well as configuring this particular mode of operation.

AWS KMS Configuration

To start using this feature you must first enable a KMS for Canton.

–Configure AWS KMS for Canton–

The following IAM permissions are required:

  • kms:CreateKey
  • kms:TagResource
  • kms:Decrypt
  • kms:Sign
  • kms:DescribeKey
  • kms:GetPublicKey

When you are using cross-account keys, you do not need the kms:CreateKey and kms:TagResource permissions.

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, we configure a new Canton participant node (called participant1) to generate and store private keys in an external AWS 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 AWS KMS and external storage configuration is shown below:

canton.participants.participant1.crypto.provider = kms
canton.participants.participant1.crypto.kms {
	type = aws
	region = us-east-1
	multi-region-key = false # optional, default is false
    audit-logging = false # optional, default is false
}

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 AWS KMS identifier for a specific key (e.g. KMS Key ARN). When using AWS cross account keys the key ID can’t be used, use the key ARN instead.

Here is a reminder of the initial keys that each node owns:

List of 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 AWS KMS keys with the correct settings:

AWS key configuration
Provider SIGNING ENCRYPTION
AWS
  • Key Purpose: SIGN_VERIFY
  • Key Algorithms: ECC_NIST_P256 or ECC_NIST_P384
  • Key Purpose: ENCRYPT_DECRYPT
  • Key Algorithm: RSA_2048

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.