diff --git a/CHANGELOG.md b/CHANGELOG.md
index 59029f4..39a0b09 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,8 +24,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Tenant name length**: [`validate_dns1035_label`](src/types/v1alpha1/tenant.rs) now caps `metadata.name` at **55** characters so derived names like `{name}-console` remain valid Kubernetes DNS labels (≤ 63).
+- **Encryption validation on reconcile**: [`validate_kms_secret`](src/context.rs) now runs whenever `spec.encryption.enabled` is true (previously skipped when `kmsSecret` was unset).
+
### Changed
+- **Tenant `spec.encryption.vault`**: Removed `tlsSkipVerify` and `customCertificates` (they were never wired to `rustfs-kms`). Vault TLS should rely on system-trusted CAs or TLS upstream. The project is still pre-production; if you have old YAML with these keys, remove them before apply.
+
+- **KMS pod environment** ([`tenant/workloads.rs`](src/types/v1alpha1/tenant/workloads.rs)): Align variable names with the RustFS server and `rustfs-kms` (`RUSTFS_KMS_ENABLE`, `RUSTFS_KMS_VAULT_ADDRESS`, KV mount and key prefix, local `RUSTFS_KMS_KEY_DIR` / `RUSTFS_KMS_DEFAULT_KEY_ID`, etc.); remove Vault TLS certificate volume mounts; `ping_seconds` remains documented as reserved (not injected).
+
+- **Local KMS** ([`context.rs`](src/context.rs)): Validate absolute `keyDirectory` and require a single server replica across pools (multi-replica tenants need Vault or shared storage).
+
- **Deploy scripts** ([`scripts/deploy/deploy-rustfs.sh`](scripts/deploy/deploy-rustfs.sh), [`deploy-rustfs-4node.sh`](scripts/deploy/deploy-rustfs-4node.sh)): Docker builds use **layer cache by default** (`docker_build_cached`); set `RUSTFS_DOCKER_NO_CACHE=true` for a full rebuild. Documented in [`scripts/README.md`](scripts/README.md).
- **4-node deploy**: Help text moved to an early heredoc (avoids trailing `case`/parse issues); see script header.
- **4-node cleanup** ([`cleanup-rustfs-4node.sh`](scripts/cleanup/cleanup-rustfs-4node.sh)): Host storage dirs under `/tmp/rustfs-storage-*` may require `sudo rm -rf` after Kind (root-owned bind mounts).
diff --git a/console-web/app/(dashboard)/tenants/[namespace]/[name]/tenant-detail-client.tsx b/console-web/app/(dashboard)/tenants/[namespace]/[name]/tenant-detail-client.tsx
index 3854471..84947e9 100644
--- a/console-web/app/(dashboard)/tenants/[namespace]/[name]/tenant-detail-client.tsx
+++ b/console-web/app/(dashboard)/tenants/[namespace]/[name]/tenant-detail-client.tsx
@@ -108,8 +108,6 @@ export function TenantDetailClient({ namespace, name, initialTab, initialYamlEdi
namespace: "",
prefix: "",
authType: "token",
- tlsSkipVerify: false,
- customCertificates: false,
})
const [encAppRole, setEncAppRole] = useState({
engine: "",
@@ -380,8 +378,6 @@ export function TenantDetailClient({ namespace, name, initialTab, initialYamlEdi
namespace: data.vault.namespace || "",
prefix: data.vault.prefix || "",
authType: data.vault.authType || "token",
- tlsSkipVerify: data.vault.tlsSkipVerify || false,
- customCertificates: data.vault.customCertificates || false,
})
if (data.vault.appRole) {
setEncAppRole({
@@ -428,8 +424,6 @@ export function TenantDetailClient({ namespace, name, initialTab, initialYamlEdi
namespace: encVault.namespace || undefined,
prefix: encVault.prefix || undefined,
authType: encVault.authType || undefined,
- tlsSkipVerify: encVault.tlsSkipVerify || undefined,
- customCertificates: encVault.customCertificates || undefined,
}
if (encVault.authType === "approle") {
body.vault.appRole = {
@@ -951,32 +945,6 @@ export function TenantDetailClient({ namespace, name, initialTab, initialYamlEdi
/>
-
{/* Auth type selector */}
@@ -1093,21 +1061,15 @@ export function TenantDetailClient({ namespace, name, initialTab, initialYamlEdi
diff --git a/console-web/types/api.ts b/console-web/types/api.ts
index e350a25..008b5f6 100644
--- a/console-web/types/api.ts
+++ b/console-web/types/api.ts
@@ -271,8 +271,6 @@ export interface VaultInfo {
prefix: string | null
authType: string | null
appRole: AppRoleInfo | null
- tlsSkipVerify: boolean | null
- customCertificates: boolean | null
}
export interface LocalKmsInfo {
@@ -310,8 +308,6 @@ export interface UpdateEncryptionRequest {
engine?: string
retrySeconds?: number
}
- tlsSkipVerify?: boolean
- customCertificates?: boolean
}
local?: {
keyDirectory?: string
diff --git a/deploy/rustfs-operator/crds/tenant-crd.yaml b/deploy/rustfs-operator/crds/tenant-crd.yaml
index b6db5da..fcd8740 100644
--- a/deploy/rustfs-operator/crds/tenant-crd.yaml
+++ b/deploy/rustfs-operator/crds/tenant-crd.yaml
@@ -66,7 +66,7 @@ spec:
kmsSecret:
description: |-
Reference to a Secret containing sensitive KMS credentials
- (Vault token or AppRole credentials, TLS certificates).
+ (Vault token or AppRole credentials).
nullable: true
properties:
name:
@@ -80,19 +80,20 @@ spec:
nullable: true
properties:
keyDirectory:
- description: 'Directory for key files inside the container (default: `/data/kms-keys`).'
+ description: |-
+ Absolute directory for KMS key files inside the container (default: `/data/kms-keys`).
+ Must be absolute; RustFS validates this for the local backend.
nullable: true
type: string
masterKeyId:
- description: 'Master key identifier (default: `default-master-key`).'
+ description: Default KMS key id for SSE (maps to `RUSTFS_KMS_DEFAULT_KEY_ID` in the RustFS binary).
nullable: true
type: string
type: object
pingSeconds:
description: |-
- Interval in seconds for KMS health-check pings (default: disabled).
- When set, the operator stores the value; the in-process KMS library
- picks it up from `RUSTFS_KMS_PING_SECONDS`.
+ Reserved for future KMS health-check tuning. Not injected into pods: the current RustFS
+ release does not read `RUSTFS_KMS_PING_SECONDS` in the server startup path.
format: int32
nullable: true
type: integer
@@ -125,19 +126,11 @@ spec:
- null
nullable: true
type: string
- customCertificates:
- description: |-
- Enable custom TLS certificates for the Vault connection.
- When `true`, the operator mounts TLS certificate files from the KMS Secret
- and configures the corresponding environment variables.
- The Secret must contain: `vault-ca-cert`, `vault-client-cert`, `vault-client-key`.
- nullable: true
- type: boolean
endpoint:
description: Vault server endpoint (e.g. `https://vault.example.com:8200`).
type: string
engine:
- description: 'Vault KV2 engine mount path (default: `kv`).'
+ description: KV secrets engine mount path (maps to `RUSTFS_KMS_VAULT_KV_MOUNT` in rustfs-kms; e.g. `secret`, `kv`).
nullable: true
type: string
namespace:
@@ -145,13 +138,9 @@ spec:
nullable: true
type: string
prefix:
- description: Key prefix inside the engine.
+ description: Key prefix inside the KV engine (maps to `RUSTFS_KMS_VAULT_KEY_PREFIX`).
nullable: true
type: string
- tlsSkipVerify:
- description: Skip TLS certificate verification for Vault connection.
- nullable: true
- type: boolean
required:
- endpoint
type: object
diff --git a/deploy/rustfs-operator/crds/tenant.yaml b/deploy/rustfs-operator/crds/tenant.yaml
index b6db5da..fcd8740 100755
--- a/deploy/rustfs-operator/crds/tenant.yaml
+++ b/deploy/rustfs-operator/crds/tenant.yaml
@@ -66,7 +66,7 @@ spec:
kmsSecret:
description: |-
Reference to a Secret containing sensitive KMS credentials
- (Vault token or AppRole credentials, TLS certificates).
+ (Vault token or AppRole credentials).
nullable: true
properties:
name:
@@ -80,19 +80,20 @@ spec:
nullable: true
properties:
keyDirectory:
- description: 'Directory for key files inside the container (default: `/data/kms-keys`).'
+ description: |-
+ Absolute directory for KMS key files inside the container (default: `/data/kms-keys`).
+ Must be absolute; RustFS validates this for the local backend.
nullable: true
type: string
masterKeyId:
- description: 'Master key identifier (default: `default-master-key`).'
+ description: Default KMS key id for SSE (maps to `RUSTFS_KMS_DEFAULT_KEY_ID` in the RustFS binary).
nullable: true
type: string
type: object
pingSeconds:
description: |-
- Interval in seconds for KMS health-check pings (default: disabled).
- When set, the operator stores the value; the in-process KMS library
- picks it up from `RUSTFS_KMS_PING_SECONDS`.
+ Reserved for future KMS health-check tuning. Not injected into pods: the current RustFS
+ release does not read `RUSTFS_KMS_PING_SECONDS` in the server startup path.
format: int32
nullable: true
type: integer
@@ -125,19 +126,11 @@ spec:
- null
nullable: true
type: string
- customCertificates:
- description: |-
- Enable custom TLS certificates for the Vault connection.
- When `true`, the operator mounts TLS certificate files from the KMS Secret
- and configures the corresponding environment variables.
- The Secret must contain: `vault-ca-cert`, `vault-client-cert`, `vault-client-key`.
- nullable: true
- type: boolean
endpoint:
description: Vault server endpoint (e.g. `https://vault.example.com:8200`).
type: string
engine:
- description: 'Vault KV2 engine mount path (default: `kv`).'
+ description: KV secrets engine mount path (maps to `RUSTFS_KMS_VAULT_KV_MOUNT` in rustfs-kms; e.g. `secret`, `kv`).
nullable: true
type: string
namespace:
@@ -145,13 +138,9 @@ spec:
nullable: true
type: string
prefix:
- description: Key prefix inside the engine.
+ description: Key prefix inside the KV engine (maps to `RUSTFS_KMS_VAULT_KEY_PREFIX`).
nullable: true
type: string
- tlsSkipVerify:
- description: Skip TLS certificate verification for Vault connection.
- nullable: true
- type: boolean
required:
- endpoint
type: object
diff --git a/src/console/handlers/encryption.rs b/src/console/handlers/encryption.rs
index 52d1d0e..98b9b9e 100644
--- a/src/console/handlers/encryption.rs
+++ b/src/console/handlers/encryption.rs
@@ -55,8 +55,6 @@ pub async fn get_encryption(
engine: ar.engine.clone(),
retry_seconds: ar.retry_seconds,
}),
- tls_skip_verify: v.tls_skip_verify,
- custom_certificates: v.custom_certificates,
}),
local: enc.local.as_ref().map(|l| LocalInfo {
key_directory: l.key_directory.clone(),
@@ -152,8 +150,6 @@ pub async fn update_encryption(
engine: ar.engine,
retry_seconds: ar.retry_seconds,
}),
- tls_skip_verify: v.tls_skip_verify,
- custom_certificates: v.custom_certificates,
})
} else {
None
diff --git a/src/console/models/encryption.rs b/src/console/models/encryption.rs
index 6a5c7a2..1717eaa 100644
--- a/src/console/models/encryption.rs
+++ b/src/console/models/encryption.rs
@@ -38,8 +38,6 @@ pub struct VaultInfo {
pub prefix: Option
,
pub auth_type: Option,
pub app_role: Option,
- pub tls_skip_verify: Option,
- pub custom_certificates: Option,
}
/// AppRole non-sensitive fields.
@@ -90,8 +88,6 @@ pub struct UpdateVaultRequest {
pub prefix: Option,
pub auth_type: Option,
pub app_role: Option,
- pub tls_skip_verify: Option,
- pub custom_certificates: Option,
}
#[derive(Debug, Deserialize, ToSchema)]
diff --git a/src/context.rs b/src/context.rs
index 238c39f..69e0606 100755
--- a/src/context.rs
+++ b/src/context.rs
@@ -75,6 +75,31 @@ pub enum Error {
Serde { source: serde_json::Error },
}
+/// Validates Local KMS: absolute `keyDirectory` and at most one server replica across pools.
+fn validate_local_kms_tenant(
+ local: Option<&types::v1alpha1::encryption::LocalKmsConfig>,
+ pools: &[types::v1alpha1::pool::Pool],
+) -> Result<(), Error> {
+ let key_dir = local
+ .and_then(|l| l.key_directory.as_deref())
+ .unwrap_or("/data/kms-keys");
+ if !key_dir.starts_with('/') {
+ return Err(Error::KmsConfigInvalid {
+ message: format!(
+ "Local KMS keyDirectory must be an absolute path (got \"{}\")",
+ key_dir
+ ),
+ });
+ }
+ let total_servers: i32 = pools.iter().map(|p| p.servers).sum();
+ if total_servers > 1 {
+ return Err(Error::KmsConfigInvalid {
+ message: "Local KMS is only supported when the tenant has a single RustFS server replica (sum of pool servers must be 1). For multiple servers use Vault KMS, or use a single-server pool.".to_string(),
+ });
+ }
+ Ok(())
+}
+
pub struct Context {
pub(crate) client: kube::Client,
pub(crate) recorder: Recorder,
@@ -303,8 +328,9 @@ impl Context {
/// Validates encryption configuration and the KMS Secret.
///
/// Checks:
- /// 1. Vault endpoint is non-empty when backend is Vault.
- /// 2. KMS Secret exists and contains the correct keys for the auth type.
+ /// 1. Local KMS: absolute key directory and single replica (sum of pool servers).
+ /// 2. Vault endpoint is non-empty when backend is Vault.
+ /// 3. KMS Secret exists and contains the correct keys for the auth type.
pub async fn validate_kms_secret(&self, tenant: &Tenant) -> Result<(), Error> {
use crate::types::v1alpha1::encryption::{KmsBackendType, VaultAuthType};
@@ -315,6 +341,12 @@ impl Context {
return Ok(());
}
+ // Local KMS: RustFS requires an absolute key directory; multi-replica tenants need Vault
+ // (or a shared filesystem) because each Pod would otherwise have its own key files.
+ if enc.backend == KmsBackendType::Local {
+ validate_local_kms_tenant(enc.local.as_ref(), &tenant.spec.pools)?;
+ }
+
// Validate Vault endpoint is non-empty and kms_secret is required for Vault
if enc.backend == KmsBackendType::Vault {
let endpoint_empty = enc
@@ -468,3 +500,46 @@ impl Context {
Ok((status.current_revision, status.update_revision))
}
}
+
+#[cfg(test)]
+mod validate_local_kms_tests {
+ use super::Error;
+ use super::validate_local_kms_tenant;
+ use crate::types::v1alpha1::encryption::LocalKmsConfig;
+ use crate::types::v1alpha1::persistence::PersistenceConfig;
+ use crate::types::v1alpha1::pool::Pool;
+
+ fn pool(servers: i32) -> Pool {
+ Pool {
+ name: "p".to_string(),
+ servers,
+ persistence: PersistenceConfig {
+ volumes_per_server: 4,
+ ..Default::default()
+ },
+ scheduling: Default::default(),
+ }
+ }
+
+ #[test]
+ fn local_kms_default_key_dir_ok_single_replica() {
+ validate_local_kms_tenant(None, &[pool(1)]).unwrap();
+ }
+
+ #[test]
+ fn local_kms_rejects_relative_key_dir() {
+ let local = LocalKmsConfig {
+ key_directory: Some("data/kms".to_string()),
+ ..Default::default()
+ };
+ let err = validate_local_kms_tenant(Some(&local), &[pool(1)]).unwrap_err();
+ assert!(matches!(err, Error::KmsConfigInvalid { .. }));
+ }
+
+ #[test]
+ fn local_kms_rejects_multi_pool_multi_replica() {
+ let local = LocalKmsConfig::default();
+ let err = validate_local_kms_tenant(Some(&local), &[pool(2), pool(2)]).unwrap_err();
+ assert!(matches!(err, Error::KmsConfigInvalid { .. }));
+ }
+}
diff --git a/src/reconcile.rs b/src/reconcile.rs
index 2627bac..529e524 100755
--- a/src/reconcile.rs
+++ b/src/reconcile.rs
@@ -79,10 +79,11 @@ pub async fn reconcile_rustfs(tenant: Arc, ctx: Arc) -> Result<
return Err(e.into());
}
- // Validate KMS Secret if encryption is configured
+ // Validate encryption / KMS: Vault requires endpoint + kmsSecret (and correct keys);
+ // must run whenever encryption is enabled — not only when kmsSecret is set, or Vault
+ // without a Secret reference would skip validation entirely.
if let Some(ref enc) = latest_tenant.spec.encryption
&& enc.enabled
- && enc.kms_secret.is_some()
&& let Err(e) = ctx.validate_kms_secret(&latest_tenant).await
{
let _ = ctx
diff --git a/src/types/v1alpha1/encryption.rs b/src/types/v1alpha1/encryption.rs
index e5e8ba0..3da37b8 100644
--- a/src/types/v1alpha1/encryption.rs
+++ b/src/types/v1alpha1/encryption.rs
@@ -65,7 +65,7 @@ impl std::fmt::Display for VaultAuthType {
/// Vault-specific KMS configuration.
///
/// Maps to `VaultConfig` in the `rustfs-kms` crate.
-/// Sensitive fields (token, TLS keys) are stored in the Secret referenced
+/// Sensitive fields (Vault token or AppRole credentials) are stored in the Secret referenced
/// by `EncryptionConfig::kms_secret`.
#[derive(Deserialize, Serialize, Clone, Debug, KubeSchema, Default)]
#[serde(rename_all = "camelCase")]
@@ -73,7 +73,7 @@ pub struct VaultKmsConfig {
/// Vault server endpoint (e.g. `https://vault.example.com:8200`).
pub endpoint: String,
- /// Vault KV2 engine mount path (default: `kv`).
+ /// KV secrets engine mount path (maps to `RUSTFS_KMS_VAULT_KV_MOUNT` in rustfs-kms; e.g. `secret`, `kv`).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub engine: Option,
@@ -81,7 +81,7 @@ pub struct VaultKmsConfig {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub namespace: Option,
- /// Key prefix inside the engine.
+ /// Key prefix inside the KV engine (maps to `RUSTFS_KMS_VAULT_KEY_PREFIX`).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub prefix: Option,
@@ -94,17 +94,6 @@ pub struct VaultKmsConfig {
/// under keys `vault-approle-id` and `vault-approle-secret`.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub app_role: Option,
-
- /// Skip TLS certificate verification for Vault connection.
- #[serde(default, skip_serializing_if = "Option::is_none")]
- pub tls_skip_verify: Option,
-
- /// Enable custom TLS certificates for the Vault connection.
- /// When `true`, the operator mounts TLS certificate files from the KMS Secret
- /// and configures the corresponding environment variables.
- /// The Secret must contain: `vault-ca-cert`, `vault-client-cert`, `vault-client-key`.
- #[serde(default, skip_serializing_if = "Option::is_none")]
- pub custom_certificates: Option,
}
/// Vault AppRole authentication settings.
@@ -132,23 +121,28 @@ pub struct VaultAppRoleConfig {
///
/// Maps to `LocalConfig` in the `rustfs-kms` crate.
/// Keys are stored as JSON files in the specified directory.
+///
+/// **RustFS binary alignment**: `key_directory` is injected as `RUSTFS_KMS_KEY_DIR` (required by
+/// `rustfs` server startup). `master_key_id` maps to `RUSTFS_KMS_DEFAULT_KEY_ID` (default SSE key id),
+/// not to a "master encryption passphrase" (`RUSTFS_KMS_LOCAL_MASTER_KEY` is separate in rustfs-kms).
#[derive(Deserialize, Serialize, Clone, Debug, KubeSchema, Default)]
#[serde(rename_all = "camelCase")]
pub struct LocalKmsConfig {
- /// Directory for key files inside the container (default: `/data/kms-keys`).
+ /// Absolute directory for KMS key files inside the container (default: `/data/kms-keys`).
+ /// Must be absolute; RustFS validates this for the local backend.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub key_directory: Option,
- /// Master key identifier (default: `default-master-key`).
+ /// Default KMS key id for SSE (maps to `RUSTFS_KMS_DEFAULT_KEY_ID` in the RustFS binary).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub master_key_id: Option,
}
/// Encryption / KMS configuration for a Tenant.
///
-/// When enabled, the operator injects KMS environment variables and mounts
-/// the referenced Secret into all RustFS pods so that the in-process
-/// `rustfs-kms` library picks them up on startup.
+/// When enabled, the operator injects environment variables matching the **RustFS server**
+/// (`rustfs` CLI / `init_kms_system`) and `rustfs_kms::KmsConfig::from_env()` where applicable.
+/// See `Tenant::configure_kms` in `tenant/workloads.rs` for the exact variable names.
///
/// Example YAML:
/// ```yaml
@@ -161,7 +155,6 @@ pub struct LocalKmsConfig {
/// engine: "kv"
/// namespace: "tenant1"
/// prefix: "rustfs"
-/// customCertificates: true
/// kmsSecret:
/// name: "my-tenant-kms-secret"
/// ```
@@ -175,11 +168,6 @@ pub struct LocalKmsConfig {
/// - `vault-approle-id` (required): AppRole role ID
/// - `vault-approle-secret` (required): AppRole secret ID
///
-/// **Vault TLS (when `customCertificates: true`):**
-/// - `vault-ca-cert`: PEM-encoded CA certificate
-/// - `vault-client-cert`: PEM-encoded client certificate for mTLS
-/// - `vault-client-key`: PEM-encoded client private key for mTLS
-///
/// **Local backend:**
/// No secret keys required (keys are stored on disk).
#[derive(Deserialize, Serialize, Clone, Debug, KubeSchema, Default)]
@@ -202,13 +190,12 @@ pub struct EncryptionConfig {
pub local: Option,
/// Reference to a Secret containing sensitive KMS credentials
- /// (Vault token or AppRole credentials, TLS certificates).
+ /// (Vault token or AppRole credentials).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub kms_secret: Option,
- /// Interval in seconds for KMS health-check pings (default: disabled).
- /// When set, the operator stores the value; the in-process KMS library
- /// picks it up from `RUSTFS_KMS_PING_SECONDS`.
+ /// Reserved for future KMS health-check tuning. Not injected into pods: the current RustFS
+ /// release does not read `RUSTFS_KMS_PING_SECONDS` in the server startup path.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ping_seconds: Option,
}
diff --git a/src/types/v1alpha1/tenant/workloads.rs b/src/types/v1alpha1/tenant/workloads.rs
index a5db7dd..a3546c8 100755
--- a/src/types/v1alpha1/tenant/workloads.rs
+++ b/src/types/v1alpha1/tenant/workloads.rs
@@ -25,9 +25,6 @@ const DEFAULT_RUN_AS_USER: i64 = 10001;
const DEFAULT_RUN_AS_GROUP: i64 = 10001;
const DEFAULT_FS_GROUP: i64 = 10001;
-const KMS_CERT_VOLUME_NAME: &str = "kms-tls";
-const KMS_CERT_MOUNT_PATH: &str = "/etc/rustfs/kms/tls";
-
fn volume_claim_template_name(shard: i32) -> String {
format!("{VOLUME_CLAIM_TEMPLATE_PREFIX}-{shard}")
}
@@ -222,6 +219,11 @@ impl Tenant {
/// Build KMS-related environment variables, pod volumes and container volume mounts
/// based on `spec.encryption`.
///
+ /// Names align with the RustFS server (`rustfs/src/init.rs`, `rustfs/src/config/cli.rs`) and
+ /// `rustfs_kms::KmsConfig::from_env()` (`rustfs/crates/kms/src/config.rs`) for forward compatibility.
+ /// The server currently reads `RUSTFS_KMS_ENABLE`, `RUSTFS_KMS_BACKEND`, `RUSTFS_KMS_KEY_DIR`,
+ /// `RUSTFS_KMS_DEFAULT_KEY_ID`, `RUSTFS_KMS_VAULT_ADDRESS`, and `RUSTFS_KMS_VAULT_TOKEN` on startup.
+ ///
/// Returns `(env_vars, pod_volumes, volume_mounts)`.
fn configure_kms(
&self,
@@ -238,17 +240,17 @@ impl Tenant {
}
let mut env = Vec::new();
- let mut volumes = Vec::new();
- let mut mounts = Vec::new();
+ let volumes: Vec = vec![];
+ let mounts: Vec = vec![];
env.push(corev1::EnvVar {
- name: "RUSTFS_KMS_BACKEND".to_owned(),
- value: Some(enc.backend.to_string()),
+ name: "RUSTFS_KMS_ENABLE".to_owned(),
+ value: Some("true".to_owned()),
..Default::default()
});
env.push(corev1::EnvVar {
- name: "RUSTFS_KMS_AUTO_START".to_owned(),
- value: Some("true".to_owned()),
+ name: "RUSTFS_KMS_BACKEND".to_owned(),
+ value: Some(enc.backend.to_string()),
..Default::default()
});
@@ -256,17 +258,10 @@ impl Tenant {
KmsBackendType::Vault => {
if let Some(ref vault) = enc.vault {
env.push(corev1::EnvVar {
- name: "RUSTFS_KMS_VAULT_ENDPOINT".to_owned(),
+ name: "RUSTFS_KMS_VAULT_ADDRESS".to_owned(),
value: Some(vault.endpoint.clone()),
..Default::default()
});
- if let Some(ref engine) = vault.engine {
- env.push(corev1::EnvVar {
- name: "RUSTFS_KMS_VAULT_ENGINE".to_owned(),
- value: Some(engine.clone()),
- ..Default::default()
- });
- }
if let Some(ref ns) = vault.namespace {
env.push(corev1::EnvVar {
name: "RUSTFS_KMS_VAULT_NAMESPACE".to_owned(),
@@ -274,17 +269,23 @@ impl Tenant {
..Default::default()
});
}
- if let Some(ref prefix) = vault.prefix {
+ // Transit secrets engine mount (rustfs-kms default: `transit`).
+ env.push(corev1::EnvVar {
+ name: "RUSTFS_KMS_VAULT_MOUNT_PATH".to_owned(),
+ value: Some("transit".to_owned()),
+ ..Default::default()
+ });
+ if let Some(ref kv_mount) = vault.engine {
env.push(corev1::EnvVar {
- name: "RUSTFS_KMS_VAULT_PREFIX".to_owned(),
- value: Some(prefix.clone()),
+ name: "RUSTFS_KMS_VAULT_KV_MOUNT".to_owned(),
+ value: Some(kv_mount.clone()),
..Default::default()
});
}
- if vault.tls_skip_verify == Some(true) {
+ if let Some(ref prefix) = vault.prefix {
env.push(corev1::EnvVar {
- name: "RUSTFS_KMS_VAULT_TLS_SKIP_VERIFY".to_owned(),
- value: Some("true".to_owned()),
+ name: "RUSTFS_KMS_VAULT_KEY_PREFIX".to_owned(),
+ value: Some(prefix.clone()),
..Default::default()
});
}
@@ -306,10 +307,10 @@ impl Tenant {
});
if let Some(ar) = enc.vault.as_ref().and_then(|v| v.app_role.as_ref()) {
- if let Some(ref engine) = ar.engine {
+ if let Some(ref approle_engine) = ar.engine {
env.push(corev1::EnvVar {
name: "RUSTFS_KMS_VAULT_APPROLE_ENGINE".to_owned(),
- value: Some(engine.clone()),
+ value: Some(approle_engine.clone()),
..Default::default()
});
}
@@ -365,64 +366,6 @@ impl Tenant {
..Default::default()
});
}
-
- // Only mount TLS certificates when explicitly enabled
- let custom_certs = enc
- .vault
- .as_ref()
- .and_then(|v| v.custom_certificates)
- .unwrap_or(false);
-
- if custom_certs {
- volumes.push(corev1::Volume {
- name: KMS_CERT_VOLUME_NAME.to_string(),
- secret: Some(corev1::SecretVolumeSource {
- secret_name: Some(secret_ref.name.clone()),
- items: Some(vec![
- corev1::KeyToPath {
- key: "vault-ca-cert".to_string(),
- path: "ca.crt".to_string(),
- ..Default::default()
- },
- corev1::KeyToPath {
- key: "vault-client-cert".to_string(),
- path: "client.crt".to_string(),
- ..Default::default()
- },
- corev1::KeyToPath {
- key: "vault-client-key".to_string(),
- path: "client.key".to_string(),
- ..Default::default()
- },
- ]),
- optional: Some(true),
- ..Default::default()
- }),
- ..Default::default()
- });
- mounts.push(corev1::VolumeMount {
- name: KMS_CERT_VOLUME_NAME.to_string(),
- mount_path: KMS_CERT_MOUNT_PATH.to_string(),
- read_only: Some(true),
- ..Default::default()
- });
-
- env.push(corev1::EnvVar {
- name: "RUSTFS_KMS_VAULT_TLS_CA".to_owned(),
- value: Some(format!("{KMS_CERT_MOUNT_PATH}/ca.crt")),
- ..Default::default()
- });
- env.push(corev1::EnvVar {
- name: "RUSTFS_KMS_VAULT_TLS_CERT".to_owned(),
- value: Some(format!("{KMS_CERT_MOUNT_PATH}/client.crt")),
- ..Default::default()
- });
- env.push(corev1::EnvVar {
- name: "RUSTFS_KMS_VAULT_TLS_KEY".to_owned(),
- value: Some(format!("{KMS_CERT_MOUNT_PATH}/client.key")),
- ..Default::default()
- });
- }
}
}
KmsBackendType::Local => {
@@ -430,31 +373,30 @@ impl Tenant {
let key_dir = local_cfg
.and_then(|l| l.key_directory.as_deref())
.unwrap_or("/data/kms-keys");
- let master_key_id = local_cfg
+ let default_key_id = local_cfg
.and_then(|l| l.master_key_id.as_deref())
.unwrap_or("default-master-key");
+ // `rustfs` server reads `RUSTFS_KMS_KEY_DIR` (see `build_local_kms_config`).
+ env.push(corev1::EnvVar {
+ name: "RUSTFS_KMS_KEY_DIR".to_owned(),
+ value: Some(key_dir.to_string()),
+ ..Default::default()
+ });
+ // Duplicate for `rustfs_kms::KmsConfig::from_env()` which uses `RUSTFS_KMS_LOCAL_KEY_DIR`.
env.push(corev1::EnvVar {
name: "RUSTFS_KMS_LOCAL_KEY_DIR".to_owned(),
value: Some(key_dir.to_string()),
..Default::default()
});
env.push(corev1::EnvVar {
- name: "RUSTFS_KMS_LOCAL_MASTER_KEY_ID".to_owned(),
- value: Some(master_key_id.to_string()),
+ name: "RUSTFS_KMS_DEFAULT_KEY_ID".to_owned(),
+ value: Some(default_key_id.to_string()),
..Default::default()
});
}
}
- if let Some(ping) = enc.ping_seconds {
- env.push(corev1::EnvVar {
- name: "RUSTFS_KMS_PING_SECONDS".to_owned(),
- value: Some(ping.to_string()),
- ..Default::default()
- });
- }
-
(env, volumes, mounts)
}