Skip to main content

memory_core/
config.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Default, Serialize, Deserialize)]
4#[serde(default)]
5pub struct Config {
6    pub storage: StorageConfig,
7    pub search: SearchConfig,
8    pub validation: ValidationConfig,
9    pub privacy: PrivacyConfig,
10}
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
13#[serde(default)]
14pub struct StorageConfig {
15    pub retention_days: u32,
16    pub vacuum_interval_secs: u64,
17    pub max_db_size_mb: u64,
18    pub busy_timeout_ms: u32,
19    pub cache_size_kb: u32,
20    pub dedup_window_secs: u64,
21    pub encryption_enabled: bool,
22}
23
24impl Default for StorageConfig {
25    fn default() -> Self {
26        Self {
27            retention_days: 90,
28            vacuum_interval_secs: 604800,
29            max_db_size_mb: 500,
30            busy_timeout_ms: 5000,
31            cache_size_kb: 2048,
32            dedup_window_secs: 900,
33            encryption_enabled: false,
34        }
35    }
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
39#[serde(default)]
40pub struct SearchConfig {
41    pub default_limit: u32,
42    pub max_limit: u32,
43}
44
45impl Default for SearchConfig {
46    fn default() -> Self {
47        Self {
48            default_limit: 10,
49            max_limit: 50,
50        }
51    }
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
55#[serde(default)]
56pub struct ValidationConfig {
57    pub max_key_length: usize,
58    pub max_value_length: usize,
59    pub max_tags: usize,
60    pub max_tag_length: usize,
61}
62
63impl Default for ValidationConfig {
64    fn default() -> Self {
65        Self {
66            max_key_length: 256,
67            max_value_length: 2000,
68            max_tags: 20,
69            max_tag_length: 64,
70        }
71    }
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
75#[serde(default)]
76pub struct PrivacyConfig {
77    pub secret_patterns: Vec<String>,
78    pub extra_patterns: Vec<String>,
79    pub replace_defaults: bool,
80    pub file_deny_list: Vec<String>,
81}
82
83impl Default for PrivacyConfig {
84    fn default() -> Self {
85        Self {
86            secret_patterns: default_secret_patterns(),
87            extra_patterns: Vec::new(),
88            replace_defaults: false,
89            file_deny_list: vec![
90                ".env".into(),
91                ".env.*".into(),
92                "*.pem".into(),
93                "*.key".into(),
94                "*.p12".into(),
95                "*.pfx".into(),
96                "id_rsa".into(),
97                "id_ed25519".into(),
98                "id_ecdsa".into(),
99                "*.secret".into(),
100                "credentials.json".into(),
101            ],
102        }
103    }
104}
105
106pub fn default_secret_patterns() -> Vec<String> {
107    vec![
108        r"AKIA[0-9A-Z]{16}".into(),
109        r"-----BEGIN [A-Z ]*PRIVATE KEY-----".into(),
110        r"(?i)(api[_-]?key|token|secret|password)\s*[:=]\s*\S+".into(),
111        r"(?i)mongodb(\+srv)?://[^\s]+".into(),
112        r"(?i)postgres(ql)?://[^\s]+".into(),
113        r"(?i)mysql://[^\s]+".into(),
114        r"(?i)redis://[^\s]+".into(),
115        r"ghp_[a-zA-Z0-9]{36}".into(),
116        r"sk-[a-zA-Z0-9]{48}".into(),
117        r"xoxb-[0-9]+-[0-9]+-[a-zA-Z0-9]+".into(),
118    ]
119}