//! 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, KeyType}; /// use std::sync::Arc; /// /// async fn example(kms: Arc) -> anyhow::Result<()> { /// // Use the trait, not the concrete type /// let key = kms.generate_key(KeyType::Asymmetric).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>; /// 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; /// 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; /// 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>; /// 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>; /// 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; /// 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; /// 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>; /// 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; /// 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, status: Option, ) -> Result>; /// Get key statistics /// /// Returns aggregate metrics about keys in the system. async fn get_statistics(&self) -> Result; /// 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>; /// 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; } /// 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, } 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, }