permissions: remove core legacy policy round trips

This commit is contained in:
Michael Bolin
2026-04-24 09:31:17 -07:00
parent bb5e9e1cef
commit 55c2f31127
13 changed files with 120 additions and 348 deletions
+11 -8
View File
@@ -2041,24 +2041,27 @@ fn web_search_mode_disabled_overrides_legacy_request() {
#[test]
fn web_search_mode_for_turn_uses_preference_for_read_only() {
let web_search_mode = Constrained::allow_any(WebSearchMode::Cached);
let mode =
resolve_web_search_mode_for_turn(&web_search_mode, &SandboxPolicy::new_read_only_policy());
let permission_profile = PermissionProfile::from_legacy_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
std::path::Path::new("/"),
);
let mode = resolve_web_search_mode_for_turn(&web_search_mode, &permission_profile);
assert_eq!(mode, WebSearchMode::Cached);
}
#[test]
fn web_search_mode_for_turn_prefers_live_for_danger_full_access() {
fn web_search_mode_for_turn_prefers_live_for_disabled_permissions() {
let web_search_mode = Constrained::allow_any(WebSearchMode::Cached);
let mode = resolve_web_search_mode_for_turn(&web_search_mode, &SandboxPolicy::DangerFullAccess);
let mode = resolve_web_search_mode_for_turn(&web_search_mode, &PermissionProfile::Disabled);
assert_eq!(mode, WebSearchMode::Live);
}
#[test]
fn web_search_mode_for_turn_respects_disabled_for_danger_full_access() {
fn web_search_mode_for_turn_respects_disabled_for_disabled_permissions() {
let web_search_mode = Constrained::allow_any(WebSearchMode::Disabled);
let mode = resolve_web_search_mode_for_turn(&web_search_mode, &SandboxPolicy::DangerFullAccess);
let mode = resolve_web_search_mode_for_turn(&web_search_mode, &PermissionProfile::Disabled);
assert_eq!(mode, WebSearchMode::Disabled);
}
@@ -2078,7 +2081,7 @@ fn web_search_mode_for_turn_falls_back_when_live_is_disallowed() -> anyhow::Resu
})
}
})?;
let mode = resolve_web_search_mode_for_turn(&web_search_mode, &SandboxPolicy::DangerFullAccess);
let mode = resolve_web_search_mode_for_turn(&web_search_mode, &PermissionProfile::Disabled);
assert_eq!(mode, WebSearchMode::Cached);
Ok(())
@@ -6641,7 +6644,7 @@ async fn requirements_web_search_mode_overrides_danger_full_access_default() ->
assert_eq!(
resolve_web_search_mode_for_turn(
&config.web_search_mode,
config.permissions.sandbox_policy.get(),
&config.permissions.permission_profile(),
),
WebSearchMode::Cached,
);
+2 -2
View File
@@ -1583,11 +1583,11 @@ fn multi_agent_v2_toml_config(features: Option<&FeaturesToml>) -> Option<&MultiA
pub(crate) fn resolve_web_search_mode_for_turn(
web_search_mode: &Constrained<WebSearchMode>,
sandbox_policy: &SandboxPolicy,
permission_profile: &PermissionProfile,
) -> WebSearchMode {
let preferred = web_search_mode.value();
if matches!(sandbox_policy, SandboxPolicy::DangerFullAccess)
if matches!(permission_profile, PermissionProfile::Disabled)
&& preferred != WebSearchMode::Disabled
{
for mode in [
+23 -9
View File
@@ -20,10 +20,10 @@ use codex_execpolicy::RuleMatch;
use codex_execpolicy::blocking_append_allow_prefix_rule;
use codex_execpolicy::blocking_append_network_rule;
use codex_protocol::approvals::ExecPolicyAmendment;
use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::FileSystemSandboxKind;
use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::SandboxPolicy;
use codex_shell_command::is_dangerous_command::command_might_be_dangerous;
use codex_shell_command::is_safe_command::is_known_safe_command;
use thiserror::Error;
@@ -204,7 +204,7 @@ pub(crate) struct ExecPolicyManager {
pub(crate) struct ExecApprovalRequest<'a> {
pub(crate) command: &'a [String],
pub(crate) approval_policy: AskForApproval,
pub(crate) sandbox_policy: &'a SandboxPolicy,
pub(crate) permission_profile: PermissionProfile,
pub(crate) file_system_sandbox_policy: &'a FileSystemSandboxPolicy,
pub(crate) sandbox_permissions: SandboxPermissions,
pub(crate) prefix_rule: Option<Vec<String>>,
@@ -238,7 +238,7 @@ impl ExecPolicyManager {
let ExecApprovalRequest {
command,
approval_policy,
sandbox_policy,
permission_profile,
file_system_sandbox_policy,
sandbox_permissions,
prefix_rule,
@@ -252,7 +252,7 @@ impl ExecPolicyManager {
let exec_policy_fallback = |cmd: &[String]| {
render_decision_for_unmatched_command(
approval_policy,
sandbox_policy,
&permission_profile,
file_system_sandbox_policy,
cmd,
sandbox_permissions,
@@ -580,7 +580,7 @@ pub async fn load_exec_policy(config_stack: &ConfigLayerStack) -> Result<Policy,
/// If a command is not matched by any execpolicy rule, derive a [`Decision`].
pub fn render_decision_for_unmatched_command(
approval_policy: AskForApproval,
sandbox_policy: &SandboxPolicy,
permission_profile: &PermissionProfile,
file_system_sandbox_policy: &FileSystemSandboxPolicy,
command: &[String],
sandbox_permissions: SandboxPermissions,
@@ -592,8 +592,8 @@ pub fn render_decision_for_unmatched_command(
// On Windows, ReadOnly sandbox is not a real sandbox, so special-case it
// here.
let environment_lacks_sandbox_protections =
cfg!(windows) && matches!(sandbox_policy, SandboxPolicy::ReadOnly { .. });
let environment_lacks_sandbox_protections = cfg!(windows)
&& profile_is_managed_read_only(permission_profile, file_system_sandbox_policy);
// If the command is flagged as dangerous or we have no sandbox protection,
// we should never allow it to run without approval.
@@ -605,8 +605,8 @@ pub fn render_decision_for_unmatched_command(
return match approval_policy {
AskForApproval::Never => {
let sandbox_is_explicitly_disabled = matches!(
sandbox_policy,
SandboxPolicy::DangerFullAccess | SandboxPolicy::ExternalSandbox { .. }
permission_profile,
PermissionProfile::Disabled | PermissionProfile::External { .. }
);
if sandbox_is_explicitly_disabled {
// If the sandbox is explicitly disabled, we should allow the command to run
@@ -670,6 +670,20 @@ pub fn render_decision_for_unmatched_command(
}
}
fn profile_is_managed_read_only(
permission_profile: &PermissionProfile,
file_system_sandbox_policy: &FileSystemSandboxPolicy,
) -> bool {
matches!(permission_profile, PermissionProfile::Managed { .. })
&& matches!(
file_system_sandbox_policy.kind,
FileSystemSandboxKind::Restricted
)
&& file_system_sandbox_policy
.get_writable_roots_with_cwd(Path::new("/"))
.is_empty()
}
fn default_policy_path(codex_home: &Path) -> PathBuf {
codex_home.join(RULES_DIR_NAME).join(DEFAULT_POLICY_FILE)
}
+38 -14
View File
@@ -15,6 +15,7 @@ use codex_config::RequirementsExecPolicy;
use codex_config::config_toml::ConfigToml;
use codex_config::config_toml::ProjectConfig;
use codex_protocol::config_types::TrustLevel;
use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::FileSystemAccessMode;
use codex_protocol::permissions::FileSystemPath;
use codex_protocol::permissions::FileSystemSandboxEntry;
@@ -116,6 +117,10 @@ 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, Path::new("/"))
}
async fn test_config() -> (TempDir, Config) {
let home = TempDir::new().expect("create temp dir");
let config = ConfigBuilder::without_managed_config_for_tests()
@@ -954,7 +959,7 @@ fn unmatched_granular_policy_still_prompts_for_restricted_sandbox_escalation() {
request_permissions: true,
mcp_elicitations: true,
}),
&SandboxPolicy::new_read_only_policy(),
&permission_profile_from_sandbox_policy(&SandboxPolicy::new_read_only_policy()),
&read_only_file_system_sandbox_policy(),
&command,
SandboxPermissions::RequireEscalated,
@@ -972,7 +977,7 @@ fn unmatched_on_request_uses_split_filesystem_policy_for_escalation_prompts() {
Decision::Prompt,
render_decision_for_unmatched_command(
AskForApproval::OnRequest,
&SandboxPolicy::DangerFullAccess,
&PermissionProfile::Disabled,
&restricted_file_system_policy,
&command,
SandboxPermissions::RequireEscalated,
@@ -1058,7 +1063,9 @@ async fn mixed_rule_and_sandbox_prompt_prioritizes_rule_for_rejection_decision()
request_permissions: true,
mcp_elicitations: true,
}),
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::RequireEscalated,
prefix_rule: None,
@@ -1095,7 +1102,9 @@ async fn mixed_rule_and_sandbox_prompt_rejects_when_granular_rules_are_disabled(
request_permissions: true,
mcp_elicitations: true,
}),
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::RequireEscalated,
prefix_rule: None,
@@ -1119,7 +1128,9 @@ async fn exec_approval_requirement_falls_back_to_heuristics() {
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
command: &command,
approval_policy: AskForApproval::UnlessTrusted,
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::UseDefault,
prefix_rule: None,
@@ -1144,7 +1155,9 @@ async fn empty_bash_lc_script_falls_back_to_original_command() {
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
command: &command,
approval_policy: AskForApproval::UnlessTrusted,
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::UseDefault,
prefix_rule: None,
@@ -1173,7 +1186,9 @@ async fn whitespace_bash_lc_script_falls_back_to_original_command() {
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
command: &command,
approval_policy: AskForApproval::UnlessTrusted,
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::UseDefault,
prefix_rule: None,
@@ -1202,7 +1217,9 @@ async fn request_rule_uses_prefix_rule() {
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
command: &command,
approval_policy: AskForApproval::OnRequest,
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::RequireEscalated,
prefix_rule: Some(vec!["cargo".to_string(), "install".to_string()]),
@@ -1234,7 +1251,7 @@ async fn request_rule_falls_back_when_prefix_rule_does_not_approve_all_commands(
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
command: &command,
approval_policy: AskForApproval::OnRequest,
sandbox_policy: &SandboxPolicy::DangerFullAccess,
permission_profile: PermissionProfile::Disabled,
file_system_sandbox_policy: &unrestricted_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::RequireEscalated,
prefix_rule: Some(vec!["cargo".to_string(), "install".to_string()]),
@@ -1273,7 +1290,7 @@ async fn heuristics_apply_when_other_commands_match_policy() {
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
command: &command,
approval_policy: AskForApproval::UnlessTrusted,
sandbox_policy: &SandboxPolicy::DangerFullAccess,
permission_profile: PermissionProfile::Disabled,
file_system_sandbox_policy: &unrestricted_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::UseDefault,
prefix_rule: None,
@@ -1759,7 +1776,9 @@ async fn verify_approval_requirement_for_unsafe_powershell_command() {
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
command: &sneaky_command,
approval_policy: AskForApproval::OnRequest,
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_permissions: permissions,
prefix_rule: None,
@@ -1783,7 +1802,9 @@ async fn verify_approval_requirement_for_unsafe_powershell_command() {
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
command: &dangerous_command,
approval_policy: AskForApproval::OnRequest,
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_permissions: permissions,
prefix_rule: None,
@@ -1803,7 +1824,9 @@ async fn verify_approval_requirement_for_unsafe_powershell_command() {
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
command: &dangerous_command,
approval_policy: AskForApproval::Never,
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_permissions: permissions,
prefix_rule: None,
@@ -1897,11 +1920,12 @@ 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,
approval_policy,
sandbox_policy: &sandbox_policy,
permission_profile,
file_system_sandbox_policy: &file_system_sandbox_policy,
sandbox_permissions,
prefix_rule,
+1 -2
View File
@@ -7018,14 +7018,13 @@ async fn rejects_escalated_permissions_when_policy_not_on_request() {
turn_context_mut.permission_profile = PermissionProfile::Disabled;
let file_system_sandbox_policy = turn_context.file_system_sandbox_policy();
let sandbox_policy = turn_context.sandbox_policy();
let exec_approval_requirement = session
.services
.exec_policy
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
command: &params.command,
approval_policy: turn_context.approval_policy.value(),
sandbox_policy: &sandbox_policy,
permission_profile: turn_context.permission_profile(),
file_system_sandbox_policy: &file_system_sandbox_policy,
sandbox_permissions: SandboxPermissions::UseDefault,
prefix_rule: None,
+3 -3
View File
@@ -381,10 +381,10 @@ impl Session {
per_turn_config.permissions.permission_profile =
session_configuration.permission_profile.clone();
let sandbox_policy = session_configuration.sandbox_policy();
per_turn_config.permissions.sandbox_policy =
Constrained::allow_only(sandbox_policy.clone());
per_turn_config.permissions.sandbox_policy = Constrained::allow_only(sandbox_policy);
let permission_profile = session_configuration.permission_profile();
let resolved_web_search_mode =
resolve_web_search_mode_for_turn(&per_turn_config.web_search_mode, &sandbox_policy);
resolve_web_search_mode_for_turn(&per_turn_config.web_search_mode, &permission_profile);
if let Err(err) = per_turn_config
.web_search_mode
.set(resolved_web_search_mode)
+1 -2
View File
@@ -514,14 +514,13 @@ impl ShellHandler {
emitter.begin(event_ctx).await;
let file_system_sandbox_policy = turn.file_system_sandbox_policy();
let sandbox_policy = turn.sandbox_policy();
let exec_approval_requirement = session
.services
.exec_policy
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
command: &exec_params.command,
approval_policy: turn.approval_policy.value(),
sandbox_policy: &sandbox_policy,
permission_profile: turn.permission_profile(),
file_system_sandbox_policy: &file_system_sandbox_policy,
sandbox_permissions: if effective_additional_permissions.permissions_preapproved {
codex_protocol::models::SandboxPermissions::UseDefault
@@ -32,7 +32,6 @@ use codex_protocol::exec_output::ExecToolCallOutput;
use codex_protocol::exec_output::StreamOutput;
use codex_protocol::models::AdditionalPermissionProfile;
use codex_protocol::models::PermissionProfile;
use codex_protocol::models::SandboxEnforcement;
use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_protocol::protocol::AskForApproval;
@@ -203,9 +202,8 @@ pub(super) async fn try_run_zsh_fork(
call_id: ctx.call_id.clone(),
tool_name: GuardianCommandSource::Shell,
approval_policy: ctx.turn.approval_policy.value(),
sandbox_policy: command_executor.sandbox_policy.clone(),
permission_profile: command_executor.permission_profile.clone(),
file_system_sandbox_policy: command_executor.file_system_sandbox_policy.clone(),
network_sandbox_policy: command_executor.network_sandbox_policy,
sandbox_permissions: req.sandbox_permissions,
approval_sandbox_permissions,
prompt_permissions: req.additional_permissions.clone(),
@@ -276,9 +274,8 @@ pub(crate) async fn prepare_unified_exec_zsh_fork(
call_id: ctx.call_id.clone(),
tool_name: GuardianCommandSource::UnifiedExec,
approval_policy: ctx.turn.approval_policy.value(),
sandbox_policy: exec_request.sandbox_policy.clone(),
permission_profile: exec_request.permission_profile.clone(),
file_system_sandbox_policy: exec_request.file_system_sandbox_policy.clone(),
network_sandbox_policy: exec_request.network_sandbox_policy,
sandbox_permissions: req.sandbox_permissions,
approval_sandbox_permissions: approval_sandbox_permissions(
req.sandbox_permissions,
@@ -311,9 +308,8 @@ struct CoreShellActionProvider {
call_id: String,
tool_name: GuardianCommandSource,
approval_policy: AskForApproval,
sandbox_policy: SandboxPolicy,
permission_profile: PermissionProfile,
file_system_sandbox_policy: FileSystemSandboxPolicy,
network_sandbox_policy: NetworkSandboxPolicy,
sandbox_permissions: SandboxPermissions,
approval_sandbox_permissions: SandboxPermissions,
prompt_permissions: Option<AdditionalPermissionProfile>,
@@ -363,9 +359,7 @@ impl CoreShellActionProvider {
fn shell_request_escalation_execution(
sandbox_permissions: SandboxPermissions,
sandbox_policy: &SandboxPolicy,
file_system_sandbox_policy: &FileSystemSandboxPolicy,
network_sandbox_policy: NetworkSandboxPolicy,
permission_profile: &PermissionProfile,
additional_permissions: Option<&AdditionalPermissionProfile>,
) -> EscalationExecution {
match sandbox_permissions {
@@ -378,15 +372,7 @@ impl CoreShellActionProvider {
EscalationExecution::Permissions(
EscalationPermissions::ResolvedPermissionProfile(
ResolvedPermissionProfile {
permission_profile:
PermissionProfile::from_runtime_permissions_with_enforcement(
SandboxEnforcement::from_legacy_sandbox_policy(
sandbox_policy,
),
file_system_sandbox_policy,
network_sandbox_policy,
),
sandbox_policy: sandbox_policy.clone(),
permission_profile: permission_profile.clone(),
},
),
)
@@ -605,7 +591,7 @@ impl EscalationPolicy for CoreShellActionProvider {
argv,
InterceptedExecPolicyContext {
approval_policy: self.approval_policy,
sandbox_policy: &self.sandbox_policy,
permission_profile: self.permission_profile.clone(),
file_system_sandbox_policy: &self.file_system_sandbox_policy,
sandbox_permissions: self.approval_sandbox_permissions,
enable_shell_wrapper_parsing:
@@ -629,9 +615,7 @@ impl EscalationPolicy for CoreShellActionProvider {
DecisionSource::PrefixRule => EscalationExecution::Unsandboxed,
DecisionSource::UnmatchedCommandFallback => Self::shell_request_escalation_execution(
self.sandbox_permissions,
&self.sandbox_policy,
&self.file_system_sandbox_policy,
self.network_sandbox_policy,
&self.permission_profile,
self.prompt_permissions.as_ref(),
),
};
@@ -657,7 +641,7 @@ fn evaluate_intercepted_exec_policy(
) -> Evaluation {
let InterceptedExecPolicyContext {
approval_policy,
sandbox_policy,
permission_profile,
file_system_sandbox_policy,
sandbox_permissions,
enable_shell_wrapper_parsing,
@@ -682,7 +666,7 @@ fn evaluate_intercepted_exec_policy(
let fallback = |cmd: &[String]| {
crate::exec_policy::render_decision_for_unmatched_command(
approval_policy,
sandbox_policy,
&permission_profile,
file_system_sandbox_policy,
cmd,
sandbox_permissions,
@@ -699,10 +683,10 @@ fn evaluate_intercepted_exec_policy(
)
}
#[derive(Clone, Copy)]
#[derive(Clone)]
struct InterceptedExecPolicyContext<'a> {
approval_policy: AskForApproval,
sandbox_policy: &'a SandboxPolicy,
permission_profile: PermissionProfile,
file_system_sandbox_policy: &'a FileSystemSandboxPolicy,
sandbox_permissions: SandboxPermissions,
enable_shell_wrapper_parsing: bool,
@@ -28,7 +28,6 @@ use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::GranularApprovalConfig;
use codex_protocol::protocol::GuardianCommandSource;
use codex_protocol::protocol::ReadOnlyAccess;
use codex_protocol::protocol::SandboxPolicy;
use codex_sandboxing::SandboxType;
use codex_shell_escalation::EscalationExecution;
@@ -67,6 +66,10 @@ fn read_only_file_system_sandbox_policy() -> FileSystemSandboxPolicy {
}])
}
fn permission_profile_from_sandbox_policy(sandbox_policy: &SandboxPolicy) -> PermissionProfile {
PermissionProfile::from_legacy_sandbox_policy(sandbox_policy, std::path::Path::new("/"))
}
#[test]
fn execve_prompt_rejection_keeps_prefix_rules_on_rules_flag() {
assert_eq!(
@@ -267,13 +270,6 @@ fn shell_request_escalation_execution_is_explicit() {
)),
..Default::default()
};
let sandbox_policy = SandboxPolicy::WorkspaceWrite {
writable_roots: vec![AbsolutePathBuf::from_absolute_path("/tmp/original/output").unwrap()],
read_only_access: ReadOnlyAccess::FullAccess,
network_access: false,
exclude_tmpdir_env_var: false,
exclude_slash_tmp: false,
};
let file_system_sandbox_policy = FileSystemSandboxPolicy::restricted(vec![
FileSystemSandboxEntry {
path: FileSystemPath::Path {
@@ -289,13 +285,15 @@ fn shell_request_escalation_execution_is_explicit() {
},
]);
let network_sandbox_policy = NetworkSandboxPolicy::Restricted;
let permission_profile = PermissionProfile::from_runtime_permissions(
&file_system_sandbox_policy,
network_sandbox_policy,
);
assert_eq!(
CoreShellActionProvider::shell_request_escalation_execution(
crate::sandboxing::SandboxPermissions::UseDefault,
&sandbox_policy,
&file_system_sandbox_policy,
network_sandbox_policy,
&permission_profile,
/*additional_permissions*/ None,
),
EscalationExecution::TurnDefault,
@@ -303,9 +301,7 @@ fn shell_request_escalation_execution_is_explicit() {
assert_eq!(
CoreShellActionProvider::shell_request_escalation_execution(
crate::sandboxing::SandboxPermissions::RequireEscalated,
&sandbox_policy,
&file_system_sandbox_policy,
network_sandbox_policy,
&permission_profile,
/*additional_permissions*/ None,
),
EscalationExecution::Unsandboxed,
@@ -313,19 +309,11 @@ fn shell_request_escalation_execution_is_explicit() {
assert_eq!(
CoreShellActionProvider::shell_request_escalation_execution(
crate::sandboxing::SandboxPermissions::WithAdditionalPermissions,
&sandbox_policy,
&file_system_sandbox_policy,
network_sandbox_policy,
&permission_profile,
Some(&requested_permissions),
),
EscalationExecution::Permissions(EscalationPermissions::ResolvedPermissionProfile(
ResolvedPermissionProfile {
permission_profile: PermissionProfile::from_runtime_permissions(
&file_system_sandbox_policy,
network_sandbox_policy,
),
sandbox_policy,
},
ResolvedPermissionProfile { permission_profile },
)),
);
}
@@ -397,8 +385,6 @@ async fn execve_permission_request_hook_short_circuits_prompt() -> anyhow::Resul
&read_only_file_system_sandbox_policy(),
NetworkSandboxPolicy::Restricted,
);
let sandbox_policy = SandboxPolicy::new_read_only_policy();
let workdir = AbsolutePathBuf::try_from(std::env::current_dir()?)?;
let target = std::env::temp_dir().join("execve-hook-short-circuit.txt");
let target_str = target.display().to_string();
@@ -412,9 +398,10 @@ async fn execve_permission_request_hook_short_circuits_prompt() -> anyhow::Resul
call_id: "execve-hook-call".to_string(),
tool_name: GuardianCommandSource::Shell,
approval_policy: AskForApproval::OnRequest,
sandbox_policy,
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: read_only_file_system_sandbox_policy(),
network_sandbox_policy: NetworkSandboxPolicy::Restricted,
sandbox_permissions: SandboxPermissions::RequireEscalated,
approval_sandbox_permissions: SandboxPermissions::RequireEscalated,
prompt_permissions: None,
@@ -478,7 +465,9 @@ fn evaluate_intercepted_exec_policy_uses_wrapper_command_when_shell_wrapper_pars
],
InterceptedExecPolicyContext {
approval_policy: AskForApproval::OnRequest,
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::UseDefault,
enable_shell_wrapper_parsing: enable_intercepted_exec_policy_shell_wrapper_parsing,
@@ -529,7 +518,9 @@ fn evaluate_intercepted_exec_policy_matches_inner_shell_commands_when_enabled()
],
InterceptedExecPolicyContext {
approval_policy: AskForApproval::OnRequest,
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::UseDefault,
enable_shell_wrapper_parsing: enable_intercepted_exec_policy_shell_wrapper_parsing,
@@ -571,7 +562,9 @@ host_executable(name = "git", paths = ["{git_path_literal}"])
&["git".to_string(), "status".to_string()],
InterceptedExecPolicyContext {
approval_policy: AskForApproval::OnRequest,
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::UseDefault,
enable_shell_wrapper_parsing: false,
@@ -611,7 +604,7 @@ fn intercepted_exec_policy_treats_preapproved_additional_permissions_as_default(
&argv,
InterceptedExecPolicyContext {
approval_policy,
sandbox_policy: &sandbox_policy,
permission_profile: permission_profile_from_sandbox_policy(&sandbox_policy),
file_system_sandbox_policy: &file_system_sandbox_policy,
sandbox_permissions: super::approval_sandbox_permissions(
SandboxPermissions::WithAdditionalPermissions,
@@ -626,7 +619,7 @@ fn intercepted_exec_policy_treats_preapproved_additional_permissions_as_default(
&argv,
InterceptedExecPolicyContext {
approval_policy,
sandbox_policy: &sandbox_policy,
permission_profile: permission_profile_from_sandbox_policy(&sandbox_policy),
file_system_sandbox_policy: &file_system_sandbox_policy,
sandbox_permissions: SandboxPermissions::WithAdditionalPermissions,
enable_shell_wrapper_parsing: false,
@@ -659,7 +652,9 @@ host_executable(name = "git", paths = ["{allowed_git_literal}"])
&["git".to_string(), "status".to_string()],
InterceptedExecPolicyContext {
approval_policy: AskForApproval::OnRequest,
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
permission_profile: permission_profile_from_sandbox_policy(
&SandboxPolicy::new_read_only_policy(),
),
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::UseDefault,
enable_shell_wrapper_parsing: false,
@@ -789,7 +789,6 @@ impl UnifiedExecProcessManager {
context.turn.tools_config.unified_exec_shell_mode.clone(),
);
let file_system_sandbox_policy = context.turn.file_system_sandbox_policy();
let sandbox_policy = context.turn.sandbox_policy();
let exec_approval_requirement = context
.session
.services
@@ -797,7 +796,7 @@ impl UnifiedExecProcessManager {
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
command: &request.command,
approval_policy: context.turn.approval_policy.value(),
sandbox_policy: &sandbox_policy,
permission_profile: context.turn.permission_profile(),
file_system_sandbox_policy: &file_system_sandbox_policy,
sandbox_permissions: if request.additional_permissions_preapproved {
crate::sandboxing::SandboxPermissions::UseDefault