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    /// Check IDs to force-enable (e.g. from an audit template).
116    /// Empty = all checks enabled per severity gates.
117    #[serde(default)]
118    pub enabled_checks: Vec<String>,
119    /// Check IDs to force-disable (e.g. from an audit template).
120    #[serde(default)]
121    pub disabled_checks: Vec<String>,
122}
123
124fn default_max_findings() -> usize {
125    50
126}
127
128impl Default for SecurityConfig {
129    fn default() -> Self {
130        Self {
131            enable_high: true,
132            enable_medium: true,
133            enable_low: true,
134            enable_info: false,
135            exploit_analysis: true,
136            gas_analysis: false,
137            bytecode_analysis: false,
138            max_findings_per_check: 50,
139            severity_overrides: std::collections::HashMap::new(),
140            enabled_checks: Vec::new(),
141            disabled_checks: Vec::new(),
142        }
143    }
144}
145
146/// Report configuration.
147#[derive(Debug, Clone, Serialize, Deserialize)]
148pub struct ReportConfig {
149    /// Include code snippets in reports.
150    #[serde(default = "default_true")]
151    pub include_snippets: bool,
152    /// Include exploit paths in reports.
153    #[serde(default = "default_true")]
154    pub include_exploit_paths: bool,
155    /// Include recommendations in reports.
156    #[serde(default = "default_true")]
157    pub include_recommendations: bool,
158    /// Output directory for report files.
159    #[serde(default = "default_report_dir")]
160    pub output_dir: String,
161    /// Generate summary only (no details).
162    #[serde(default)]
163    pub summary_only: bool,
164}
165
166fn default_report_dir() -> String {
167    "reports".into()
168}
169
170impl Default for ReportConfig {
171    fn default() -> Self {
172        Self {
173            include_snippets: true,
174            include_exploit_paths: true,
175            include_recommendations: true,
176            output_dir: default_report_dir(),
177            summary_only: false,
178        }
179    }
180}
181
182/// Cache configuration.
183#[derive(Debug, Clone, Serialize, Deserialize)]
184pub struct CacheConfig {
185    /// Enable caching.
186    #[serde(default = "default_true")]
187    pub enabled: bool,
188    /// Cache directory path.
189    #[serde(default = "default_cache_dir")]
190    pub directory: String,
191    /// Maximum cache size in MB.
192    #[serde(default = "default_cache_size")]
193    pub max_size_mb: u64,
194    /// Cache TTL in seconds.
195    #[serde(default = "default_cache_ttl")]
196    pub ttl_seconds: u64,
197}
198
199fn default_cache_dir() -> String {
200    ".forge-guard-cache".into()
201}
202fn default_cache_size() -> u64 {
203    500
204}
205fn default_cache_ttl() -> u64 {
206    3600
207}
208
209impl Default for CacheConfig {
210    fn default() -> Self {
211        Self {
212            enabled: true,
213            directory: default_cache_dir(),
214            max_size_mb: 500,
215            ttl_seconds: 3600,
216        }
217    }
218}
219
220/// AI auditor configuration.
221#[derive(Debug, Clone, Serialize, Deserialize)]
222pub struct AiConfig {
223    /// Provider type: "openai", "claude", "ollama".
224    #[serde(default = "default_ai_provider")]
225    pub provider: String,
226    /// Model identifier.
227    #[serde(default = "default_ai_model")]
228    pub model: String,
229    /// Sampling temperature.
230    #[serde(default = "default_ai_temperature")]
231    pub temperature: f64,
232    /// Maximum tokens per response.
233    #[serde(default = "default_ai_max_tokens")]
234    pub max_tokens: u32,
235    /// Minimum confidence for findings (0.0–1.0).
236    #[serde(default = "default_ai_min_confidence")]
237    pub min_confidence: f64,
238    /// Run full audit (security + gas + logic) when enabled.
239    #[serde(default)]
240    pub full_audit: bool,
241}
242
243fn default_ai_provider() -> String {
244    "openai".into()
245}
246fn default_ai_model() -> String {
247    "gpt-4".into()
248}
249fn default_ai_temperature() -> f64 {
250    0.1
251}
252fn default_ai_max_tokens() -> u32 {
253    4000
254}
255fn default_ai_min_confidence() -> f64 {
256    0.5
257}
258
259impl Default for AiConfig {
260    fn default() -> Self {
261        Self {
262            provider: default_ai_provider(),
263            model: default_ai_model(),
264            temperature: default_ai_temperature(),
265            max_tokens: default_ai_max_tokens(),
266            min_confidence: default_ai_min_confidence(),
267            full_audit: false,
268        }
269    }
270}
271
272/// Plugin configuration.
273#[derive(Debug, Clone, Serialize, Deserialize)]
274pub struct PluginConfig {
275    /// Directories to search for plugins.
276    #[serde(default = "default_plugin_dirs")]
277    pub directories: Vec<String>,
278    /// Plugins to enable (empty = all).
279    #[serde(default)]
280    pub enabled: Vec<String>,
281    /// Plugins to disable.
282    #[serde(default)]
283    pub disabled: Vec<String>,
284    /// Allow loading plugins from outside the project.
285    #[serde(default)]
286    pub allow_external: bool,
287}
288
289fn default_plugin_dirs() -> Vec<String> {
290    vec![".forge-guard/plugins".into()]
291}
292
293impl Default for PluginConfig {
294    fn default() -> Self {
295        Self {
296            directories: default_plugin_dirs(),
297            enabled: Vec::new(),
298            disabled: Vec::new(),
299            allow_external: false,
300        }
301    }
302}