Skip to main content

clawft_types/config/
policies.rs

1//! Security policy configuration types.
2//!
3//! Defines [`CommandPolicyConfig`] (command execution allowlist/denylist)
4//! and [`UrlPolicyConfig`] (SSRF protection for URL fetching).
5
6use serde::{Deserialize, Serialize};
7
8/// Command execution security policy configuration.
9///
10/// Controls which commands the shell and spawn tools are allowed to execute.
11/// In allowlist mode (default), only explicitly permitted commands can run.
12/// In denylist mode, any command not matching a blocked pattern is allowed.
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct CommandPolicyConfig {
15    /// Policy mode: "allowlist" (default, recommended) or "denylist".
16    #[serde(default = "default_policy_mode")]
17    pub mode: String,
18
19    /// Permitted command basenames when in allowlist mode.
20    /// Overrides defaults when non-empty.
21    #[serde(default)]
22    pub allowlist: Vec<String>,
23
24    /// Blocked command patterns when in denylist mode.
25    /// Overrides defaults when non-empty.
26    #[serde(default)]
27    pub denylist: Vec<String>,
28}
29
30fn default_policy_mode() -> String {
31    "allowlist".to_string()
32}
33
34impl Default for CommandPolicyConfig {
35    fn default() -> Self {
36        Self {
37            mode: default_policy_mode(),
38            allowlist: Vec::new(),
39            denylist: Vec::new(),
40        }
41    }
42}
43
44/// URL safety policy configuration for SSRF protection.
45///
46/// Controls which URLs the web fetch tool is allowed to access.
47/// When enabled (default), requests to private networks, loopback
48/// addresses, and cloud metadata endpoints are blocked.
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct UrlPolicyConfig {
51    /// Whether URL safety validation is enabled.
52    #[serde(default = "default_url_policy_enabled")]
53    pub enabled: bool,
54
55    /// Allow requests to private/internal IP ranges.
56    #[serde(default, alias = "allowPrivate")]
57    pub allow_private: bool,
58
59    /// Domains that bypass all safety checks.
60    #[serde(default, alias = "allowedDomains")]
61    pub allowed_domains: Vec<String>,
62
63    /// Domains that are always blocked.
64    #[serde(default, alias = "blockedDomains")]
65    pub blocked_domains: Vec<String>,
66}
67
68fn default_url_policy_enabled() -> bool {
69    true
70}
71
72impl Default for UrlPolicyConfig {
73    fn default() -> Self {
74        Self {
75            enabled: default_url_policy_enabled(),
76            allow_private: false,
77            allowed_domains: Vec::new(),
78            blocked_domains: Vec::new(),
79        }
80    }
81}