- Overview
- Tutorials
- How Tos
- Download
- Install
- Configure
- Secure
- TLS API Configuration
- Configure API Authentication and Authorization with JWT
- Configure API Limits
- Set Resource Limits
- Crypto key management
- Restrict key usage
- Namespace Key Management
- Key management service (KMS) configuration
- Optimize
- Observe
- Operate
- Initializing node identity manually
- Canton Console
- Synchronizer connections
- High Availability Usage
- Manage Daml packages and archives
- Participant Node pruning
- Party Management
- Party replication
- Decentralized party overview
- Setup an External Party
- Ledger API User Management
- Node Traffic Management
- Identity Management
- Upgrade
- Decommission
- Recover
- Troubleshoot
- Explanations
- Reference
Enable encrypted private key storage with a KMS¶
Canton can use a KMS to encrypt private keys at rest (envelope encryption):
Private keys are stored encrypted in the node’s database.
On startup, the KMS decrypts them for in-memory use.
This improves security with no runtime performance impact. See Protect private keys with envelope encryption and a Key Management Service for details.
Note
This assumes the KMS provider has already been configured. See Configure a KMS.
Enable envelope encryption¶
Envelope encryption is a common approach chosen by KMS vendors that uses a symmetric encryption key, called the wrapper key, to encrypt and decrypt the stored, private keys.
To enable encrypted private key storage with a KMS using envelope encryption, we must add the following configuration and restart the node.
canton.participants.participant1.crypto.private-key-store.encryption.type = kms
Both new and existing nodes (including Participants) can be configured to use this feature.
In both cases, keys are stored encrypted in the Canton node’s database.
Important
Restoring from a database backup requires access to the wrapper keys used during the encryption of the data in the backup. Deleting the wrapper keys renders the backup unusable.
Manually generate a wrapper key¶
By default, a new symmetric wrapper key is automatically generated by Canton after the node restarts. If you want to use a pre-generated wrapper key, you must first create a new wrapper key in the KMS and record its identifier, taking into account the following requirements.
AWS KMS wrapper key requirements¶
Supported values for identifying the wrapper key:
Key ID:
1234abcd-12ab-34cd-56ef-1234567890abKey ARN (Amazon Resource Name):
arn:aws:kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890abKey alias:
alias/test-key
Note that if you are using an existing key, it must be a symmetric key using the correct scheme. In AWS KMS, this means:
Key specification: SYMMETRIC_DEFAULT
Key usage: ENCRYPT_DECRYPT
GCP KMS wrapper key requirements¶
Supported values for identifying the wrapper key:
Key name:
test-keyKey Resource Name (RN):
projects/gcp-kms-testing/locations/us-east1/keyRings/canton-test-keys/cryptoKeys/test-key/cryptoKeyVersions/1
Note that if you are using an existing key, it must be created with the following attributes:
Key algorithm:
GOOGLE_SYMMETRIC_ENCRYPTIONKey purpose:
ENCRYPT_DECRYPT
KMS Driver key requirements¶
The way keys are uniquely identified is left to the driver implementation. However, the following constraints must be observed:
Keys must be 128-bit in length and usable with the AES-GCM crypto scheme.
Add new wrapper key to configuration¶
With the key created and its ID in hand, you must explicitly add the ID to the configuration using:
canton.participants.participant1.crypto.private-key-store.encryption.wrapper-key-id = alias/canton-kms-test-key
An example configuration that puts together both AWS KMS and envelope encryption with a manually generated wrapper key is shown below:
_shared_aws {
# Configure an AWS KMS
crypto {
kms {
type = aws
region = us-east-1
multi-region-key = false
audit-logging = false
}
# Configure an encrypted store with KMS
private-key-store {
encryption.type = kms
# In this example we are using the same wrapper key for all nodes. This is not recommended and you should
# either let Canton generate those keys or choose a different one for each node.
encryption.wrapper-key-id = alias/canton-kms-test-key
}
}
}
After subsequent restarts the operator does not need to specify the identifier for the wrapper key; Canton stores the wrapper key ID in the database.