From 13aed95f5caf9ab08f292a0c82d3c62656dc84c8 Mon Sep 17 00:00:00 2001 From: timonwong Date: Mon, 11 May 2026 13:16:49 +0000 Subject: [PATCH 1/2] docs(etcd-encryption): document global cluster deterministic installation The etcd Encryption Manager now supports global clusters via deterministic key derivation. Restructure the page to introduce a "Key Strategies" section and split installation into the existing workload/DCS path and a new global cluster path that documents the three UI-exposed plugin parameters (key_strategy, replication_group_id, master_secret_name), master Secret preparation, and chart-only advanced fields. Highlight DR-pair requirements (matching parameters across Active/Standby, etcd Synchronizer v4.3.7+ baseline, same master key material on every cluster in the replication group, sufficient entropy when generating the master key) as warning callouts so misconfiguration that would silently break failover is hard to miss. --- .../en/configure/clusters/etcd-encryption.mdx | 159 ++++++++++++++++-- 1 file changed, 149 insertions(+), 10 deletions(-) diff --git a/docs/en/configure/clusters/etcd-encryption.mdx b/docs/en/configure/clusters/etcd-encryption.mdx index c4a60c10c..b1e1d57b3 100644 --- a/docs/en/configure/clusters/etcd-encryption.mdx +++ b/docs/en/configure/clusters/etcd-encryption.mdx @@ -3,25 +3,158 @@ weight: 91 title: etcd Encryption --- +{/* cspell:ignore master Master urandom */} +{/* "master" here refers to the upstream chart parameter `master_secret_name`/`masterSecretRef` and the cryptography term "master key", not control-plane semantics. */} + # etcd Encryption This guide helps you install, understand, and operate the etcd Encryption Manager in to automate etcd data encryption key rotation within your clusters. It ensures that sensitive data stored in etcd, such as secrets and configmaps, is encrypted using a secure algorithm, enhancing your cluster's security. +## Key Strategies + +The plugin supports two key strategies. Pick the one that matches your cluster role. + +| Strategy | When to use | How keys are produced | +| --- | --- | --- | +| `random` | Default for workload and DCS clusters running standalone (no etcd synchronization). | Each rotation generates a fresh random key locally. | +| `deterministic` | **Required** for `global` clusters, especially when paired in a DR setup via the etcd Synchronizer. | Each key is derived deterministically from a shared master Secret and a shared SeedBundle, so the Active and Standby clusters always reach the same key for the same revision. | + +In `deterministic` mode, the runtime Active / Standby role is detected automatically; it is not a manual install parameter. + ## Installation -See [Cluster Plugin](/extend/cluster_plugin.mdx) for installation instructions. +The plugin supports two installation paths depending on the target cluster: + +* **Workload / DCS clusters** — use the default `random` key strategy. +* **Global clusters** — must use the `deterministic` key strategy (see [Global Clusters (Deterministic Mode)](#global-deterministic) below). + +See [Cluster Plugin](/extend/cluster_plugin.mdx) for the general plugin installation workflow. + +### Workload / DCS Clusters (random strategy) + +* Supported cluster types: On-Premises, DCS. +* No additional installation parameters are required — install via the standard Cluster Plugin workflow. + +### Global Clusters (Deterministic Mode) \{#global-deterministic} + + + +For a Global DR pair, install the plugin **on both the Active and Standby clusters** in `deterministic` mode, and configure **identical** `replication_group_id` and `master_secret_name` (with matching master key material) on both sides. Asymmetric or mismatched configuration causes the Standby to derive different per-revision keys than the Active and breaks failover. + + + +#### Prerequisites + +* The cluster must be a `global` cluster. When `global.cluster.name` is `global`, the chart enforces `etcdEncryption.keyStrategy=deterministic`; the plugin UI also defaults the field to `deterministic` for clusters labeled `is-global=true`. + + + +The **etcd Synchronizer** plugin must be installed at version **v4.3.7 or later** before installing the etcd Encryption Manager in `deterministic` mode. Earlier versions do not replicate the shared SeedBundle, so the Standby cluster cannot derive matching keys. + + + +#### Plugin Parameters + +The plugin form exposes the following parameters for deterministic installation. Defaults reflect the current `plugin-config.yaml` shipped with the chart. + +| Plugin parameter | Required | Default | Purpose | +| --- | --- | --- | --- | +| `key_strategy` | Yes | `random`; dynamically defaults to `deterministic` for `global` clusters. | Selects between random per-rotation key generation and deterministic derivation. | +| `replication_group_id` | Yes | The plugin UI prefills the current cluster name (not recommended — see below). | Identifies the Active / Standby DR group and participates in HKDF domain separation. | +| `master_secret_name` | Yes | `etcd-derivation-master` | Name of the Secret in `kube-system` that holds the deterministic master key material. | + +The `masterSecretRef.namespace` is fixed to `kube-system` and is not exposed in the form. + +##### `key_strategy` + +| Value | Meaning | +| --- | --- | +| `random` | Single-cluster random rotation. | +| `deterministic` | Derived keys based on a shared master Secret and SeedBundle. | + +For `global` clusters this must be `deterministic`. + +##### `replication_group_id` + +| Property | Value | +| --- | --- | +| Purpose | Identifies one Active / Standby DR replication group and participates in HKDF domain separation. | +| Consistency requirement | The Active and Standby clusters in the same DR group **must** use exactly the same value. | +| Default in UI | Current cluster name. | +| Recommended to keep the default | **No.** | + +Recommendations: -> **Note:** -> -> * Currently supported: -> -> * On-Premises clusters -> * DCS clusters -> * Not supported: -> -> * `global cluster` +* For DR clusters built with the etcd Synchronizer, both sides of the same DR group must share the same `replication_group_id`. +* To avoid leaking real business, environment, or cluster identity, do **not** reuse the cluster name even when the UI prefills it. Plan a separate opaque identifier ahead of installation. +* A UUID-style identifier may be a good fit, for example `6f1b9e2c-7c3a-4a9c-8b72-2fd0f8f3c1ab`. + +To generate a UUID-style value from the command line: + +```bash +openssl rand -hex 16 | sed -E 's/^(.{8})(.{4})(.{4})(.{4})(.{12})$/\1-\2-\3-\4-\5/' +``` + + + +Generate the value **once**, then configure the same `replication_group_id` on the Active and Standby clusters of the DR group. Generating different values on each side will produce divergent encryption keys. + + + +##### `master_secret_name` + +| Property | Value | +| --- | --- | +| Purpose | Refers to the deterministic master key Secret. | +| Default | `etcd-derivation-master` | +| Fixed namespace | `kube-system` | +| Cross-cluster requirement | All clusters in the same replication group must use the same master key material. | + +The plugin form exposes only the Secret name; the namespace is always `kube-system` at render time. + +#### Preparing the Master Secret + +The deterministic master Secret must exist in `kube-system` before installing the plugin. Prepare it in two steps: + +1. Generate 32 bytes of cryptographically strong random material into `./master-key.bin`. The bytes must come from a high-entropy source — typically the operating system CSPRNG. `openssl rand` is a safe default; equivalent OS-CSPRNG-backed commands such as `head -c 32 /dev/urandom > ./master-key.bin` also work. Do **not** use shell `$RANDOM`, language-level `rand()`, or any time-seeded generator. + + ```bash + openssl rand -out ./master-key.bin 32 + ``` + +2. Create the Secret in `kube-system` from that file: + + ```bash + kubectl -n kube-system create secret generic etcd-derivation-master \ + --from-file=master-key=./master-key.bin + ``` + +If you use a different Secret name, replace `etcd-derivation-master` above with the value you will enter as `master_secret_name`. + + + +Generate `./master-key.bin` **once**, then transport the **same file** to every cluster in the replication group and run the `kubectl create secret` step on each. Do **not** regenerate the key material per cluster — different master key bytes will produce divergent encryption keys. + + + +#### Advanced (chart values, not exposed in the plugin form) + +
+Show advanced chart values + +The following fields exist in the chart but are not surfaced as plugin install parameters. They retain their chart defaults unless you install via YAML / Helm overrides. + +| Chart field | Default | Purpose | +| --- | --- | --- | +| `etcdEncryption.deterministic.activationPolicy` | `timed-approval` | Controls how a new derived key becomes active. `timed-approval` waits for a delay before activation. | +| `etcdEncryption.deterministic.approvalDelay` | `30m` | Delay applied under `timed-approval`. The plugin form maps this as `approval_delay_minutes` (integer minutes) internally. | +| `etcdEncryption.deterministic.derivationAlgorithm` | `hkdf-sha512-v1` | Algorithm used to derive per-revision keys from the master Secret. | +| `etcdEncryption.deterministic.dimension` | `default` | Additional HKDF domain separator. Leave at the default unless you need to fork a key lineage on purpose. | +| `etcdEncryption.deterministic.masterSecretRef.namespace` | `kube-system` | Fixed; not exposed by the form. | + +
--- @@ -37,6 +170,12 @@ Upon installation, an `etcd-encryption-manager` controller is deployed in the `k Cluster stability is maintained throughout these operations. +When the plugin is installed in `deterministic` mode on a `global` DR pair, the controller additionally: + +* Detects whether it is acting as **Active** or **Standby** at runtime — this is not a manual configuration. +* On the Active side, generates the SeedBundle and lets the etcd Synchronizer replicate it to the Standby. +* On the Standby side, derives the same per-revision keys from the shared SeedBundle and the master Secret, so a failover produces identical encryption keys without manual key copy. + ### Default Configuration | Parameter | Value | From adee078af6602cfbd7b13757f25404eeb4cba929 Mon Sep 17 00:00:00 2001 From: timonwong Date: Mon, 11 May 2026 13:33:13 +0000 Subject: [PATCH 2/2] =?UTF-8?q?docs(etcd-encryption):=20rename=20master?= =?UTF-8?q?=E2=86=92root=20for=20derivation=20key=20terminology?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Align with the upstream etcd-encryption-manager API rename: masterSecretRef → rootSecretRef, master_secret_name → root_secret_name, default Secret etcd-derivation-master → etcd-derivation-root, Secret data key master-key → root-key, and the example file master-key.bin → root-key.bin. Drop the cspell ignore for "master" — it is no longer used in this file and the project's inclusive-language rule (master → control plane) now applies cleanly. Keep the cspell ignore for `urandom`, which is still referenced via `/dev/urandom`. --- .../en/configure/clusters/etcd-encryption.mdx | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/docs/en/configure/clusters/etcd-encryption.mdx b/docs/en/configure/clusters/etcd-encryption.mdx index b1e1d57b3..07cabf14c 100644 --- a/docs/en/configure/clusters/etcd-encryption.mdx +++ b/docs/en/configure/clusters/etcd-encryption.mdx @@ -3,8 +3,7 @@ weight: 91 title: etcd Encryption --- -{/* cspell:ignore master Master urandom */} -{/* "master" here refers to the upstream chart parameter `master_secret_name`/`masterSecretRef` and the cryptography term "master key", not control-plane semantics. */} +{/* cspell:ignore urandom */} # etcd Encryption @@ -19,7 +18,7 @@ The plugin supports two key strategies. Pick the one that matches your cluster r | Strategy | When to use | How keys are produced | | --- | --- | --- | | `random` | Default for workload and DCS clusters running standalone (no etcd synchronization). | Each rotation generates a fresh random key locally. | -| `deterministic` | **Required** for `global` clusters, especially when paired in a DR setup via the etcd Synchronizer. | Each key is derived deterministically from a shared master Secret and a shared SeedBundle, so the Active and Standby clusters always reach the same key for the same revision. | +| `deterministic` | **Required** for `global` clusters, especially when paired in a DR setup via the etcd Synchronizer. | Each key is derived deterministically from a shared root Secret and a shared SeedBundle, so the Active and Standby clusters always reach the same key for the same revision. | In `deterministic` mode, the runtime Active / Standby role is detected automatically; it is not a manual install parameter. @@ -41,7 +40,7 @@ See [Cluster Plugin](/extend/cluster_plugin.mdx) for the general plugin installa -For a Global DR pair, install the plugin **on both the Active and Standby clusters** in `deterministic` mode, and configure **identical** `replication_group_id` and `master_secret_name` (with matching master key material) on both sides. Asymmetric or mismatched configuration causes the Standby to derive different per-revision keys than the Active and breaks failover. +For a Global DR pair, install the plugin **on both the Active and Standby clusters** in `deterministic` mode, and configure **identical** `replication_group_id` and `root_secret_name` (with matching root key material) on both sides. Asymmetric or mismatched configuration causes the Standby to derive different per-revision keys than the Active and breaks failover. @@ -63,16 +62,16 @@ The plugin form exposes the following parameters for deterministic installation. | --- | --- | --- | --- | | `key_strategy` | Yes | `random`; dynamically defaults to `deterministic` for `global` clusters. | Selects between random per-rotation key generation and deterministic derivation. | | `replication_group_id` | Yes | The plugin UI prefills the current cluster name (not recommended — see below). | Identifies the Active / Standby DR group and participates in HKDF domain separation. | -| `master_secret_name` | Yes | `etcd-derivation-master` | Name of the Secret in `kube-system` that holds the deterministic master key material. | +| `root_secret_name` | Yes | `etcd-derivation-root` | Name of the Secret in `kube-system` that holds the deterministic root key material. | -The `masterSecretRef.namespace` is fixed to `kube-system` and is not exposed in the form. +The `rootSecretRef.namespace` is fixed to `kube-system` and is not exposed in the form. ##### `key_strategy` | Value | Meaning | | --- | --- | | `random` | Single-cluster random rotation. | -| `deterministic` | Derived keys based on a shared master Secret and SeedBundle. | +| `deterministic` | Derived keys based on a shared root Secret and SeedBundle. | For `global` clusters this must be `deterministic`. @@ -103,39 +102,39 @@ Generate the value **once**, then configure the same `replication_group_id` on t -##### `master_secret_name` +##### `root_secret_name` | Property | Value | | --- | --- | -| Purpose | Refers to the deterministic master key Secret. | -| Default | `etcd-derivation-master` | +| Purpose | Refers to the deterministic root key Secret. | +| Default | `etcd-derivation-root` | | Fixed namespace | `kube-system` | -| Cross-cluster requirement | All clusters in the same replication group must use the same master key material. | +| Cross-cluster requirement | All clusters in the same replication group must use the same root key material. | The plugin form exposes only the Secret name; the namespace is always `kube-system` at render time. -#### Preparing the Master Secret +#### Preparing the Root Secret -The deterministic master Secret must exist in `kube-system` before installing the plugin. Prepare it in two steps: +The deterministic root Secret must exist in `kube-system` before installing the plugin. Prepare it in two steps: -1. Generate 32 bytes of cryptographically strong random material into `./master-key.bin`. The bytes must come from a high-entropy source — typically the operating system CSPRNG. `openssl rand` is a safe default; equivalent OS-CSPRNG-backed commands such as `head -c 32 /dev/urandom > ./master-key.bin` also work. Do **not** use shell `$RANDOM`, language-level `rand()`, or any time-seeded generator. +1. Generate 32 bytes of cryptographically strong random material into `./root-key.bin`. The bytes must come from a high-entropy source — typically the operating system CSPRNG. `openssl rand` is a safe default; equivalent OS-CSPRNG-backed commands such as `head -c 32 /dev/urandom > ./root-key.bin` also work. Do **not** use shell `$RANDOM`, language-level `rand()`, or any time-seeded generator. ```bash - openssl rand -out ./master-key.bin 32 + openssl rand -out ./root-key.bin 32 ``` 2. Create the Secret in `kube-system` from that file: ```bash - kubectl -n kube-system create secret generic etcd-derivation-master \ - --from-file=master-key=./master-key.bin + kubectl -n kube-system create secret generic etcd-derivation-root \ + --from-file=root-key=./root-key.bin ``` -If you use a different Secret name, replace `etcd-derivation-master` above with the value you will enter as `master_secret_name`. +If you use a different Secret name, replace `etcd-derivation-root` above with the value you will enter as `root_secret_name`. -Generate `./master-key.bin` **once**, then transport the **same file** to every cluster in the replication group and run the `kubectl create secret` step on each. Do **not** regenerate the key material per cluster — different master key bytes will produce divergent encryption keys. +Generate `./root-key.bin` **once**, then transport the **same file** to every cluster in the replication group and run the `kubectl create secret` step on each. Do **not** regenerate the key material per cluster — different root key bytes will produce divergent encryption keys. @@ -150,9 +149,9 @@ The following fields exist in the chart but are not surfaced as plugin install p | --- | --- | --- | | `etcdEncryption.deterministic.activationPolicy` | `timed-approval` | Controls how a new derived key becomes active. `timed-approval` waits for a delay before activation. | | `etcdEncryption.deterministic.approvalDelay` | `30m` | Delay applied under `timed-approval`. The plugin form maps this as `approval_delay_minutes` (integer minutes) internally. | -| `etcdEncryption.deterministic.derivationAlgorithm` | `hkdf-sha512-v1` | Algorithm used to derive per-revision keys from the master Secret. | +| `etcdEncryption.deterministic.derivationAlgorithm` | `hkdf-sha512-v1` | Algorithm used to derive per-revision keys from the root Secret. | | `etcdEncryption.deterministic.dimension` | `default` | Additional HKDF domain separator. Leave at the default unless you need to fork a key lineage on purpose. | -| `etcdEncryption.deterministic.masterSecretRef.namespace` | `kube-system` | Fixed; not exposed by the form. | +| `etcdEncryption.deterministic.rootSecretRef.namespace` | `kube-system` | Fixed; not exposed by the form. | @@ -174,7 +173,7 @@ When the plugin is installed in `deterministic` mode on a `global` DR pair, the * Detects whether it is acting as **Active** or **Standby** at runtime — this is not a manual configuration. * On the Active side, generates the SeedBundle and lets the etcd Synchronizer replicate it to the Standby. -* On the Standby side, derives the same per-revision keys from the shared SeedBundle and the master Secret, so a failover produces identical encryption keys without manual key copy. +* On the Standby side, derives the same per-revision keys from the shared SeedBundle and the root Secret, so a failover produces identical encryption keys without manual key copy. ### Default Configuration