344 lines
8.9 KiB
Rust
Raw Normal View History

//! KMS Module Facade
//!
//! Provides a stable, trait-based interface for the KMS module,
//! reducing coupling by hiding implementation details.
use async_trait::async_trait;
use crate::kms::error::{KmsError, Result};
use crate::kms::types::{KeyData, KeyType, ProviderCredentials};
/// Stable facade trait for Key Management Service operations
///
/// This trait defines the public contract for KMS operations,
/// allowing implementations to change without affecting consumers.
///
/// # Design Goals
///
/// - **Stable Interface**: Public API remains constant across refactorings
/// - **Implementation Hiding**: Internal details are not exposed
/// - **Testability**: Easy to mock for testing
/// - **Extensibility**: New features added without breaking changes
///
/// # Usage
///
/// ```rust,no_run
/// use control_center::kms::{KmsService, KmsConfig};
/// use std::sync::Arc;
///
/// async fn example(kms: Arc<dyn KmsService>) -> anyhow::Result<()> {
/// // Use the trait, not the concrete type
/// let key = kms.generate_key(/* params */).await?;
/// println!("Generated key: {}", key.key_id);
/// Ok(())
/// }
/// ```
#[async_trait]
pub trait KmsService: Send + Sync {
/// Initialize the KMS system
///
/// Performs one-time setup including backend initialization,
/// rotation scheduler startup, and credential manager configuration.
///
/// # Errors
///
/// - `Configuration` - Invalid configuration
/// - `Backend` - Backend initialization failed
/// - `Internal` - System initialization failed
async fn initialize(&mut self) -> Result<()>;
/// Get a key by ID
///
/// Retrieves key data from the configured backend.
/// Access is logged for audit purposes.
///
/// # Arguments
///
/// * `key_id` - Unique identifier for the key
///
/// # Returns
///
/// Key data if found, None otherwise
///
/// # Errors
///
/// - `Backend` - Backend query failed
/// - `Audit` - Audit logging failed
async fn get_key(&self, key_id: &str) -> Result<Option<KeyData>>;
/// Store a new key
///
/// Persists key data to the configured backend.
/// Storage operation is logged for audit purposes.
///
/// # Arguments
///
/// * `key` - Key data to store
///
/// # Returns
///
/// The stored key ID
///
/// # Errors
///
/// - `KeyAlreadyExists` - Key with same ID already exists
/// - `Validation` - Invalid key data
/// - `Backend` - Backend storage failed
async fn store_key(&self, key: KeyData) -> Result<String>;
/// Delete a key by ID
///
/// Removes key from the backend. Deletion is permanent.
/// Operation is logged for audit purposes.
///
/// # Arguments
///
/// * `key_id` - Unique identifier for the key
///
/// # Returns
///
/// true if key was deleted, false if not found
///
/// # Errors
///
/// - `Backend` - Backend deletion failed
/// - `Audit` - Audit logging failed
async fn delete_key(&self, key_id: &str) -> Result<bool>;
/// Encrypt data with a key
///
/// Uses the specified key to encrypt plaintext data.
///
/// # Arguments
///
/// * `key_id` - Key to use for encryption
/// * `plaintext` - Data to encrypt
///
/// # Returns
///
/// Encrypted ciphertext
///
/// # Errors
///
/// - `KeyNotFound` - Specified key does not exist
/// - `Cryptographic` - Encryption operation failed
/// - `PermissionDenied` - Key does not allow encryption
async fn encrypt(&self, key_id: &str, plaintext: &[u8]) -> Result<Vec<u8>>;
/// Decrypt data with a key
///
/// Uses the specified key to decrypt ciphertext data.
///
/// # Arguments
///
/// * `key_id` - Key to use for decryption
/// * `ciphertext` - Data to decrypt
///
/// # Returns
///
/// Decrypted plaintext
///
/// # Errors
///
/// - `KeyNotFound` - Specified key does not exist
/// - `Cryptographic` - Decryption operation failed
/// - `PermissionDenied` - Key does not allow decryption
async fn decrypt(&self, key_id: &str, ciphertext: &[u8]) -> Result<Vec<u8>>;
/// Generate a new encryption key
///
/// Creates a new key with the specified parameters and stores it.
///
/// # Arguments
///
/// * `key_type` - Type of key to generate
///
/// # Returns
///
/// Generated key data
///
/// # Errors
///
/// - `Cryptographic` - Key generation failed
/// - `Backend` - Storage failed
async fn generate_key(&self, key_type: KeyType) -> Result<KeyData>;
/// Rotate a key
///
/// Generates a new version of an existing key.
/// Old version is marked as deprecated but retained.
///
/// # Arguments
///
/// * `key_id` - Key to rotate
///
/// # Returns
///
/// New key data
///
/// # Errors
///
/// - `KeyNotFound` - Specified key does not exist
/// - `Rotation` - Rotation operation failed
async fn rotate_key(&self, key_id: &str) -> Result<KeyData>;
/// Get provider credentials
///
/// Retrieves stored credentials for a cloud provider.
///
/// # Arguments
///
/// * `provider` - Provider name (e.g., "aws", "upcloud")
///
/// # Returns
///
/// Provider credentials if found
///
/// # Errors
///
/// - `Backend` - Credential retrieval failed
async fn get_provider_credentials(&self, provider: &str)
-> Result<Option<ProviderCredentials>>;
/// Store provider credentials
///
/// Securely stores credentials for a cloud provider.
///
/// # Arguments
///
/// * `provider` - Provider name
/// * `credentials` - Provider credentials
///
/// # Errors
///
/// - `Backend` - Credential storage failed
/// - `Cryptographic` - Credential encryption failed
async fn store_provider_credentials(
&self,
provider: &str,
credentials: ProviderCredentials,
) -> Result<()>;
/// Shutdown the KMS system
///
/// Gracefully shuts down all KMS components including
/// rotation scheduler and backend connections.
///
/// # Errors
///
/// - `Backend` - Backend shutdown failed
async fn shutdown(&mut self) -> Result<()>;
}
/// Extension trait for advanced KMS operations
///
/// Provides optional advanced functionality that not all implementations
/// may support. Check backend capabilities before using.
#[async_trait]
pub trait KmsServiceExt: KmsService {
/// Health check for KMS system
///
/// Returns detailed health status for all components.
async fn health_check(&self) -> Result<KmsHealthStatus>;
/// List all keys matching criteria
///
/// Returns keys filtered by optional parameters.
///
/// # Arguments
///
/// * `key_type` - Filter by key type (None for all)
/// * `status` - Filter by status (None for all)
///
/// # Returns
///
/// Vector of matching key IDs
async fn list_keys(
&self,
key_type: Option<KeyType>,
status: Option<KeyStatus>,
) -> Result<Vec<String>>;
/// Get key statistics
///
/// Returns aggregate metrics about keys in the system.
async fn get_statistics(&self) -> Result<KmsStatistics>;
/// Export key for backup
///
/// Exports a key in encrypted form for backup purposes.
/// Requires export permission on the key.
///
/// # Arguments
///
/// * `key_id` - Key to export
/// * `wrap_key_id` - Key to use for wrapping
///
/// # Returns
///
/// Wrapped key data
async fn export_key(&self, key_id: &str, wrap_key_id: &str) -> Result<Vec<u8>>;
/// Import a key from backup
///
/// Imports a previously exported key.
///
/// # Arguments
///
/// * `wrapped_key` - Encrypted key data
/// * `unwrap_key_id` - Key to use for unwrapping
///
/// # Returns
///
/// Imported key ID
async fn import_key(&self, wrapped_key: &[u8], unwrap_key_id: &str) -> Result<String>;
}
/// KMS health status
#[derive(Debug, Clone)]
pub struct KmsHealthStatus {
pub backend: ComponentHealth,
pub rotation: ComponentHealth,
pub credentials: ComponentHealth,
pub overall: bool,
}
impl KmsHealthStatus {
pub fn is_healthy(&self) -> bool {
self.overall
}
}
/// Component health status
#[derive(Debug, Clone)]
pub struct ComponentHealth {
pub healthy: bool,
pub message: Option<String>,
}
impl ComponentHealth {
pub fn is_healthy(&self) -> bool {
self.healthy
}
}
/// Key status enumeration (re-exported for facade)
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyStatus {
Active,
Pending,
Deactivated,
Compromised,
Destroyed,
Archived,
}
/// KMS statistics
#[derive(Debug, Clone)]
pub struct KmsStatistics {
pub total_keys: usize,
pub active_keys: usize,
pub expired_keys: usize,
pub rotation_pending: usize,
}