mirror of
https://github.com/rustfs/rustfs.git
synced 2026-10-03 20:20:29 +00:00
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:
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user