datafold/security/
mod.rs

1//! Security module for client key management, message signing, and encryption
2//!
3//! This module provides:
4//! - Ed25519 key pair generation and management
5//! - Message signing and verification
6//! - AES-GCM encryption/decryption for data at rest
7//! - Integration with network and permissions layers
8
9use base64::{engine::general_purpose, Engine as _};
10
11pub mod encryption;
12pub mod keys;
13pub mod signing;
14pub mod types;
15pub mod utils;
16
17pub use encryption::*;
18pub use keys::*;
19pub use signing::*;
20pub use types::{
21    EncryptedData, KeyRegistrationRequest, KeyRegistrationResponse, PublicKeyInfo,
22    PublicKeyRegistration, SignedMessage, VerificationResult,
23};
24pub use utils::*;
25
26use thiserror::Error;
27
28/// Security-related errors
29#[derive(Error, Debug)]
30pub enum SecurityError {
31    #[error("Key generation failed: {0}")]
32    KeyGenerationFailed(String),
33
34    #[error("Signature verification failed: {0}")]
35    SignatureVerificationFailed(String),
36
37    #[error("Encryption failed: {0}")]
38    EncryptionFailed(String),
39
40    #[error("Decryption failed: {0}")]
41    DecryptionFailed(String),
42
43    #[error("Invalid public key: {0}")]
44    InvalidPublicKey(String),
45
46    #[error("Invalid signature: {0}")]
47    InvalidSignature(String),
48
49    #[error("Key not found: {0}")]
50    KeyNotFound(String),
51
52    #[error("Serialization error: {0}")]
53    SerializationError(String),
54
55    #[error("Deserialization error: {0}")]
56    DeserializationError(String),
57
58    #[error("Invalid key format: {0}")]
59    InvalidKeyFormat(String),
60}
61
62pub type SecurityResult<T> = Result<T, SecurityError>;
63
64/// Security module configuration
65#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
66pub struct SecurityConfig {
67    /// Whether to require TLS for all connections
68    pub require_tls: bool,
69    /// Whether to require signatures on all messages
70    pub require_signatures: bool,
71    /// Whether to encrypt sensitive data at rest
72    pub encrypt_at_rest: bool,
73    /// Master key for at-rest encryption (should be securely managed)
74    #[serde(skip)]
75    pub master_key: Option<[u8; 32]>,
76}
77
78impl Default for SecurityConfig {
79    fn default() -> Self {
80        Self {
81            require_tls: true,
82            require_signatures: true,
83            encrypt_at_rest: false, // Disabled by default (enable with a master_key)
84            master_key: None,
85        }
86    }
87}
88
89impl SecurityConfig {
90    /// Create a new security config with default settings
91    pub fn new() -> Self {
92        Self::default()
93    }
94
95    /// Load security configuration from environment variables
96    pub fn from_env() -> Self {
97        let mut config = Self::default();
98
99        // Load from environment variables
100        if let Ok(value) = std::env::var("DATAFOLD_REQUIRE_TLS") {
101            config.require_tls = value.parse().unwrap_or(true);
102        }
103
104        if let Ok(value) = std::env::var("DATAFOLD_REQUIRE_SIGNATURES") {
105            config.require_signatures = value.parse().unwrap_or(true);
106        }
107
108        if let Ok(value) = std::env::var("DATAFOLD_ENCRYPT_AT_REST") {
109            config.encrypt_at_rest = value.parse().unwrap_or(true);
110        }
111
112        // Load master key from environment (base64 encoded)
113        if let Ok(key_base64) = std::env::var("DATAFOLD_MASTER_KEY") {
114            if let Ok(key_bytes) = general_purpose::STANDARD.decode(&key_base64) {
115                if key_bytes.len() == 32 {
116                    let mut key = [0u8; 32];
117                    key.copy_from_slice(&key_bytes);
118                    config.master_key = Some(key);
119                }
120            }
121        }
122
123        config
124    }
125
126    /// Enable or disable TLS requirement
127    pub fn with_tls(mut self, require_tls: bool) -> Self {
128        self.require_tls = require_tls;
129        self
130    }
131
132    /// Enable or disable signature requirement
133    pub fn with_signatures(mut self, require_signatures: bool) -> Self {
134        self.require_signatures = require_signatures;
135        self
136    }
137
138    /// Enable or disable at-rest encryption
139    pub fn with_encryption(mut self, encrypt_at_rest: bool) -> Self {
140        self.encrypt_at_rest = encrypt_at_rest;
141        self
142    }
143
144    /// Set the master key for at-rest encryption
145    pub fn with_master_key(mut self, key: [u8; 32]) -> Self {
146        self.master_key = Some(key);
147        self
148    }
149}