test(kms): cover non-default Vault Transit paths (#7657)

Backport the Vault coverage from 4d31621f0a. Keep the release cleanup polls synchronized with object read locks.
This commit is contained in:
overtrue
2026-09-14 22:10:41 +08:00
parent 6fc748d6de
commit 397ee852da
2 changed files with 66 additions and 8 deletions
+33 -4
View File
@@ -29,6 +29,8 @@ use rustfs_kms::{
};
use std::collections::HashMap;
const LIVE_KEY_DESCRIPTION: &str = "AppRole live metadata";
fn assert_approle_config(config: &KmsConfig, expected_backend: KmsBackend) {
assert_eq!(config.backend, expected_backend);
let auth_method = match &config.backend_config {
@@ -42,12 +44,13 @@ fn assert_approle_config(config: &KmsConfig, expected_backend: KmsBackend) {
);
}
async fn exercise_backend<B: KmsBackendTrait + ?Sized>(backend: &B, key_prefix: &str) -> rustfs_kms::Result<()> {
async fn exercise_backend<B: KmsBackendTrait + ?Sized>(backend: &B, key_prefix: &str) -> rustfs_kms::Result<String> {
let key_id = format!("{key_prefix}-{}", uuid::Uuid::new_v4());
let created = backend
.create_key(CreateKeyRequest {
key_name: Some(key_id.clone()),
key_usage: KeyUsage::EncryptDecrypt,
description: Some(LIVE_KEY_DESCRIPTION.to_string()),
..Default::default()
})
.await?;
@@ -57,6 +60,7 @@ async fn exercise_backend<B: KmsBackendTrait + ?Sized>(backend: &B, key_prefix:
.describe_key(rustfs_kms::DescribeKeyRequest { key_id: key_id.clone() })
.await?;
assert_eq!(described.key_metadata.key_id, key_id);
assert_eq!(described.key_metadata.description.as_deref(), Some(LIVE_KEY_DESCRIPTION));
let listed = backend
.list_keys(ListKeysRequest {
@@ -88,7 +92,7 @@ async fn exercise_backend<B: KmsBackendTrait + ?Sized>(backend: &B, key_prefix:
})
.await?;
assert_eq!(unwrapped.plaintext, generated.plaintext_key);
Ok(())
Ok(key_id)
}
#[tokio::test]
@@ -97,7 +101,7 @@ async fn vault_kv2_approle_auth_live() -> rustfs_kms::Result<()> {
let config = KmsConfig::from_env()?;
assert_approle_config(&config, KmsBackend::VaultKv2);
let backend = VaultKmsBackend::new(config).await?;
exercise_backend(&backend, "rustfs-approle-kv2").await
exercise_backend(&backend, "rustfs-approle-kv2").await.map(|_| ())
}
#[tokio::test]
@@ -109,9 +113,34 @@ async fn vault_transit_approle_auth_live() -> rustfs_kms::Result<()> {
BackendConfig::VaultTransit(vault) => vault,
_ => panic!("expected Vault Transit configuration"),
};
assert_eq!(transit.mount_path, "transit");
assert_eq!(transit.metadata_kv_mount, DEFAULT_VAULT_TRANSIT_METADATA_KV_MOUNT);
assert_eq!(transit.metadata_key_prefix, DEFAULT_VAULT_TRANSIT_METADATA_KEY_PREFIX);
let backend = VaultTransitKmsBackend::new(config).await?;
exercise_backend(&backend, "rustfs-approle-transit").await
exercise_backend(&backend, "rustfs-approle-transit").await.map(|_| ())
}
#[tokio::test]
#[ignore = "requires a real Vault AppRole; run scripts/test/vault_approle_kms_live.sh"]
async fn vault_transit_approle_custom_paths_live() -> rustfs_kms::Result<()> {
let config = KmsConfig::from_env()?;
assert_approle_config(&config, KmsBackend::VaultTransit);
let BackendConfig::VaultTransit(transit) = &config.backend_config else {
panic!("expected Vault Transit configuration");
};
assert_eq!(transit.mount_path, "kms-test/transit");
assert_eq!(transit.metadata_kv_mount, "kms-test/metadata");
assert_eq!(transit.metadata_key_prefix, "custom/transit-metadata");
let backend = VaultTransitKmsBackend::new(config.clone()).await?;
let key_id = exercise_backend(&backend, "rustfs-approle-custom-transit").await?;
drop(backend);
// A fresh backend must read the stored record, not synthesize Enabled
// metadata or reuse a record cached during key creation.
let restarted = VaultTransitKmsBackend::new(config).await?;
let described = restarted.describe_key(rustfs_kms::DescribeKeyRequest { key_id }).await?;
assert_eq!(described.key_metadata.description.as_deref(), Some(LIVE_KEY_DESCRIPTION));
Ok(())
}
+33 -4
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
# Start an ephemeral Vault, issue a least-privilege AppRole, and run the two
# Start an ephemeral Vault, issue a least-privilege AppRole, and run the
# ignored RustFS KMS checks without ever exposing the generated credentials.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -77,6 +77,8 @@ if [[ "$ready" != 1 ]]; then
fi
vault_cli secrets enable -path=transit transit >/dev/null
vault_cli secrets enable -path=kms-test/transit transit >/dev/null
vault_cli secrets enable -path=kms-test/metadata kv-v2 >/dev/null
vault_cli auth enable approle >/dev/null
POLICY_NAME="rustfs-kms-live-$$"
@@ -105,6 +107,11 @@ path "secret/metadata/rustfs/kms/transit-metadata" {
capabilities = ["list"]
}
# Non-default Transit metadata mount and prefix, both containing slashes.
path "kms-test/metadata/data/custom/transit-metadata/*" {
capabilities = ["create", "read", "update"]
}
# Transit key lifecycle and data-path operations.
path "transit/keys" {
capabilities = ["list"]
@@ -118,6 +125,20 @@ path "transit/encrypt/*" {
path "transit/decrypt/*" {
capabilities = ["update"]
}
# The same operations under a non-default, nested Transit mount.
path "kms-test/transit/keys" {
capabilities = ["list"]
}
path "kms-test/transit/keys/*" {
capabilities = ["create", "read", "update"]
}
path "kms-test/transit/encrypt/*" {
capabilities = ["update"]
}
path "kms-test/transit/decrypt/*" {
capabilities = ["update"]
}
EOF
vault_cli policy write "$POLICY_NAME" "$POLICY_FILE" >/dev/null
@@ -135,6 +156,9 @@ SECRET_ID="$(vault_cli write -f -field=secret_id "auth/approle/role/${ROLE_NAME}
run_live_test() {
local backend="$1"
local test_name="$2"
local transit_mount="${3:-transit}"
local metadata_mount="${4:-secret}"
local metadata_prefix="${5:-rustfs/kms/transit-metadata}"
local -a backend_env=(
-u RUSTFS_KMS_BACKEND
@@ -178,9 +202,9 @@ run_live_test() {
)
else
backend_env+=(
RUSTFS_KMS_VAULT_MOUNT_PATH=transit
RUSTFS_KMS_VAULT_TRANSIT_METADATA_KV_MOUNT=secret
RUSTFS_KMS_VAULT_TRANSIT_METADATA_PREFIX=rustfs/kms/transit-metadata
RUSTFS_KMS_VAULT_MOUNT_PATH="$transit_mount"
RUSTFS_KMS_VAULT_TRANSIT_METADATA_KV_MOUNT="$metadata_mount"
RUSTFS_KMS_VAULT_TRANSIT_METADATA_PREFIX="$metadata_prefix"
)
fi
@@ -193,4 +217,9 @@ run_live_test() {
cd "$PROJECT_ROOT"
run_live_test vault vault_kv2_approle_auth_live
run_live_test vault-transit vault_transit_approle_auth_live
# Remove the default mounts so a fallback to transit or secret cannot pass.
vault_cli secrets disable transit >/dev/null
vault_cli secrets disable secret >/dev/null
run_live_test vault-transit vault_transit_approle_custom_paths_live \
kms-test/transit kms-test/metadata custom/transit-metadata
echo "Vault AppRole KV2 and Transit live checks passed"