Use permission profiles throughout sandbox execution (#36183)

## What changed

- Pass the canonical `PermissionProfile` through execution requests, sandbox
  selection, escalation, and the exec server instead of carrying separate
  derived filesystem and network policies.
- Derive runtime sandbox policies from the effective profile at their points of
  use, including after applying additional permissions.
- Update sandbox and escalation tests to inspect policies through the profile.

GitOrigin-RevId: 695b82ea94f5289516b0933bb23074cb2dcce8ac
This commit is contained in:
viyatb-oai authored and copyberry committed 2026-07-30 16:30:32 +00:00
1 parent ceb4bc72c4
commit 0dcad0c972
15 files changed
+74 -166

No files matched your search

+5 -9
View File
@@ -449,16 +449,12 @@ impl Permissions {
self.permission_profile_state.profile_workspace_roots() self.permission_profile_state.profile_workspace_roots()
} }
fn materialized_permission_profile(&self) -> PermissionProfile {
self.permission_profile()
.clone()
.materialize_project_roots_with_workspace_roots(&self.workspace_roots)
}
/// Effective runtime permissions after config requirements and runtime /// Effective runtime permissions after config requirements and runtime
/// workspace-root materialization have been applied. /// workspace-root materialization have been applied.
pub fn effective_permission_profile(&self) -> PermissionProfile { pub fn effective_permission_profile(&self) -> PermissionProfile {
self.materialized_permission_profile() self.permission_profile()
.clone()
.materialize_project_roots_with_workspace_roots(&self.workspace_roots)
} }
/// Named profile selected by config, if the current profile has one. /// Named profile selected by config, if the current profile has one.
@@ -468,7 +464,7 @@ impl Permissions {
/// Effective filesystem sandbox policy derived from the canonical profile. /// Effective filesystem sandbox policy derived from the canonical profile.
pub fn file_system_sandbox_policy(&self) -> FileSystemSandboxPolicy { pub fn file_system_sandbox_policy(&self) -> FileSystemSandboxPolicy {
self.materialized_permission_profile() self.effective_permission_profile()
.file_system_sandbox_policy() .file_system_sandbox_policy()
} }
@@ -479,7 +475,7 @@ impl Permissions {
/// Legacy compatibility projection derived from the canonical profile. /// Legacy compatibility projection derived from the canonical profile.
pub fn legacy_sandbox_policy(&self, cwd: &Path) -> SandboxPolicy { pub fn legacy_sandbox_policy(&self, cwd: &Path) -> SandboxPolicy {
let permission_profile = self.materialized_permission_profile(); let permission_profile = self.effective_permission_profile();
compatibility_sandbox_policy_for_permission_profile(&permission_profile, cwd) compatibility_sandbox_policy_for_permission_profile(&permission_profile, cwd)
} }
+4 -11
View File
@@ -30,7 +30,6 @@ use codex_protocol::error::SandboxErr;
use codex_protocol::exec_output::ExecToolCallOutput; use codex_protocol::exec_output::ExecToolCallOutput;
use codex_protocol::exec_output::StreamOutput; use codex_protocol::exec_output::StreamOutput;
use codex_protocol::models::PermissionProfile; use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_protocol::permissions::NetworkSandboxPolicy; use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_protocol::protocol::Event; use codex_protocol::protocol::Event;
use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::EventMsg;
@@ -115,14 +114,12 @@ pub enum ExecCapturePolicy {
} }
fn select_process_exec_tool_sandbox_type( fn select_process_exec_tool_sandbox_type(
file_system_sandbox_policy: &FileSystemSandboxPolicy, permission_profile: &PermissionProfile,
network_sandbox_policy: NetworkSandboxPolicy,
windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel, windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel,
enforce_managed_network: bool, enforce_managed_network: bool,
) -> SandboxType { ) -> SandboxType {
SandboxManager::new().select_initial( SandboxManager::new().select_initial(
file_system_sandbox_policy, permission_profile,
network_sandbox_policy,
SandboxablePreference::Auto, SandboxablePreference::Auto,
windows_sandbox_level, windows_sandbox_level,
enforce_managed_network, enforce_managed_network,
@@ -345,11 +342,8 @@ pub fn build_exec_request(
} = params; } = params;
let enforce_managed_network = network.is_some(); let enforce_managed_network = network.is_some();
let (file_system_sandbox_policy, network_sandbox_policy) =
permission_profile.to_runtime_permissions();
let sandbox_type = select_process_exec_tool_sandbox_type( let sandbox_type = select_process_exec_tool_sandbox_type(
&file_system_sandbox_policy, permission_profile,
network_sandbox_policy,
windows_sandbox_level, windows_sandbox_level,
enforce_managed_network, enforce_managed_network,
); );
@@ -453,8 +447,6 @@ pub(crate) async fn execute_exec_request(
windows_sandbox_level, windows_sandbox_level,
windows_sandbox_private_desktop, windows_sandbox_private_desktop,
permission_profile, permission_profile,
file_system_sandbox_policy: _,
network_sandbox_policy,
windows_sandbox_filesystem_overrides, windows_sandbox_filesystem_overrides,
network_environment_id, network_environment_id,
arg0, arg0,
@@ -463,6 +455,7 @@ pub(crate) async fn execute_exec_request(
exec_server_managed_network: _, exec_server_managed_network: _,
exec_server_network_proxy: _, exec_server_network_proxy: _,
} = exec_request; } = exec_request;
let network_sandbox_policy = permission_profile.network_sandbox_policy();
// TODO(anp): Keep PathUri through the local process launch boundary. // TODO(anp): Keep PathUri through the local process launch boundary.
let cwd = cwd let cwd = cwd
+5 -2
View File
@@ -1,6 +1,7 @@
use super::*; use super::*;
use codex_protocol::config_types::WindowsSandboxLevel; use codex_protocol::config_types::WindowsSandboxLevel;
use codex_protocol::models::PermissionProfile; use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_sandboxing::SandboxType; use codex_sandboxing::SandboxType;
use core_test_support::PathBufExt; use core_test_support::PathBufExt;
use core_test_support::PathExt; use core_test_support::PathExt;
@@ -1049,8 +1050,10 @@ fn process_exec_tool_call_uses_platform_sandbox_for_network_only_restrictions()
assert_eq!( assert_eq!(
select_process_exec_tool_sandbox_type( select_process_exec_tool_sandbox_type(
&FileSystemSandboxPolicy::unrestricted(), &PermissionProfile::from_runtime_permissions(
NetworkSandboxPolicy::Restricted, &FileSystemSandboxPolicy::unrestricted(),
NetworkSandboxPolicy::Restricted,
),
codex_protocol::config_types::WindowsSandboxLevel::Disabled, codex_protocol::config_types::WindowsSandboxLevel::Disabled,
/*enforce_managed_network*/ false, /*enforce_managed_network*/ false,
), ),
+2 -12
View File
@@ -22,8 +22,6 @@ use codex_protocol::config_types::WindowsSandboxLevel;
use codex_protocol::exec_output::ExecToolCallOutput; use codex_protocol::exec_output::ExecToolCallOutput;
use codex_protocol::models::PermissionProfile; use codex_protocol::models::PermissionProfile;
pub use codex_protocol::models::SandboxPermissions; pub use codex_protocol::models::SandboxPermissions;
use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_sandboxing::SandboxExecRequest; use codex_sandboxing::SandboxExecRequest;
use codex_sandboxing::SandboxType; use codex_sandboxing::SandboxType;
use codex_sandboxing::WindowsSandboxFilesystemOverrides; use codex_sandboxing::WindowsSandboxFilesystemOverrides;
@@ -59,8 +57,6 @@ pub struct ExecRequest {
pub windows_sandbox_level: WindowsSandboxLevel, pub windows_sandbox_level: WindowsSandboxLevel,
pub windows_sandbox_private_desktop: bool, pub windows_sandbox_private_desktop: bool,
pub permission_profile: PermissionProfile, pub permission_profile: PermissionProfile,
pub file_system_sandbox_policy: FileSystemSandboxPolicy,
pub network_sandbox_policy: NetworkSandboxPolicy,
pub(crate) windows_sandbox_filesystem_overrides: Option<WindowsSandboxFilesystemOverrides>, pub(crate) windows_sandbox_filesystem_overrides: Option<WindowsSandboxFilesystemOverrides>,
pub arg0: Option<String>, pub arg0: Option<String>,
pub(crate) exec_server_sandbox: Option<FileSystemSandboxContext>, pub(crate) exec_server_sandbox: Option<FileSystemSandboxContext>,
@@ -88,8 +84,6 @@ impl ExecRequest {
) -> Self { ) -> Self {
let cwd = PathUri::from_abs_path(&cwd); let cwd = PathUri::from_abs_path(&cwd);
let windows_sandbox_policy_cwd = cwd.clone(); let windows_sandbox_policy_cwd = cwd.clone();
let (file_system_sandbox_policy, network_sandbox_policy) =
permission_profile.to_runtime_permissions();
Self { Self {
command, command,
cwd, cwd,
@@ -105,8 +99,6 @@ impl ExecRequest {
windows_sandbox_level, windows_sandbox_level,
windows_sandbox_private_desktop, windows_sandbox_private_desktop,
permission_profile, permission_profile,
file_system_sandbox_policy,
network_sandbox_policy,
windows_sandbox_filesystem_overrides: None, windows_sandbox_filesystem_overrides: None,
arg0, arg0,
exec_server_sandbox: None, exec_server_sandbox: None,
@@ -132,14 +124,14 @@ impl ExecRequest {
windows_sandbox_level, windows_sandbox_level,
windows_sandbox_private_desktop, windows_sandbox_private_desktop,
permission_profile, permission_profile,
file_system_sandbox_policy,
network_sandbox_policy,
arg0, arg0,
..
} = request; } = request;
let ExecOptions { let ExecOptions {
expiration, expiration,
capture_policy, capture_policy,
} = options; } = options;
let network_sandbox_policy = permission_profile.network_sandbox_policy();
if !network_sandbox_policy.is_enabled() { if !network_sandbox_policy.is_enabled() {
env.insert( env.insert(
CODEX_SANDBOX_NETWORK_DISABLED_ENV_VAR.to_string(), CODEX_SANDBOX_NETWORK_DISABLED_ENV_VAR.to_string(),
@@ -165,8 +157,6 @@ impl ExecRequest {
windows_sandbox_level, windows_sandbox_level,
windows_sandbox_private_desktop, windows_sandbox_private_desktop,
permission_profile, permission_profile,
file_system_sandbox_policy,
network_sandbox_policy,
windows_sandbox_filesystem_overrides: None, windows_sandbox_filesystem_overrides: None,
arg0, arg0,
exec_server_sandbox: None, exec_server_sandbox: None,
+3 -16
View File
@@ -16,8 +16,7 @@ use codex_protocol::protocol::MultiAgentVersion;
use codex_protocol::protocol::ThreadHistoryMode; use codex_protocol::protocol::ThreadHistoryMode;
use codex_protocol::protocol::TurnEnvironmentSelection; use codex_protocol::protocol::TurnEnvironmentSelection;
use codex_sandboxing::compatibility_sandbox_policy_for_permission_profile; use codex_sandboxing::compatibility_sandbox_policy_for_permission_profile;
use codex_sandboxing::policy_transforms::effective_file_system_sandbox_policy; use codex_sandboxing::policy_transforms::effective_permission_profile;
use codex_sandboxing::policy_transforms::effective_network_sandbox_policy;
use codex_utils_path_uri::PathUri; use codex_utils_path_uri::PathUri;
use futures::FutureExt; use futures::FutureExt;
use futures::future::BoxFuture; use futures::future::BoxFuture;
@@ -335,22 +334,10 @@ impl TurnContext {
additional_permissions: Option<AdditionalPermissionProfile>, additional_permissions: Option<AdditionalPermissionProfile>,
environment: &TurnEnvironment, environment: &TurnEnvironment,
) -> FileSystemSandboxContext { ) -> FileSystemSandboxContext {
let permission_profile = self.config.permissions.permission_profile(); let permissions = effective_permission_profile(
let (base_file_system_sandbox_policy, base_network_sandbox_policy) = self.config.permissions.permission_profile(),
permission_profile.to_runtime_permissions();
let file_system_sandbox_policy = effective_file_system_sandbox_policy(
&base_file_system_sandbox_policy,
additional_permissions.as_ref(), additional_permissions.as_ref(),
); );
let network_sandbox_policy = effective_network_sandbox_policy(
base_network_sandbox_policy,
additional_permissions.as_ref(),
);
let permissions = PermissionProfile::from_runtime_permissions_with_enforcement(
permission_profile.enforcement(),
&file_system_sandbox_policy,
network_sandbox_policy,
);
FileSystemSandboxContext { FileSystemSandboxContext {
permissions: permissions.into(), permissions: permissions.into(),
cwd: Some(environment.cwd().clone()), cwd: Some(environment.cwd().clone()),
+1 -3
View File
@@ -225,9 +225,7 @@ pub(crate) async fn execute_user_shell_command(
.config .config
.permissions .permissions
.windows_sandbox_private_desktop, .windows_sandbox_private_desktop,
permission_profile: permission_profile.clone(), permission_profile,
file_system_sandbox_policy: permission_profile.file_system_sandbox_policy(),
network_sandbox_policy: permission_profile.network_sandbox_policy(),
windows_sandbox_filesystem_overrides: None, windows_sandbox_filesystem_overrides: None,
arg0: None, arg0: None,
exec_server_sandbox: None, exec_server_sandbox: None,
@@ -155,8 +155,7 @@ impl ExecCommandHandler {
// permissions config below. Consult the configured platform-sandbox requirement before // permissions config below. Consult the configured platform-sandbox requirement before
// deciding whether parsing may continue without that base path. // deciding whether parsing may continue without that base path.
let sandbox = SandboxManager::new().select_initial( let sandbox = SandboxManager::new().select_initial(
&turn.file_system_sandbox_policy(), &turn.permission_profile,
turn.network_sandbox_policy(),
SandboxablePreference::Auto, SandboxablePreference::Auto,
turn.windows_sandbox_level, turn.windows_sandbox_level,
turn.network.is_some(), turn.network.is_some(),
+5 -10
View File
@@ -160,8 +160,7 @@ impl ToolOrchestrator {
let permissions = permission_profile let permissions = permission_profile
.clone() .clone()
.materialize_project_roots_with_workspace_roots(&materialized_workspace_roots); .materialize_project_roots_with_workspace_roots(&materialized_workspace_roots);
let (file_system_sandbox_policy, network_sandbox_policy) = let file_system_sandbox_policy = permissions.file_system_sandbox_policy();
permissions.to_runtime_permissions();
let requirement = tool.exec_approval_requirement(req).unwrap_or_else(|| { let requirement = tool.exec_approval_requirement(req).unwrap_or_else(|| {
default_exec_approval_requirement(approval_policy, &file_system_sandbox_policy) default_exec_approval_requirement(approval_policy, &file_system_sandbox_policy)
}); });
@@ -235,16 +234,14 @@ impl ToolOrchestrator {
let sandbox_requested = match sandbox_override { let sandbox_requested = match sandbox_override {
SandboxOverride::BypassSandboxFirstAttempt => false, SandboxOverride::BypassSandboxFirstAttempt => false,
SandboxOverride::NoOverride => self.sandbox.should_sandbox( SandboxOverride::NoOverride => self.sandbox.should_sandbox(
&file_system_sandbox_policy, &permissions,
network_sandbox_policy,
sandbox_preference, sandbox_preference,
managed_network_active, managed_network_active,
), ),
}; };
let initial_sandbox = if sandbox_requested { let initial_sandbox = if sandbox_requested {
self.sandbox.select_initial( self.sandbox.select_initial(
&file_system_sandbox_policy, &permissions,
network_sandbox_policy,
sandbox_preference, sandbox_preference,
turn_ctx.windows_sandbox_level, turn_ctx.windows_sandbox_level,
managed_network_active, managed_network_active,
@@ -423,15 +420,13 @@ impl ToolOrchestrator {
let retry_sandbox_requested = !unsandboxed_allowed let retry_sandbox_requested = !unsandboxed_allowed
&& self.sandbox.should_sandbox( && self.sandbox.should_sandbox(
&file_system_sandbox_policy, &permissions,
network_sandbox_policy,
sandbox_preference, sandbox_preference,
managed_network_active, managed_network_active,
); );
let retry_sandbox = if retry_sandbox_requested { let retry_sandbox = if retry_sandbox_requested {
self.sandbox.select_initial( self.sandbox.select_initial(
&file_system_sandbox_policy, &permissions,
network_sandbox_policy,
sandbox_preference, sandbox_preference,
turn_ctx.windows_sandbox_level, turn_ctx.windows_sandbox_level,
managed_network_active, managed_network_active,
@@ -36,8 +36,6 @@ use codex_protocol::exec_output::ExecToolCallOutput;
use codex_protocol::exec_output::StreamOutput; use codex_protocol::exec_output::StreamOutput;
use codex_protocol::models::AdditionalPermissionProfile; use codex_protocol::models::AdditionalPermissionProfile;
use codex_protocol::models::PermissionProfile; use codex_protocol::models::PermissionProfile;
use codex_protocol::permissions::FileSystemSandboxPolicy;
use codex_protocol::permissions::NetworkSandboxPolicy;
use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::AskForApproval;
use codex_protocol::protocol::GuardianCommandSource; use codex_protocol::protocol::GuardianCommandSource;
use codex_protocol::protocol::NetworkPolicyRuleAction; use codex_protocol::protocol::NetworkPolicyRuleAction;
@@ -160,8 +158,6 @@ pub(super) async fn try_run_zsh_fork(
windows_sandbox_level, windows_sandbox_level,
windows_sandbox_private_desktop: _windows_sandbox_private_desktop, windows_sandbox_private_desktop: _windows_sandbox_private_desktop,
permission_profile, permission_profile,
file_system_sandbox_policy,
network_sandbox_policy,
windows_sandbox_filesystem_overrides: _windows_sandbox_filesystem_overrides, windows_sandbox_filesystem_overrides: _windows_sandbox_filesystem_overrides,
arg0, arg0,
exec_server_sandbox: _, exec_server_sandbox: _,
@@ -189,8 +185,6 @@ pub(super) async fn try_run_zsh_fork(
command, command,
cwd: sandbox_cwd, cwd: sandbox_cwd,
permission_profile, permission_profile,
file_system_sandbox_policy,
network_sandbox_policy,
sandbox, sandbox,
env: sandbox_env, env: sandbox_env,
network: sandbox_network, network: sandbox_network,
@@ -240,7 +234,6 @@ pub(super) async fn try_run_zsh_fork(
tool_name: GuardianCommandSource::Shell, tool_name: GuardianCommandSource::Shell,
approval_policy: ctx.turn.approval_policy.value(), approval_policy: ctx.turn.approval_policy.value(),
permission_profile: command_executor.permission_profile.clone(), permission_profile: command_executor.permission_profile.clone(),
file_system_sandbox_policy: command_executor.file_system_sandbox_policy.clone(),
sandbox_permissions: req.sandbox_permissions, sandbox_permissions: req.sandbox_permissions,
approval_sandbox_permissions, approval_sandbox_permissions,
prompt_permissions: req.additional_permissions.clone(), prompt_permissions: req.additional_permissions.clone(),
@@ -302,8 +295,6 @@ pub(crate) async fn prepare_unified_exec_zsh_fork(
command: exec_request.command.clone(), command: exec_request.command.clone(),
cwd, cwd,
permission_profile: exec_request.permission_profile.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: exec_request.sandbox, sandbox: exec_request.sandbox,
env: exec_request.env.clone(), env: exec_request.env.clone(),
network: exec_request.network.clone(), network: exec_request.network.clone(),
@@ -324,7 +315,6 @@ pub(crate) async fn prepare_unified_exec_zsh_fork(
tool_name: GuardianCommandSource::UnifiedExec, tool_name: GuardianCommandSource::UnifiedExec,
approval_policy: ctx.turn.approval_policy.value(), approval_policy: ctx.turn.approval_policy.value(),
permission_profile: exec_request.permission_profile.clone(), permission_profile: exec_request.permission_profile.clone(),
file_system_sandbox_policy: exec_request.file_system_sandbox_policy.clone(),
sandbox_permissions: req.sandbox_permissions, sandbox_permissions: req.sandbox_permissions,
approval_sandbox_permissions: approval_sandbox_permissions( approval_sandbox_permissions: approval_sandbox_permissions(
req.sandbox_permissions, req.sandbox_permissions,
@@ -359,7 +349,6 @@ struct CoreShellActionProvider {
tool_name: GuardianCommandSource, tool_name: GuardianCommandSource,
approval_policy: AskForApproval, approval_policy: AskForApproval,
permission_profile: PermissionProfile, permission_profile: PermissionProfile,
file_system_sandbox_policy: FileSystemSandboxPolicy,
sandbox_permissions: SandboxPermissions, sandbox_permissions: SandboxPermissions,
approval_sandbox_permissions: SandboxPermissions, approval_sandbox_permissions: SandboxPermissions,
prompt_permissions: Option<AdditionalPermissionProfile>, prompt_permissions: Option<AdditionalPermissionProfile>,
@@ -404,13 +393,12 @@ impl CoreShellActionProvider {
fn shell_request_escalation_execution( fn shell_request_escalation_execution(
sandbox_permissions: SandboxPermissions, sandbox_permissions: SandboxPermissions,
permission_profile: &PermissionProfile, permission_profile: &PermissionProfile,
file_system_sandbox_policy: &FileSystemSandboxPolicy,
additional_permissions: Option<&AdditionalPermissionProfile>, additional_permissions: Option<&AdditionalPermissionProfile>,
) -> EscalationExecution { ) -> EscalationExecution {
match sandbox_permissions { match sandbox_permissions {
SandboxPermissions::UseDefault => EscalationExecution::TurnDefault, SandboxPermissions::UseDefault => EscalationExecution::TurnDefault,
SandboxPermissions::RequireEscalated => { SandboxPermissions::RequireEscalated => {
if unsandboxed_execution_allowed(file_system_sandbox_policy) { if unsandboxed_execution_allowed(&permission_profile.file_system_sandbox_policy()) {
EscalationExecution::Unsandboxed EscalationExecution::Unsandboxed
} else { } else {
EscalationExecution::TurnDefault EscalationExecution::TurnDefault
@@ -627,7 +615,8 @@ impl CoreShellActionProvider {
// fallback function. // fallback function.
let decision_driven_by_policy = let decision_driven_by_policy =
Self::decision_driven_by_policy(&evaluation.matched_rules, evaluation.decision); Self::decision_driven_by_policy(&evaluation.matched_rules, evaluation.decision);
let unsandboxed_allowed = unsandboxed_execution_allowed(&self.file_system_sandbox_policy); let unsandboxed_allowed =
unsandboxed_execution_allowed(&self.permission_profile.file_system_sandbox_policy());
let needs_escalation = match self.sandbox_permissions { let needs_escalation = match self.sandbox_permissions {
SandboxPermissions::UseDefault => unsandboxed_allowed && decision_driven_by_policy, SandboxPermissions::UseDefault => unsandboxed_allowed && decision_driven_by_policy,
SandboxPermissions::RequireEscalated => unsandboxed_allowed, SandboxPermissions::RequireEscalated => unsandboxed_allowed,
@@ -645,7 +634,6 @@ impl CoreShellActionProvider {
DecisionSource::UnmatchedCommandFallback => Self::shell_request_escalation_execution( DecisionSource::UnmatchedCommandFallback => Self::shell_request_escalation_execution(
self.sandbox_permissions, self.sandbox_permissions,
&self.permission_profile, &self.permission_profile,
&self.file_system_sandbox_policy,
self.prompt_permissions.as_ref(), self.prompt_permissions.as_ref(),
), ),
}; };
@@ -777,8 +765,6 @@ struct CoreShellCommandExecutor {
command: Vec<String>, command: Vec<String>,
cwd: AbsolutePathBuf, cwd: AbsolutePathBuf,
permission_profile: PermissionProfile, permission_profile: PermissionProfile,
file_system_sandbox_policy: FileSystemSandboxPolicy,
network_sandbox_policy: NetworkSandboxPolicy,
sandbox: SandboxType, sandbox: SandboxType,
env: HashMap<String, String>, env: HashMap<String, String>,
network: Option<codex_network_proxy::NetworkProxy>, network: Option<codex_network_proxy::NetworkProxy>,
@@ -862,8 +848,6 @@ impl CoreShellCommandExecutor {
windows_sandbox_level: self.windows_sandbox_level, windows_sandbox_level: self.windows_sandbox_level,
windows_sandbox_private_desktop: false, windows_sandbox_private_desktop: false,
permission_profile: self.permission_profile.clone(), permission_profile: self.permission_profile.clone(),
file_system_sandbox_policy: self.file_system_sandbox_policy.clone(),
network_sandbox_policy: self.network_sandbox_policy,
windows_sandbox_filesystem_overrides: None, windows_sandbox_filesystem_overrides: None,
arg0: self.arg0.clone(), arg0: self.arg0.clone(),
exec_server_sandbox: None, exec_server_sandbox: None,
@@ -958,15 +942,12 @@ impl CoreShellCommandExecutor {
permission_profile, permission_profile,
additional_permissions, additional_permissions,
} = params; } = params;
let (file_system_sandbox_policy, network_sandbox_policy) =
permission_profile.to_runtime_permissions();
let (program, args) = command let (program, args) = command
.split_first() .split_first()
.ok_or_else(|| anyhow::anyhow!("prepared command must not be empty"))?; .ok_or_else(|| anyhow::anyhow!("prepared command must not be empty"))?;
let sandbox_manager = SandboxManager::new(); let sandbox_manager = SandboxManager::new();
let sandbox = sandbox_manager.select_initial( let sandbox = sandbox_manager.select_initial(
&file_system_sandbox_policy, permission_profile,
network_sandbox_policy,
SandboxablePreference::Auto, SandboxablePreference::Auto,
self.windows_sandbox_level, self.windows_sandbox_level,
self.network.is_some(), self.network.is_some(),
@@ -317,13 +317,15 @@ fn shell_request_escalation_execution_is_explicit() {
&file_system_sandbox_policy, &file_system_sandbox_policy,
network_sandbox_policy, network_sandbox_policy,
); );
let read_only_file_system_policy = read_only_file_system_sandbox_policy(); let read_only_permission_profile = PermissionProfile::from_runtime_permissions(
&read_only_file_system_sandbox_policy(),
network_sandbox_policy,
);
assert_eq!( assert_eq!(
CoreShellActionProvider::shell_request_escalation_execution( CoreShellActionProvider::shell_request_escalation_execution(
crate::sandboxing::SandboxPermissions::UseDefault, crate::sandboxing::SandboxPermissions::UseDefault,
&permission_profile, &permission_profile,
&file_system_sandbox_policy,
/*additional_permissions*/ None, /*additional_permissions*/ None,
), ),
EscalationExecution::TurnDefault, EscalationExecution::TurnDefault,
@@ -331,8 +333,7 @@ fn shell_request_escalation_execution_is_explicit() {
assert_eq!( assert_eq!(
CoreShellActionProvider::shell_request_escalation_execution( CoreShellActionProvider::shell_request_escalation_execution(
crate::sandboxing::SandboxPermissions::RequireEscalated, crate::sandboxing::SandboxPermissions::RequireEscalated,
&permission_profile, &read_only_permission_profile,
&read_only_file_system_policy,
/*additional_permissions*/ None, /*additional_permissions*/ None,
), ),
EscalationExecution::Unsandboxed, EscalationExecution::Unsandboxed,
@@ -341,7 +342,6 @@ fn shell_request_escalation_execution_is_explicit() {
CoreShellActionProvider::shell_request_escalation_execution( CoreShellActionProvider::shell_request_escalation_execution(
crate::sandboxing::SandboxPermissions::RequireEscalated, crate::sandboxing::SandboxPermissions::RequireEscalated,
&permission_profile, &permission_profile,
&file_system_sandbox_policy,
/*additional_permissions*/ None, /*additional_permissions*/ None,
), ),
EscalationExecution::TurnDefault, EscalationExecution::TurnDefault,
@@ -350,7 +350,6 @@ fn shell_request_escalation_execution_is_explicit() {
CoreShellActionProvider::shell_request_escalation_execution( CoreShellActionProvider::shell_request_escalation_execution(
crate::sandboxing::SandboxPermissions::WithAdditionalPermissions, crate::sandboxing::SandboxPermissions::WithAdditionalPermissions,
&permission_profile, &permission_profile,
&file_system_sandbox_policy,
Some(&requested_permissions), Some(&requested_permissions),
), ),
EscalationExecution::Permissions(EscalationPermissions::ResolvedPermissionProfile( EscalationExecution::Permissions(EscalationPermissions::ResolvedPermissionProfile(
@@ -366,8 +365,6 @@ async fn unsandboxed_intercepted_exec_strips_managed_network_env() -> anyhow::Re
command: Vec::new(), command: Vec::new(),
cwd: workdir.clone(), cwd: workdir.clone(),
permission_profile: PermissionProfile::workspace_write(), permission_profile: PermissionProfile::workspace_write(),
file_system_sandbox_policy: read_only_file_system_sandbox_policy(),
network_sandbox_policy: NetworkSandboxPolicy::Restricted,
sandbox: SandboxType::None, sandbox: SandboxType::None,
env: HashMap::new(), env: HashMap::new(),
network: None, network: None,
@@ -435,7 +432,6 @@ async fn preapproved_additional_permissions_escalate_intercepted_exec() -> anyho
tool_name: GuardianCommandSource::Shell, tool_name: GuardianCommandSource::Shell,
approval_policy: AskForApproval::OnRequest, approval_policy: AskForApproval::OnRequest,
permission_profile: permission_profile.clone(), permission_profile: permission_profile.clone(),
file_system_sandbox_policy: read_only_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::WithAdditionalPermissions, sandbox_permissions: SandboxPermissions::WithAdditionalPermissions,
approval_sandbox_permissions: SandboxPermissions::UseDefault, approval_sandbox_permissions: SandboxPermissions::UseDefault,
prompt_permissions: Some(requested_permissions), prompt_permissions: Some(requested_permissions),
@@ -571,7 +567,6 @@ async fn execve_permission_request_hook_short_circuits_prompt() -> anyhow::Resul
tool_name: GuardianCommandSource::Shell, tool_name: GuardianCommandSource::Shell,
approval_policy: AskForApproval::OnRequest, approval_policy: AskForApproval::OnRequest,
permission_profile: PermissionProfile::read_only(), permission_profile: PermissionProfile::read_only(),
file_system_sandbox_policy: read_only_file_system_sandbox_policy(),
sandbox_permissions: SandboxPermissions::RequireEscalated, sandbox_permissions: SandboxPermissions::RequireEscalated,
approval_sandbox_permissions: SandboxPermissions::RequireEscalated, approval_sandbox_permissions: SandboxPermissions::RequireEscalated,
prompt_permissions: None, prompt_permissions: None,
@@ -782,7 +777,6 @@ prefix_rule(pattern = ["{cat_path_literal}"], decision = "allow")
tool_name: GuardianCommandSource::Shell, tool_name: GuardianCommandSource::Shell,
approval_policy: AskForApproval::OnRequest, approval_policy: AskForApproval::OnRequest,
permission_profile, permission_profile,
file_system_sandbox_policy,
sandbox_permissions: SandboxPermissions::UseDefault, sandbox_permissions: SandboxPermissions::UseDefault,
approval_sandbox_permissions: SandboxPermissions::UseDefault, approval_sandbox_permissions: SandboxPermissions::UseDefault,
prompt_permissions: None, prompt_permissions: None,
@@ -825,7 +819,6 @@ async fn denied_reads_keep_granular_sandbox_rejection_for_escalation() -> anyhow
mcp_elicitations: true, mcp_elicitations: true,
}), }),
permission_profile, permission_profile,
file_system_sandbox_policy,
sandbox_permissions: SandboxPermissions::RequireEscalated, sandbox_permissions: SandboxPermissions::RequireEscalated,
approval_sandbox_permissions: SandboxPermissions::RequireEscalated, approval_sandbox_permissions: SandboxPermissions::RequireEscalated,
prompt_permissions: None, prompt_permissions: None,
@@ -110,9 +110,6 @@ fn exec_server_params_use_path_uri_and_env_policy_overlay_contract() {
.expect("current dir") .expect("current dir")
.try_into() .try_into()
.expect("absolute path"); .expect("absolute path");
let file_system_sandbox_policy =
codex_protocol::permissions::FileSystemSandboxPolicy::unrestricted();
let network_sandbox_policy = codex_protocol::permissions::NetworkSandboxPolicy::Restricted;
let permission_profile = codex_protocol::models::PermissionProfile::Disabled; let permission_profile = codex_protocol::models::PermissionProfile::Disabled;
let managed_network = ManagedNetworkSandboxContext { let managed_network = ManagedNetworkSandboxContext {
loopback_ports: vec![43123], loopback_ports: vec![43123],
@@ -167,8 +164,6 @@ fn exec_server_params_use_path_uri_and_env_policy_overlay_contract() {
windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel::Disabled, windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel::Disabled,
windows_sandbox_private_desktop: false, windows_sandbox_private_desktop: false,
permission_profile: permission_profile.clone(), permission_profile: permission_profile.clone(),
file_system_sandbox_policy,
network_sandbox_policy,
windows_sandbox_filesystem_overrides: None, windows_sandbox_filesystem_overrides: None,
arg0: None, arg0: None,
exec_server_sandbox: None, exec_server_sandbox: None,
+1 -3
View File
@@ -112,10 +112,8 @@ impl FileSystemSandboxRunner {
) -> Result<SandboxExecRequest, JSONRPCErrorError> { ) -> Result<SandboxExecRequest, JSONRPCErrorError> {
let helper = &self.runtime_paths.codex_self_exe; let helper = &self.runtime_paths.codex_self_exe;
let sandbox_manager = SandboxManager::new(); let sandbox_manager = SandboxManager::new();
let (file_system_policy, network_policy) = permission_profile.to_runtime_permissions();
let sandbox = sandbox_manager.select_initial( let sandbox = sandbox_manager.select_initial(
&file_system_policy, permission_profile,
network_policy,
SandboxablePreference::Auto, SandboxablePreference::Auto,
sandbox_context.windows_sandbox_level, sandbox_context.windows_sandbox_level,
/*has_managed_network_requirements*/ false, /*has_managed_network_requirements*/ false,
+2 -2
View File
@@ -150,6 +150,7 @@ pub(crate) async fn prepare_exec_request(
managed_mitm_ca_trust_bundle_path.as_ref(), managed_mitm_ca_trust_bundle_path.as_ref(),
native_sandbox_policy_cwd.as_path(), native_sandbox_policy_cwd.as_path(),
); );
#[cfg(unix)]
let (file_system_policy, network_policy) = permissions.to_runtime_permissions(); let (file_system_policy, network_policy) = permissions.to_runtime_permissions();
#[cfg(unix)] #[cfg(unix)]
let sandbox_helper_paths = params let sandbox_helper_paths = params
@@ -179,8 +180,7 @@ pub(crate) async fn prepare_exec_request(
); );
let sandbox_manager = SandboxManager::new(); let sandbox_manager = SandboxManager::new();
let sandbox = sandbox_manager.select_initial( let sandbox = sandbox_manager.select_initial(
&file_system_policy, &permissions,
network_policy,
SandboxablePreference::Require, SandboxablePreference::Require,
sandbox_context.windows_sandbox_level, sandbox_context.windows_sandbox_level,
params.enforce_managed_network, params.enforce_managed_network,
+25 -46
View File
@@ -120,8 +120,6 @@ pub struct SandboxExecRequest {
pub windows_sandbox_level: WindowsSandboxLevel, pub windows_sandbox_level: WindowsSandboxLevel,
pub windows_sandbox_private_desktop: bool, pub windows_sandbox_private_desktop: bool,
pub permission_profile: PermissionProfile, pub permission_profile: PermissionProfile,
pub file_system_sandbox_policy: FileSystemSandboxPolicy,
pub network_sandbox_policy: NetworkSandboxPolicy,
pub arg0: Option<String>, pub arg0: Option<String>,
} }
@@ -160,8 +158,6 @@ struct PendingSandboxedExecRequest {
native_command_cwd: AbsolutePathBuf, native_command_cwd: AbsolutePathBuf,
native_sandbox_policy_cwd: AbsolutePathBuf, native_sandbox_policy_cwd: AbsolutePathBuf,
effective_permission_profile: PermissionProfile, effective_permission_profile: PermissionProfile,
effective_file_system_policy: FileSystemSandboxPolicy,
effective_network_policy: NetworkSandboxPolicy,
} }
impl PendingSandboxedExecRequest { impl PendingSandboxedExecRequest {
@@ -189,14 +185,10 @@ impl PendingSandboxedExecRequest {
managed_mitm_ca_trust_bundle_path, managed_mitm_ca_trust_bundle_path,
native_sandbox_policy_cwd.as_path(), native_sandbox_policy_cwd.as_path(),
); );
let (effective_file_system_policy, effective_network_policy) =
effective_permission_profile.to_runtime_permissions();
Ok(Self { Ok(Self {
native_command_cwd, native_command_cwd,
native_sandbox_policy_cwd, native_sandbox_policy_cwd,
effective_permission_profile, effective_permission_profile,
effective_file_system_policy,
effective_network_policy,
}) })
} }
} }
@@ -279,18 +271,12 @@ impl SandboxManager {
pub fn select_initial( pub fn select_initial(
&self, &self,
file_system_policy: &FileSystemSandboxPolicy, permission_profile: &PermissionProfile,
network_policy: NetworkSandboxPolicy,
pref: SandboxablePreference, pref: SandboxablePreference,
windows_sandbox_level: WindowsSandboxLevel, windows_sandbox_level: WindowsSandboxLevel,
has_managed_network_requirements: bool, has_managed_network_requirements: bool,
) -> SandboxType { ) -> SandboxType {
if self.should_sandbox( if self.should_sandbox(permission_profile, pref, has_managed_network_requirements) {
file_system_policy,
network_policy,
pref,
has_managed_network_requirements,
) {
get_platform_sandbox(windows_sandbox_level != WindowsSandboxLevel::Disabled) get_platform_sandbox(windows_sandbox_level != WindowsSandboxLevel::Disabled)
.unwrap_or(SandboxType::None) .unwrap_or(SandboxType::None)
} else { } else {
@@ -302,19 +288,22 @@ impl SandboxManager {
/// this host can provide a concrete sandbox implementation. /// this host can provide a concrete sandbox implementation.
pub fn should_sandbox( pub fn should_sandbox(
&self, &self,
file_system_policy: &FileSystemSandboxPolicy, permission_profile: &PermissionProfile,
network_policy: NetworkSandboxPolicy,
pref: SandboxablePreference, pref: SandboxablePreference,
has_managed_network_requirements: bool, has_managed_network_requirements: bool,
) -> bool { ) -> bool {
match pref { match pref {
SandboxablePreference::Forbid => false, SandboxablePreference::Forbid => false,
SandboxablePreference::Require => true, SandboxablePreference::Require => true,
SandboxablePreference::Auto => should_require_platform_sandbox( SandboxablePreference::Auto => {
file_system_policy, let (file_system_policy, network_policy) =
network_policy, permission_profile.to_runtime_permissions();
has_managed_network_requirements, should_require_platform_sandbox(
), &file_system_policy,
network_policy,
has_managed_network_requirements,
)
}
} }
} }
@@ -348,8 +337,6 @@ impl SandboxManager {
base_effective_permission_profile.clone(), base_effective_permission_profile.clone(),
managed_mitm_ca_trust_bundle_path.as_ref(), managed_mitm_ca_trust_bundle_path.as_ref(),
); );
let (base_file_system_policy, base_network_policy) =
base_effective_permission_profile.to_runtime_permissions();
let mut argv = Vec::with_capacity(1 + command.args.len()); let mut argv = Vec::with_capacity(1 + command.args.len());
argv.push(command.program); argv.push(command.program);
argv.extend(command.args.into_iter().map(OsString::from)); argv.extend(command.args.into_iter().map(OsString::from));
@@ -363,10 +350,13 @@ impl SandboxManager {
use crate::seatbelt::create_seatbelt_command_args; use crate::seatbelt::create_seatbelt_command_args;
let pending = pending_sandboxed_request?; let pending = pending_sandboxed_request?;
let (file_system_sandbox_policy, network_sandbox_policy) = pending
.effective_permission_profile
.to_runtime_permissions();
let mut args = create_seatbelt_command_args(CreateSeatbeltCommandArgsParams { let mut args = create_seatbelt_command_args(CreateSeatbeltCommandArgsParams {
command: os_argv_to_strings(argv), command: os_argv_to_strings(argv),
file_system_sandbox_policy: &pending.effective_file_system_policy, file_system_sandbox_policy: &file_system_sandbox_policy,
network_sandbox_policy: pending.effective_network_policy, network_sandbox_policy,
sandbox_policy_cwd: pending.native_sandbox_policy_cwd.as_path(), sandbox_policy_cwd: pending.native_sandbox_policy_cwd.as_path(),
enforce_managed_network, enforce_managed_network,
managed_network, managed_network,
@@ -389,7 +379,9 @@ impl SandboxManager {
let allow_proxy_network = allow_network_for_proxy(enforce_managed_network); let allow_proxy_network = allow_network_for_proxy(enforce_managed_network);
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
ensure_linux_bubblewrap_is_supported( ensure_linux_bubblewrap_is_supported(
&pending.effective_file_system_policy, &pending
.effective_permission_profile
.file_system_sandbox_policy(),
use_legacy_landlock, use_legacy_landlock,
allow_proxy_network, allow_proxy_network,
is_wsl1(), is_wsl1(),
@@ -427,22 +419,11 @@ impl SandboxManager {
// Unsandboxed exec-server requests may have foreign cwd values that cannot be prepared // Unsandboxed exec-server requests may have foreign cwd values that cannot be prepared
// locally, but their effective permissions must still be preserved. In that case, carry // locally, but their effective permissions must still be preserved. In that case, carry
// forward the base profile and its derived runtime policies. // forward the base profile.
let (permission_profile, file_system_sandbox_policy, network_sandbox_policy) = let permission_profile = pending_sandboxed_request
pending_sandboxed_request.map_or( .map_or(base_effective_permission_profile, |pending| {
( pending.effective_permission_profile
base_effective_permission_profile, });
base_file_system_policy,
base_network_policy,
),
|pending| {
(
pending.effective_permission_profile,
pending.effective_file_system_policy,
pending.effective_network_policy,
)
},
);
Ok(SandboxExecRequest { Ok(SandboxExecRequest {
command: argv, command: argv,
@@ -455,8 +436,6 @@ impl SandboxManager {
windows_sandbox_level, windows_sandbox_level,
windows_sandbox_private_desktop, windows_sandbox_private_desktop,
permission_profile, permission_profile,
file_system_sandbox_policy,
network_sandbox_policy,
arg0: arg0_override, arg0: arg0_override,
}) })
} }
+11 -10
View File
@@ -29,8 +29,7 @@ use tempfile::TempDir;
fn danger_full_access_defaults_to_no_sandbox_without_network_requirements() { fn danger_full_access_defaults_to_no_sandbox_without_network_requirements() {
let manager = SandboxManager::new(); let manager = SandboxManager::new();
let sandbox = manager.select_initial( let sandbox = manager.select_initial(
&FileSystemSandboxPolicy::unrestricted(), &PermissionProfile::Disabled,
NetworkSandboxPolicy::Enabled,
SandboxablePreference::Auto, SandboxablePreference::Auto,
WindowsSandboxLevel::Disabled, WindowsSandboxLevel::Disabled,
/*has_managed_network_requirements*/ false, /*has_managed_network_requirements*/ false,
@@ -44,8 +43,7 @@ fn danger_full_access_uses_platform_sandbox_with_network_requirements() {
let expected = let expected =
get_platform_sandbox(/*windows_sandbox_enabled*/ false).unwrap_or(SandboxType::None); get_platform_sandbox(/*windows_sandbox_enabled*/ false).unwrap_or(SandboxType::None);
let sandbox = manager.select_initial( let sandbox = manager.select_initial(
&FileSystemSandboxPolicy::unrestricted(), &PermissionProfile::Disabled,
NetworkSandboxPolicy::Enabled,
SandboxablePreference::Auto, SandboxablePreference::Auto,
WindowsSandboxLevel::Disabled, WindowsSandboxLevel::Disabled,
/*has_managed_network_requirements*/ true, /*has_managed_network_requirements*/ true,
@@ -58,7 +56,7 @@ fn restricted_file_system_uses_platform_sandbox_without_managed_network() {
let manager = SandboxManager::new(); let manager = SandboxManager::new();
let expected = let expected =
get_platform_sandbox(/*windows_sandbox_enabled*/ false).unwrap_or(SandboxType::None); get_platform_sandbox(/*windows_sandbox_enabled*/ false).unwrap_or(SandboxType::None);
let sandbox = manager.select_initial( let permissions = PermissionProfile::from_runtime_permissions(
&FileSystemSandboxPolicy::restricted(vec![FileSystemSandboxEntry { &FileSystemSandboxPolicy::restricted(vec![FileSystemSandboxEntry {
path: FileSystemPath::Special { path: FileSystemPath::Special {
value: FileSystemSpecialPath::Root, value: FileSystemSpecialPath::Root,
@@ -67,6 +65,9 @@ fn restricted_file_system_uses_platform_sandbox_without_managed_network() {
missing_path_behavior: None, missing_path_behavior: None,
}]), }]),
NetworkSandboxPolicy::Enabled, NetworkSandboxPolicy::Enabled,
);
let sandbox = manager.select_initial(
&permissions,
SandboxablePreference::Auto, SandboxablePreference::Auto,
WindowsSandboxLevel::Disabled, WindowsSandboxLevel::Disabled,
/*has_managed_network_requirements*/ false, /*has_managed_network_requirements*/ false,
@@ -112,11 +113,11 @@ fn unsandboxed_transform_preserves_foreign_cwd_and_unrestricted_file_system_poli
assert_eq!(exec_request.cwd, cwd_uri); assert_eq!(exec_request.cwd, cwd_uri);
assert_eq!(exec_request.sandbox_policy_cwd, cwd_uri); assert_eq!(exec_request.sandbox_policy_cwd, cwd_uri);
assert_eq!( assert_eq!(
exec_request.file_system_sandbox_policy, exec_request.permission_profile.file_system_sandbox_policy(),
FileSystemSandboxPolicy::unrestricted() FileSystemSandboxPolicy::unrestricted()
); );
assert_eq!( assert_eq!(
exec_request.network_sandbox_policy, exec_request.permission_profile.network_sandbox_policy(),
NetworkSandboxPolicy::Restricted NetworkSandboxPolicy::Restricted
); );
} }
@@ -172,7 +173,7 @@ fn transform_additional_permissions_enable_network_for_external_sandbox() {
} }
); );
assert_eq!( assert_eq!(
exec_request.network_sandbox_policy, exec_request.permission_profile.network_sandbox_policy(),
NetworkSandboxPolicy::Enabled NetworkSandboxPolicy::Enabled
); );
} }
@@ -239,7 +240,7 @@ fn transform_additional_permissions_preserves_denied_entries() {
.expect("transform"); .expect("transform");
assert_eq!( assert_eq!(
exec_request.file_system_sandbox_policy, exec_request.permission_profile.file_system_sandbox_policy(),
FileSystemSandboxPolicy::restricted(vec![ FileSystemSandboxPolicy::restricted(vec![
FileSystemSandboxEntry { FileSystemSandboxEntry {
path: FileSystemPath::Special { path: FileSystemPath::Special {
@@ -261,7 +262,7 @@ fn transform_additional_permissions_preserves_denied_entries() {
]) ])
); );
assert_eq!( assert_eq!(
exec_request.network_sandbox_policy, exec_request.permission_profile.network_sandbox_policy(),
NetworkSandboxPolicy::Restricted NetworkSandboxPolicy::Restricted
); );
} }