Key Management Service (KMS)
How to enable KMS-backed key management for Canton Validator Participant nodes using IRSA (IAM Roles for Service Accounts).
CatalyX Blockchain Manager supports External Key Management Services (KMS) for storing Canton Validator Participant cryptographic keys. When KMS is enabled, participant keys are stored and managed in an external KMS rather than locally on the node, improving key security and enabling compliance with enterprise key management policies.
For background on why KMS matters, the two Canton key storage modes (encrypted vs. external), and the broader key management and wallet strategy for CAT-BM, see the Security & Privacy Implementation page:
Security & Privacy ImplementationKMS integration was introduced in v1.11.8 as a Phase 1, environment-level toggle. As of v1.11.11, KMS is configured per validator — each validator can be created with its own KMS provider configuration and ServiceAccount, independently of other validators in the same environment.
KMS is now selected at validator creation time in the console (or via the API). It cannot be toggled on or off for an existing validator through the edit wizard. The environment-level Operator settings still exist, but they are no longer a master switch — they now only support migration of pre-v1.11.11 validators. See Operator Settings (Legacy Migration Only) below.
What Changed in v1.11.11
Scope
Environment-wide — applied to all newly created validators
Per validator — chosen individually at creation time
How it is enabled
CANTON_TOPOLOGY_KMS_ENABLED=true on the Operator
enableKms flag in the validator create request / console create flow
KMS provider config
Single global CANTON_TOPOLOGY_KMS_VALUE for everyone
Per-validator kmsValue (falls back to the Operator default if omitted)
ServiceAccount
Single global CANTON_TOPOLOGY_KMS_SERVICE_ACCOUNT
Per-validator kmsServiceAccount (falls back to the Operator default if omitted)
Changing the toggle
Required redeploying the Operator
No redeploy — set per validator at create time
Existing validators
Retained their original config
Legacy KMS validators are auto-migrated on first reconcile (see Backward Compatibility)
The Phase 1 global auto-enable flag (CANTON_TOPOLOGY_KMS_ENABLED) has been retired. KMS is no longer turned on by an environment variable; it is driven entirely by the per-validator request.
How It Works
When a validator is created with KMS enabled, the CAT-BM Operator injects additional Canton crypto configuration into that validator's Participant pod at provisioning time. The Participant authenticates with the external KMS using IRSA — an IAM Role is associated with a Kubernetes ServiceAccount, and that ServiceAccount is assigned to the Participant pod.
The ServiceAccount is externally managed. It must be created and maintained outside of CAT-BM, and its name is provided per validator (or via the Operator default).
Each validator carries its own KMS settings on its spec:
enableKms— whether this validator uses KMSkmsValue— the Canton KMS provider configuration fragment for this validatorkmsServiceAccount— the externally managed ServiceAccount this validator's Participant pod runs under
Validators created without KMS are unaffected and continue to run under the default ServiceAccount with no KMS crypto config injected.
Prerequisites
Before enabling KMS for a validator, ensure the following are in place:
An external KMS key created in the appropriate region/project (e.g. AWS KMS, GCP KMS)
An IAM Role configured with permissions to use the KMS key
A Kubernetes ServiceAccount created in the validator namespace with the IAM Role ARN annotated via IRSA:
The ServiceAccount name and the KMS provider configuration available to supply in the create request
Enabling KMS for a Validator
KMS is enabled per validator at creation time. In the Create Validator flow, the participant configuration accepts three fields:
enableKms
Set to true to store this validator's participant keys in an external KMS. Default: false.
kmsValue
The KMS provider configuration in Canton config format (see below). Required when enableKms is true.
kmsServiceAccount
The externally managed Kubernetes ServiceAccount used for IRSA authentication. Required when enableKms is true.
Request body (API)
These fields live under clusterParticipantConfig in the create-validator request. There are two modes, distinguished by which field you supply:
AWS / GCP — use
kmsServiceAccountAzure — use
kmsAzureVaultSecretName(plusoverrideImage)
clusterParticipantConfig KMS fields:
enableKms
boolean
Master flag — turns KMS on for this validator
kmsValue
string
HOCON provider config (see Provider Examples below)
kmsServiceAccount
string
K8s ServiceAccount for AWS/GCP (IRSA / workload identity)
kmsAzureVaultSecretName
string
K8s Secret holding Azure credentials (Azure only)
overrideImage
string
Participant image override (required for Azure driver image)
Azure also needs a pull secret for overrideImage, set elsewhere in the request body:
participant.resources.imagePullSecret
Pull secret for the override image (Azure only)
AWS example:
kmsValue format
kmsValue formatkmsValue takes a Canton configuration fragment. Because it is passed through verbatim, any Canton-supported KMS provider can be used.
AWS KMS:
GCP KMS:
Azure KMS (driver-based):
Azure additionally requires:
kmsAzureVaultSecretName: a K8s Secret containing fieldstenant-id,client-id,client-secretoverrideImage: an Azure-KMS-enabled participant image that matches the splice image used by the validator's other appsA pull secret for that image, set under
participant.resources.imagePullSecret
Azure example request:
Adjust the provider settings to match your KMS key. For AWS, set audit-logging = true to enable KMS API audit logs (recommended for production).
Validation
When enableKms is true, kmsValue must be non-blank, and at least one of kmsServiceAccount (AWS/GCP) or kmsAzureVaultSecretName (Azure) must be non-blank. If a required field is missing, empty, or whitespace-only, the API rejects the request with HTTP 400 and a fieldErrors map identifying the offending field(s):
When enableKms is false, these fields are ignored and no validation is applied.
Operator Settings (Legacy Migration Only)
The Operator still reads two environment-level KMS settings, but in v1.11.11 they are not a general-purpose configuration knob. Because the API requires both kmsValue and kmsServiceAccount whenever enableKms=true (see Validation), every validator created through the CAT-BM API or console already carries explicit values — so the Operator defaults are never consulted for new validators.
If enableKms=true but a per-validator KMS field is left blank, the Operator falls back to its configured defaults. This happens both as a one-time backfill onto pre-v1.11.11 validators on first reconcile, and at render time for any validator.
CANTON_TOPOLOGY_KMS_ENABLED
Retired — no longer used to auto-enable KMS. KMS is enabled per validator via enableKms.
CANTON_TOPOLOGY_KMS_VALUE
Default fallback for kmsValue when blank.
CANTON_TOPOLOGY_KMS_SERVICE_ACCOUNT
Default fallback for kmsServiceAccount when blank.
CANTON_TOPOLOGY_KMS_AZURE_IMAGE
Default fallback for overrideImage (Azure) when blank.
CANTON_TOPOLOGY_KMS_AZURE_IMAGE_PULL_SECRET
Default fallback for participant.resources.imagePullSecret (Azure) when blank.
CANTON_TOPOLOGY_KMS_AZURE_VAULT_SECRET
Default fallback for kmsAzureVaultSecretName (Azure) when blank.
To prevent a validator with blank KMS fields from silently inheriting these defaults, set the relevant variables to "" on the Operator.
If your environment has no legacy (pre-v1.11.11) KMS validators, these Operator settings have no effect and can be ignored. They only matter while un-migrated Phase 1 validators still exist — see Backward Compatibility.
What the Operator Configures
When a validator is provisioned with KMS enabled, the Operator makes the following changes to that validator's Participant pod:
ServiceAccount reference — the resolved ServiceAccount (per-validator value, or the Operator default) is set on the Participant/Canton spec:
KMS crypto config injection — the following environment variable is injected into the Participant pod, built from the resolved kmsValue:
Backward Compatibility with Legacy Validators
Validators that were created under the Phase 1 environment-level model (with enableKms=true but no per-validator kmsValue / kmsServiceAccount on their spec) are automatically migrated. On the next reconcile, the Operator backfills the global topology values (CANTON_TOPOLOGY_KMS_VALUE / CANTON_TOPOLOGY_KMS_SERVICE_ACCOUNT) onto the validator CR.
This makes the validator's KMS configuration fully explicit on its own spec, so that API reads (GET) and Operator writes (reconcile) share a single source of truth. The backfill:
Runs only for validators that already have
enableKms=true.Only fills fields that are currently blank — it never overwrites an explicit per-validator value.
Runs regardless of the
disableUserEditflag, because it is a system migration rather than a user edit (it executes before the user-edit guard in the reconcile loop).Is idempotent and self-terminating — once both
kmsValueandkmsServiceAccountare populated, it short-circuits and patches nothing on subsequent reconciles. After this one-time migration the validator no longer depends on the global Operator defaults.
For the legacy backfill to work, the Operator's CANTON_TOPOLOGY_KMS_VALUE and CANTON_TOPOLOGY_KMS_SERVICE_ACCOUNT defaults must still match what those validators were originally provisioned with, until every legacy validator has reconciled at least once. Removing them before legacy validators have been migrated would leave those validators without a resolvable KMS configuration.
Verifying KMS Is Active
After provisioning a validator with KMS enabled, verify that:
The API echoes the KMS fields back on the participant — a GET on the participant returns
enableKms=trueand thekmsValue/kmsServiceAccountyou submitted.The Participant pod references the correct ServiceAccount — check with
kubectl get pod <participant-pod> -o yaml | grep serviceAccountNameThe
ADDITIONAL_CONFIG_SPLICE_PARTICIPANT_CRYPTO_KMSenvironment variable is present on the Participant podThe Participant starts successfully and reaches a Ready state — check the Status page in the console
KMS key usage will appear in your provider's audit log (e.g. AWS CloudTrail) if audit logging is enabled on your KMS key. This can be used to confirm the Participant is actively using KMS for cryptographic operations.
Scope and Limitations
Per-validator KMS toggle (at create time)
✅ Supported
Per-validator KMS provider config & ServiceAccount
✅ Supported
Multiple KMS providers (AWS, GCP, …)
✅ Supported via the kmsValue Canton config fragment
Legacy validator migration
✅ Supported — Operator KMS settings backfilled onto the CR on reconcile
Environment-level KMS defaults for new validators
❌ Not applicable — validation requires explicit values, so Operator defaults are never used for new validators
Toggling KMS on an existing validator (edit)
❌ Not supported — KMS is fixed at creation time; the edit wizard guards these fields. All KMS fields are immutable after creation except overrideImage, which remains editable.
Retroactive KMS enablement for non-KMS validators
❌ Not supported — only validators created with enableKms=true use KMS
Operator-managed ServiceAccount lifecycle
❌ Not yet supported — SA must be externally managed
KMS key rotation
❌ Not yet supported
Last updated
Was this helpful?