diff --git a/assets/settings/default.json b/assets/settings/default.json index f51e815fbbc3fa0be0aebd24b65308a47fed72d0..77b34d94cf47937e1172c3ebe5c386526ab5c6fa 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -962,75 +962,26 @@ // Per-tool permission rules for granular control over tool actions. // This setting only applies to the native Zed agent. "tool_permissions": { + // Here are some examples of tool-specific permissions. "tools": { - "terminal": { - "default_mode": "confirm", - "always_deny": [ - // Dangerous rm commands - { "pattern": "rm\\s+-rf\\s+(/|\\.\\.|\"|~|\\*)" }, - { "pattern": "rm\\s+-rf\\s*$" }, - // Disk destruction - { "pattern": "> /dev/sd" }, - { "pattern": "mkfs\\." }, - { "pattern": "dd\\s+if=/dev/(zero|random)" }, - // Fork bomb - { "pattern": ":\\(\\)\\{\\s*:\\|:&\\s*\\};:" }, - // System files - { "pattern": "/etc/passwd" }, - { "pattern": "/etc/shadow" }, - // Windows destructive commands - { "pattern": "del /f /s /q c:\\\\" }, - { "pattern": "format c:" }, - { "pattern": "rd /s /q" }, - ], - "always_confirm": [ - // File deletion - { "pattern": "rm\\s" }, - // Destructive git operations - { "pattern": "git\\s+(reset|clean)\\s+--hard" }, - { "pattern": "git\\s+push\\s+(-f|--force)" }, - // Database operations - { "pattern": "DROP\\s+TABLE", "case_sensitive": true }, - { "pattern": "DELETE\\s+FROM", "case_sensitive": true }, - // Privileged commands - { "pattern": "sudo\\s" }, - ], - }, - "edit_file": { - "default_mode": "confirm", - "always_deny": [ - // Secrets and credentials - { "pattern": "\\.env($|\\.)" }, - { "pattern": "secrets?/" }, - { "pattern": "\\.pem$" }, - { "pattern": "\\.key$" }, - ], - }, - "delete_path": { - "default_mode": "confirm", - "always_deny": [ - // System directories - { "pattern": "^/etc" }, - { "pattern": "^/usr" }, - { "pattern": "^/bin" }, - { "pattern": "^/sbin" }, - { "pattern": "^/var" }, - { "pattern": "^/boot" }, - { "pattern": "^/root" }, - // Home directory root - { "pattern": "^~$" }, - { "pattern": "^/Users/[^/]+$" }, - { "pattern": "^/home/[^/]+$" }, - // Git directory - { "pattern": "\\.git/?$" }, - // Windows system directories - { "pattern": "^C:\\\\Windows" }, - { "pattern": "^C:\\\\Program Files" }, - ], - }, - "fetch": { - "default_mode": "confirm", - }, + // "terminal": { + // "default_mode": "confirm", + // "always_confirm": [ + // // Destructive git operations + // { "pattern": "git\\s+(reset|clean)\\s+--hard" }, + // { "pattern": "git\\s+push\\s+(-f|--force)" }, + // ], + // }, + // "edit_file": { + // "default_mode": "confirm", + // "always_deny": [ + // // Secrets and credentials + // { "pattern": "\\.env($|\\.)" }, + // { "pattern": "secrets?/" }, + // { "pattern": "\\.pem$" }, + // { "pattern": "\\.key$" }, + // ], + // }, }, }, // When enabled, agent edits will be displayed in single-file editors for review diff --git a/crates/agent_settings/src/agent_settings.rs b/crates/agent_settings/src/agent_settings.rs index 9b5960eed27c07528d8dd04ef605064fb1695c2f..79fb87877b9d028bcdf1ff2eb2c78cf085320f07 100644 --- a/crates/agent_settings/src/agent_settings.rs +++ b/crates/agent_settings/src/agent_settings.rs @@ -542,98 +542,6 @@ mod tests { assert_eq!(permissions.invalid_patterns().len(), 2); } - #[test] - fn test_default_json_tool_permissions_parse() { - let default_json = include_str!("../../../assets/settings/default.json"); - - let value: serde_json::Value = serde_json_lenient::from_str(default_json) - .expect("default.json should be valid JSON with comments"); - - let agent = value - .get("agent") - .expect("default.json should have 'agent' key"); - let tool_permissions = agent - .get("tool_permissions") - .expect("agent should have 'tool_permissions' key"); - - let content: ToolPermissionsContent = serde_json::from_value(tool_permissions.clone()) - .expect("tool_permissions should parse into ToolPermissionsContent"); - - let permissions = compile_tool_permissions(Some(content)); - - let terminal = permissions - .tools - .get("terminal") - .expect("terminal tool should be configured"); - assert!( - !terminal.always_deny.is_empty(), - "terminal should have deny rules" - ); - assert!( - !terminal.always_confirm.is_empty(), - "terminal should have confirm rules" - ); - let edit_file = permissions - .tools - .get("edit_file") - .expect("edit_file tool should be configured"); - assert!( - !edit_file.always_deny.is_empty(), - "edit_file should have deny rules" - ); - - let delete_path = permissions - .tools - .get("delete_path") - .expect("delete_path tool should be configured"); - assert!( - !delete_path.always_deny.is_empty(), - "delete_path should have deny rules" - ); - - let fetch = permissions - .tools - .get("fetch") - .expect("fetch tool should be configured"); - assert_eq!( - fetch.default_mode, - settings::ToolPermissionMode::Confirm, - "fetch should have confirm as default mode" - ); - } - - #[test] - fn test_default_deny_rules_match_dangerous_commands() { - let default_json = include_str!("../../../assets/settings/default.json"); - let value: serde_json::Value = serde_json_lenient::from_str(default_json).unwrap(); - let tool_permissions = value["agent"]["tool_permissions"].clone(); - let content: ToolPermissionsContent = serde_json::from_value(tool_permissions).unwrap(); - let permissions = compile_tool_permissions(Some(content)); - - let terminal = permissions.tools.get("terminal").unwrap(); - - let dangerous_commands = [ - "rm -rf /", - "rm -rf ~", - "rm -rf ..", - "mkfs.ext4 /dev/sda", - "dd if=/dev/zero of=/dev/sda", - "cat /etc/passwd", - "cat /etc/shadow", - "del /f /s /q c:\\", - "format c:", - "rd /s /q c:\\windows", - ]; - - for cmd in &dangerous_commands { - assert!( - terminal.always_deny.iter().any(|r| r.is_match(cmd)), - "Command '{}' should be blocked by deny rules", - cmd - ); - } - } - #[test] fn test_deny_takes_precedence_over_allow_and_confirm() { let json = json!({ @@ -739,25 +647,6 @@ mod tests { ); } - #[test] - fn test_default_json_fork_bomb_pattern_matches() { - let default_json = include_str!("../../../assets/settings/default.json"); - let value: serde_json::Value = serde_json_lenient::from_str(default_json).unwrap(); - let tool_permissions = value["agent"]["tool_permissions"].clone(); - let content: ToolPermissionsContent = serde_json::from_value(tool_permissions).unwrap(); - let permissions = compile_tool_permissions(Some(content)); - - let terminal = permissions.tools.get("terminal").unwrap(); - - assert!( - terminal - .always_deny - .iter() - .any(|r| r.is_match(":(){ :|:& };:")), - "Default deny rules should block the classic fork bomb" - ); - } - #[test] fn test_compiled_regex_stores_case_sensitivity() { let case_sensitive = CompiledRegex::new("test", true).unwrap();