diff --git a/codex-rs/core/src/exec_policy_tests.rs b/codex-rs/core/src/exec_policy_tests.rs index 2db07a0fcef7..fa11a4dbc1cf 100644 --- a/codex-rs/core/src/exec_policy_tests.rs +++ b/codex-rs/core/src/exec_policy_tests.rs @@ -23,7 +23,6 @@ use codex_protocol::permissions::FileSystemSpecialPath; use codex_protocol::permissions::NetworkSandboxPolicy; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::GranularApprovalConfig; -use codex_protocol::protocol::SandboxPolicy; use codex_utils_absolute_path::AbsolutePathBuf; use pretty_assertions::assert_eq; use std::fs; @@ -126,10 +125,6 @@ fn external_file_system_sandbox_policy() -> FileSystemSandboxPolicy { FileSystemSandboxPolicy::external_sandbox() } -fn permission_profile_from_sandbox_policy(sandbox_policy: &SandboxPolicy) -> PermissionProfile { - PermissionProfile::from_legacy_sandbox_policy(sandbox_policy) -} - async fn test_config() -> (TempDir, Config) { let home = TempDir::new().expect("create temp dir"); let config = ConfigBuilder::without_managed_config_for_tests() @@ -644,7 +639,7 @@ async fn evaluates_bash_lc_inner_commands() { "rm -rf /some/important/folder".to_string(), ], approval_policy: AskForApproval::OnRequest, - sandbox_policy: SandboxPolicy::DangerFullAccess, + permission_profile: PermissionProfile::Disabled, file_system_sandbox_policy: unrestricted_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -726,7 +721,7 @@ async fn evaluates_heredoc_script_against_prefix_rules() { policy_src: Some(r#"prefix_rule(pattern=["python3"], decision="allow")"#.to_string()), command, approval_policy: AskForApproval::OnRequest, - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -750,7 +745,7 @@ async fn omits_auto_amendment_for_heredoc_fallback_prompts() { "python3 <<'PY'\nprint('hello')\nPY".to_string(), ], approval_policy: AskForApproval::UnlessTrusted, - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -774,7 +769,7 @@ async fn drops_requested_amendment_for_heredoc_fallback_prompts_when_it_wont_mat "python3 <<'PY'\nprint('hello')\nPY".to_string(), ], approval_policy: AskForApproval::UnlessTrusted, - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: Some(vec![ @@ -811,7 +806,7 @@ prefix_rule( "/some/important/folder".to_string(), ], approval_policy: AskForApproval::OnRequest, - sandbox_policy: SandboxPolicy::DangerFullAccess, + permission_profile: PermissionProfile::Disabled, file_system_sandbox_policy: unrestricted_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -830,7 +825,7 @@ async fn exec_approval_requirement_prefers_execpolicy_match() { policy_src: Some(r#"prefix_rule(pattern=["rm"], decision="prompt")"#.to_string()), command: vec!["rm".to_string()], approval_policy: AskForApproval::OnRequest, - sandbox_policy: SandboxPolicy::DangerFullAccess, + permission_profile: PermissionProfile::Disabled, file_system_sandbox_policy: unrestricted_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -858,7 +853,7 @@ prefix_rule(pattern=["git"], decision="allow") policy_src: Some(policy_src), command: vec![git_path, "status".to_string()], approval_policy: AskForApproval::UnlessTrusted, - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -892,7 +887,7 @@ prefix_rule(pattern=["git"], decision="prompt") policy_src: Some(policy_src), command: vec![disallowed_git_path.clone(), "status".to_string()], approval_policy: AskForApproval::UnlessTrusted, - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -919,7 +914,7 @@ async fn requested_prefix_rule_can_approve_absolute_path_commands() { "cargo-insta".to_string(), ], approval_policy: AskForApproval::UnlessTrusted, - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: Some(vec!["cargo".to_string(), "install".to_string()]), @@ -942,7 +937,7 @@ async fn exec_approval_requirement_respects_approval_policy() { policy_src: Some(r#"prefix_rule(pattern=["rm"], decision="prompt")"#.to_string()), command: vec!["rm".to_string()], approval_policy: AskForApproval::Never, - sandbox_policy: SandboxPolicy::DangerFullAccess, + permission_profile: PermissionProfile::Disabled, file_system_sandbox_policy: unrestricted_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -968,7 +963,7 @@ fn unmatched_granular_policy_still_prompts_for_restricted_sandbox_escalation() { request_permissions: true, mcp_elicitations: true, }), - &permission_profile_from_sandbox_policy(&SandboxPolicy::new_read_only_policy()), + &PermissionProfile::read_only(), &read_only_file_system_sandbox_policy(), Path::new("/tmp"), &command, @@ -1067,7 +1062,7 @@ async fn exec_approval_requirement_prompts_for_inline_additional_permissions_und "touch requested-dir/requested-but-unused.txt".to_string(), ], approval_policy: AskForApproval::OnRequest, - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::WithAdditionalPermissions, prefix_rule: None, @@ -1097,7 +1092,7 @@ async fn exec_approval_requirement_rejects_unmatched_sandbox_escalation_when_gra request_permissions: true, mcp_elicitations: true, }), - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::RequireEscalated, prefix_rule: None, @@ -1133,9 +1128,7 @@ async fn mixed_rule_and_sandbox_prompt_prioritizes_rule_for_rejection_decision() request_permissions: true, mcp_elicitations: true, }), - permission_profile: permission_profile_from_sandbox_policy( - &SandboxPolicy::new_read_only_policy(), - ), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: &read_only_file_system_sandbox_policy(), sandbox_cwd: Path::new("/tmp"), sandbox_permissions: SandboxPermissions::RequireEscalated, @@ -1173,9 +1166,7 @@ async fn mixed_rule_and_sandbox_prompt_rejects_when_granular_rules_are_disabled( request_permissions: true, mcp_elicitations: true, }), - permission_profile: permission_profile_from_sandbox_policy( - &SandboxPolicy::new_read_only_policy(), - ), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: &read_only_file_system_sandbox_policy(), sandbox_cwd: Path::new("/tmp"), sandbox_permissions: SandboxPermissions::RequireEscalated, @@ -1200,9 +1191,7 @@ async fn exec_approval_requirement_falls_back_to_heuristics() { .create_exec_approval_requirement_for_command(ExecApprovalRequest { command: &command, approval_policy: AskForApproval::UnlessTrusted, - permission_profile: permission_profile_from_sandbox_policy( - &SandboxPolicy::new_read_only_policy(), - ), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: &read_only_file_system_sandbox_policy(), sandbox_cwd: Path::new("/tmp"), sandbox_permissions: SandboxPermissions::UseDefault, @@ -1228,9 +1217,7 @@ async fn empty_bash_lc_script_falls_back_to_original_command() { .create_exec_approval_requirement_for_command(ExecApprovalRequest { command: &command, approval_policy: AskForApproval::UnlessTrusted, - permission_profile: permission_profile_from_sandbox_policy( - &SandboxPolicy::new_read_only_policy(), - ), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: &read_only_file_system_sandbox_policy(), sandbox_cwd: Path::new("/tmp"), sandbox_permissions: SandboxPermissions::UseDefault, @@ -1260,9 +1247,7 @@ async fn whitespace_bash_lc_script_falls_back_to_original_command() { .create_exec_approval_requirement_for_command(ExecApprovalRequest { command: &command, approval_policy: AskForApproval::UnlessTrusted, - permission_profile: permission_profile_from_sandbox_policy( - &SandboxPolicy::new_read_only_policy(), - ), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: &read_only_file_system_sandbox_policy(), sandbox_cwd: Path::new("/tmp"), sandbox_permissions: SandboxPermissions::UseDefault, @@ -1292,9 +1277,7 @@ async fn request_rule_uses_prefix_rule() { .create_exec_approval_requirement_for_command(ExecApprovalRequest { command: &command, approval_policy: AskForApproval::OnRequest, - permission_profile: permission_profile_from_sandbox_policy( - &SandboxPolicy::new_read_only_policy(), - ), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: &read_only_file_system_sandbox_policy(), sandbox_cwd: Path::new("/tmp"), sandbox_permissions: SandboxPermissions::RequireEscalated, @@ -1443,7 +1426,7 @@ async fn proposed_execpolicy_amendment_is_present_for_single_command_without_pol policy_src: None, command: command.clone(), approval_policy: AskForApproval::UnlessTrusted, - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -1463,7 +1446,7 @@ async fn proposed_execpolicy_amendment_is_omitted_when_policy_prompts() { policy_src: Some(r#"prefix_rule(pattern=["rm"], decision="prompt")"#.to_string()), command: vec!["rm".to_string()], approval_policy: AskForApproval::OnRequest, - sandbox_policy: SandboxPolicy::DangerFullAccess, + permission_profile: PermissionProfile::Disabled, file_system_sandbox_policy: unrestricted_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -1487,7 +1470,7 @@ async fn proposed_execpolicy_amendment_is_present_for_multi_command_scripts() { "cargo build && echo ok".to_string(), ], approval_policy: AskForApproval::UnlessTrusted, - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -1517,7 +1500,7 @@ async fn proposed_execpolicy_amendment_uses_first_no_match_in_multi_command_scri policy_src: Some(policy_src.to_string()), command, approval_policy: AskForApproval::UnlessTrusted, - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -1541,7 +1524,7 @@ async fn proposed_execpolicy_amendment_is_present_when_heuristics_allow() { policy_src: None, command: command.clone(), approval_policy: AskForApproval::OnRequest, - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -1561,7 +1544,7 @@ async fn proposed_execpolicy_amendment_is_suppressed_when_policy_matches_allow() policy_src: Some(r#"prefix_rule(pattern=["echo"], decision="allow")"#.to_string()), command: vec!["echo".to_string(), "safe".to_string()], approval_policy: AskForApproval::OnRequest, - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -1592,7 +1575,7 @@ prefix_rule(pattern=["cat"], decision="allow") policy_src: Some(policy_src.to_string()), command: command.clone(), approval_policy, - sandbox_policy: SandboxPolicy::new_workspace_write_policy(), + permission_profile: PermissionProfile::workspace_write(), file_system_sandbox_policy: workspace_write_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -1624,7 +1607,7 @@ prefix_rule(pattern=["bash"], decision="allow") .to_string(), ], approval_policy: AskForApproval::OnRequest, - sandbox_policy: SandboxPolicy::new_read_only_policy(), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: read_only_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -1790,7 +1773,7 @@ async fn dangerous_rm_rf_requires_approval_in_danger_full_access() { policy_src: None, command: command.clone(), approval_policy: AskForApproval::OnRequest, - sandbox_policy: SandboxPolicy::DangerFullAccess, + permission_profile: PermissionProfile::Disabled, file_system_sandbox_policy: unrestricted_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, prefix_rule: None, @@ -1831,7 +1814,7 @@ async fn verify_approval_requirement_for_unsafe_powershell_command() { ]))); let (pwsh_approval_reason, expected_req) = if cfg!(windows) { ( - r#"On Windows, SandboxPolicy::ReadOnly should be assumed to mean + r#"On Windows, a read-only permission profile should be assumed to mean that no sandbox is present, so anything that is not "provably safe" should require approval."#, ExecApprovalRequirement::NeedsApproval { @@ -1854,9 +1837,7 @@ async fn verify_approval_requirement_for_unsafe_powershell_command() { .create_exec_approval_requirement_for_command(ExecApprovalRequest { command: &sneaky_command, approval_policy: AskForApproval::OnRequest, - permission_profile: permission_profile_from_sandbox_policy( - &SandboxPolicy::new_read_only_policy(), - ), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: &read_only_file_system_sandbox_policy(), sandbox_cwd: Path::new("/tmp"), sandbox_permissions: permissions, @@ -1881,9 +1862,7 @@ async fn verify_approval_requirement_for_unsafe_powershell_command() { .create_exec_approval_requirement_for_command(ExecApprovalRequest { command: &dangerous_command, approval_policy: AskForApproval::OnRequest, - permission_profile: permission_profile_from_sandbox_policy( - &SandboxPolicy::new_read_only_policy(), - ), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: &read_only_file_system_sandbox_policy(), sandbox_cwd: Path::new("/tmp"), sandbox_permissions: permissions, @@ -1904,9 +1883,7 @@ async fn verify_approval_requirement_for_unsafe_powershell_command() { .create_exec_approval_requirement_for_command(ExecApprovalRequest { command: &dangerous_command, approval_policy: AskForApproval::Never, - permission_profile: permission_profile_from_sandbox_policy( - &SandboxPolicy::new_read_only_policy(), - ), + permission_profile: PermissionProfile::read_only(), file_system_sandbox_policy: &read_only_file_system_sandbox_policy(), sandbox_cwd: Path::new("/tmp"), sandbox_permissions: permissions, @@ -1926,8 +1903,8 @@ async fn dangerous_command_allowed_when_sandbox_is_explicitly_disabled() { policy_src: None, command, approval_policy: AskForApproval::Never, - sandbox_policy: SandboxPolicy::ExternalSandbox { - network_access: Default::default(), + permission_profile: PermissionProfile::External { + network: NetworkSandboxPolicy::Restricted, }, file_system_sandbox_policy: external_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, @@ -1951,8 +1928,8 @@ async fn dangerous_command_forbidden_in_external_sandbox_when_policy_matches() { policy_src: Some("prefix_rule(pattern=['rm'], decision='prompt')".to_string()), command, approval_policy: AskForApproval::Never, - sandbox_policy: SandboxPolicy::ExternalSandbox { - network_access: Default::default(), + permission_profile: PermissionProfile::External { + network: NetworkSandboxPolicy::Restricted, }, file_system_sandbox_policy: external_file_system_sandbox_policy(), sandbox_permissions: SandboxPermissions::UseDefault, @@ -1970,7 +1947,7 @@ struct ExecApprovalRequirementScenario { policy_src: Option, command: Vec, approval_policy: AskForApproval, - sandbox_policy: SandboxPolicy, + permission_profile: PermissionProfile, file_system_sandbox_policy: FileSystemSandboxPolicy, sandbox_permissions: SandboxPermissions, prefix_rule: Option>, @@ -1984,7 +1961,7 @@ async fn assert_exec_approval_requirement_for_command( policy_src, command, approval_policy, - sandbox_policy, + permission_profile, file_system_sandbox_policy, sandbox_permissions, prefix_rule, @@ -2001,7 +1978,6 @@ async fn assert_exec_approval_requirement_for_command( None => Arc::new(Policy::empty()), }; - let permission_profile = permission_profile_from_sandbox_policy(&sandbox_policy); let requirement = ExecPolicyManager::new(policy) .create_exec_approval_requirement_for_command(ExecApprovalRequest { command: &command,