Skip to main content

forge_guard/core/
config.rs

1use serde::{Deserialize, Serialize};
2
3/// Global forge-guard configuration.
4#[derive(Debug, Clone, Default, Serialize, Deserialize)]
5pub struct ForgeGuardConfig {
6    /// Deployment guard settings.
7    #[serde(default)]
8    pub deployment: DeploymentConfig,
9    /// Security engine settings.
10    #[serde(default)]
11    pub security: SecurityConfig,
12    /// Report generation settings.
13    #[serde(default)]
14    pub report: ReportConfig,
15    /// Caching settings.
16    #[serde(default)]
17    pub cache: CacheConfig,
18    /// Plugin settings.
19    #[serde(default)]
20    pub plugins: PluginConfig,
21    /// AI auditor settings.
22    #[serde(default)]
23    pub ai: AiConfig,
24}
25
26/// Deployment guard configuration.
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct DeploymentConfig {
29    /// Minimum security score required to deploy (0-100).
30    #[serde(default = "default_min_score")]
31    pub min_score: u8,
32    /// Whether to block on high-severity findings.
33    #[serde(default = "default_true")]
34    pub block_on_high: bool,
35    /// Whether to block on medium-severity findings.
36    #[serde(default)]
37    pub block_on_medium: bool,
38    /// Whether to block on critical findings.
39    #[serde(default = "default_true")]
40    pub block_on_critical: bool,
41    /// Require fuzzing to pass before deployment.
42    #[serde(default = "default_true")]
43    pub require_fuzzing: bool,
44    /// Require invariant tests to pass before deployment.
45    #[serde(default = "default_true")]
46    pub require_invariants: bool,
47    /// Whether to run deployment simulation.
48    #[serde(default = "default_true")]
49    pub simulate_deployment: bool,
50    /// Require on-chain verification after deployment.
51    #[serde(default)]
52    pub require_verification: bool,
53    /// Auto-verify after successful deployment.
54    #[serde(default)]
55    pub auto_verify: bool,
56    /// Explorer API key (reads chain-specific env var when empty).
57    #[serde(default)]
58    pub explorer_api_key: Option<String>,
59}
60
61fn default_min_score() -> u8 {
62    70
63}
64fn default_true() -> bool {
65    true
66}
67
68impl Default for DeploymentConfig {
69    fn default() -> Self {
70        Self {
71            min_score: 70,
72            block_on_high: true,
73            block_on_medium: false,
74            block_on_critical: true,
75            require_fuzzing: true,
76            require_invariants: true,
77            simulate_deployment: true,
78            require_verification: false,
79            auto_verify: false,
80            explorer_api_key: None,
81        }
82    }
83}
84
85/// Security engine configuration.
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct SecurityConfig {
88    /// Enable HIGH severity checks.
89    #[serde(default = "default_true")]
90    pub enable_high: bool,
91    /// Enable MEDIUM severity checks.
92    #[serde(default = "default_true")]
93    pub enable_medium: bool,
94    /// Enable LOW severity checks.
95    #[serde(default = "default_true")]
96    pub enable_low: bool,
97    /// Enable INFORMATIONAL checks.
98    #[serde(default)]
99    pub enable_info: bool,
100    /// Enable exploit path analysis.
101    #[serde(default = "default_true")]
102    pub exploit_analysis: bool,
103    /// Enable gas analysis.
104    #[serde(default)]
105    pub gas_analysis: bool,
106    /// Enable bytecode analysis.
107    #[serde(default)]
108    pub bytecode_analysis: bool,
109    /// Maximum number of findings per check.
110    #[serde(default = "default_max_findings")]
111    pub max_findings_per_check: usize,
112    /// Custom check severities (check_name -> Severity override).
113    #[serde(default)]
114    pub severity_overrides: std::collections::HashMap<String, String>,
115}
116
117fn default_max_findings() -> usize {
118    50
119}
120
121impl Default for SecurityConfig {
122    fn default() -> Self {
123        Self {
124            enable_high: true,
125            enable_medium: true,
126            enable_low: true,
127            enable_info: false,
128            exploit_analysis: true,
129            gas_analysis: false,
130            bytecode_analysis: false,
131            max_findings_per_check: 50,
132            severity_overrides: std::collections::HashMap::new(),
133        }
134    }
135}
136
137/// Report configuration.
138#[derive(Debug, Clone, Serialize, Deserialize)]
139pub struct ReportConfig {
140    /// Include code snippets in reports.
141    #[serde(default = "default_true")]
142    pub include_snippets: bool,
143    /// Include exploit paths in reports.
144    #[serde(default = "default_true")]
145    pub include_exploit_paths: bool,
146    /// Include recommendations in reports.
147    #[serde(default = "default_true")]
148    pub include_recommendations: bool,
149    /// Output directory for report files.
150    #[serde(default = "default_report_dir")]
151    pub output_dir: String,
152    /// Generate summary only (no details).
153    #[serde(default)]
154    pub summary_only: bool,
155}
156
157fn default_report_dir() -> String {
158    "reports".into()
159}
160
161impl Default for ReportConfig {
162    fn default() -> Self {
163        Self {
164            include_snippets: true,
165            include_exploit_paths: true,
166            include_recommendations: true,
167            output_dir: default_report_dir(),
168            summary_only: false,
169        }
170    }
171}
172
173/// Cache configuration.
174#[derive(Debug, Clone, Serialize, Deserialize)]
175pub struct CacheConfig {
176    /// Enable caching.
177    #[serde(default = "default_true")]
178    pub enabled: bool,
179    /// Cache directory path.
180    #[serde(default = "default_cache_dir")]
181    pub directory: String,
182    /// Maximum cache size in MB.
183    #[serde(default = "default_cache_size")]
184    pub max_size_mb: u64,
185    /// Cache TTL in seconds.
186    #[serde(default = "default_cache_ttl")]
187    pub ttl_seconds: u64,
188}
189
190fn default_cache_dir() -> String {
191    ".forge-guard-cache".into()
192}
193fn default_cache_size() -> u64 {
194    500
195}
196fn default_cache_ttl() -> u64 {
197    3600
198}
199
200impl Default for CacheConfig {
201    fn default() -> Self {
202        Self {
203            enabled: true,
204            directory: default_cache_dir(),
205            max_size_mb: 500,
206            ttl_seconds: 3600,
207        }
208    }
209}
210
211/// AI auditor configuration.
212#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct AiConfig {
214    /// Provider type: "openai", "claude", "ollama".
215    #[serde(default = "default_ai_provider")]
216    pub provider: String,
217    /// Model identifier.
218    #[serde(default = "default_ai_model")]
219    pub model: String,
220    /// Sampling temperature.
221    #[serde(default = "default_ai_temperature")]
222    pub temperature: f64,
223    /// Maximum tokens per response.
224    #[serde(default = "default_ai_max_tokens")]
225    pub max_tokens: u32,
226    /// Minimum confidence for findings (0.0–1.0).
227    #[serde(default = "default_ai_min_confidence")]
228    pub min_confidence: f64,
229    /// Run full audit (security + gas + logic) when enabled.
230    #[serde(default)]
231    pub full_audit: bool,
232}
233
234fn default_ai_provider() -> String {
235    "openai".into()
236}
237fn default_ai_model() -> String {
238    "gpt-4".into()
239}
240fn default_ai_temperature() -> f64 {
241    0.1
242}
243fn default_ai_max_tokens() -> u32 {
244    4000
245}
246fn default_ai_min_confidence() -> f64 {
247    0.5
248}
249
250impl Default for AiConfig {
251    fn default() -> Self {
252        Self {
253            provider: default_ai_provider(),
254            model: default_ai_model(),
255            temperature: default_ai_temperature(),
256            max_tokens: default_ai_max_tokens(),
257            min_confidence: default_ai_min_confidence(),
258            full_audit: false,
259        }
260    }
261}
262
263/// Plugin configuration.
264#[derive(Debug, Clone, Serialize, Deserialize)]
265pub struct PluginConfig {
266    /// Directories to search for plugins.
267    #[serde(default = "default_plugin_dirs")]
268    pub directories: Vec<String>,
269    /// Plugins to enable (empty = all).
270    #[serde(default)]
271    pub enabled: Vec<String>,
272    /// Plugins to disable.
273    #[serde(default)]
274    pub disabled: Vec<String>,
275    /// Allow loading plugins from outside the project.
276    #[serde(default)]
277    pub allow_external: bool,
278}
279
280fn default_plugin_dirs() -> Vec<String> {
281    vec![".forge-guard/plugins".into()]
282}
283
284impl Default for PluginConfig {
285    fn default() -> Self {
286        Self {
287            directories: default_plugin_dirs(),
288            enabled: Vec::new(),
289            disabled: Vec::new(),
290            allow_external: false,
291        }
292    }
293}