mirror of
https://github.com/openai/codex.git
synced 2026-11-01 19:33:35 +00:00
feat: support allowed_sandbox_modes in requirements.toml
This commit is contained in:
@@ -510,7 +510,7 @@ impl App {
|
||||
{
|
||||
let should_check = codex_core::get_platform_sandbox().is_some()
|
||||
&& matches!(
|
||||
app.config.sandbox_policy,
|
||||
app.config.sandbox_policy.get(),
|
||||
codex_core::protocol::SandboxPolicy::WorkspaceWrite { .. }
|
||||
| codex_core::protocol::SandboxPolicy::ReadOnly
|
||||
)
|
||||
@@ -524,7 +524,7 @@ impl App {
|
||||
let env_map: std::collections::HashMap<String, String> = std::env::vars().collect();
|
||||
let tx = app.app_event_tx.clone();
|
||||
let logs_base_dir = app.config.codex_home.clone();
|
||||
let sandbox_policy = app.config.sandbox_policy.clone();
|
||||
let sandbox_policy = app.config.sandbox_policy.clone_value();
|
||||
Self::spawn_world_writable_scan(cwd, env_map, logs_base_dir, sandbox_policy, tx);
|
||||
}
|
||||
}
|
||||
@@ -1744,19 +1744,29 @@ impl App {
|
||||
AppEvent::UpdateSandboxPolicy(policy) => {
|
||||
#[cfg(target_os = "windows")]
|
||||
let policy_is_workspace_write_or_ro = matches!(
|
||||
policy,
|
||||
&policy,
|
||||
codex_core::protocol::SandboxPolicy::WorkspaceWrite { .. }
|
||||
| codex_core::protocol::SandboxPolicy::ReadOnly
|
||||
);
|
||||
|
||||
self.config.sandbox_policy = policy.clone();
|
||||
if let Err(err) = self.config.sandbox_policy.set(policy.clone()) {
|
||||
tracing::warn!(%err, "failed to set sandbox policy on app config");
|
||||
self.chat_widget
|
||||
.add_error_message(format!("Failed to set sandbox policy: {err}"));
|
||||
return Ok(true);
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
if !matches!(policy, codex_core::protocol::SandboxPolicy::ReadOnly)
|
||||
if !matches!(&policy, codex_core::protocol::SandboxPolicy::ReadOnly)
|
||||
|| codex_core::get_platform_sandbox().is_some()
|
||||
{
|
||||
self.config.forced_auto_mode_downgraded_on_windows = false;
|
||||
}
|
||||
self.chat_widget.set_sandbox_policy(policy);
|
||||
if let Err(err) = self.chat_widget.set_sandbox_policy(policy) {
|
||||
tracing::warn!(%err, "failed to set sandbox policy on chat config");
|
||||
self.chat_widget
|
||||
.add_error_message(format!("Failed to set sandbox policy: {err}"));
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
// If sandbox policy becomes workspace-write or read-only, run the Windows world-writable scan.
|
||||
#[cfg(target_os = "windows")]
|
||||
@@ -1776,7 +1786,7 @@ impl App {
|
||||
std::env::vars().collect();
|
||||
let tx = self.app_event_tx.clone();
|
||||
let logs_base_dir = self.config.codex_home.clone();
|
||||
let sandbox_policy = self.config.sandbox_policy.clone();
|
||||
let sandbox_policy = self.config.sandbox_policy.clone_value();
|
||||
Self::spawn_world_writable_scan(
|
||||
cwd,
|
||||
env_map,
|
||||
|
||||
@@ -8,6 +8,7 @@ use std::time::Duration;
|
||||
use codex_app_server_protocol::AuthMode;
|
||||
use codex_backend_client::Client as BackendClient;
|
||||
use codex_core::config::Config;
|
||||
use codex_core::config::ConstraintResult;
|
||||
use codex_core::config::types::Notifications;
|
||||
use codex_core::git_info::current_branch_name;
|
||||
use codex_core::git_info::local_git_branches;
|
||||
@@ -2554,12 +2555,12 @@ impl ChatWidget {
|
||||
/// Open a popup to choose the approvals mode (ask for approval policy + sandbox policy).
|
||||
pub(crate) fn open_approvals_popup(&mut self) {
|
||||
let current_approval = self.config.approval_policy.value();
|
||||
let current_sandbox = self.config.sandbox_policy.clone();
|
||||
let current_sandbox = self.config.sandbox_policy.get();
|
||||
let mut items: Vec<SelectionItem> = Vec::new();
|
||||
let presets: Vec<ApprovalPreset> = builtin_approval_presets();
|
||||
for preset in presets.into_iter() {
|
||||
let is_current =
|
||||
Self::preset_matches_current(current_approval, ¤t_sandbox, &preset);
|
||||
Self::preset_matches_current(current_approval, current_sandbox, &preset);
|
||||
let name = preset.label.to_string();
|
||||
let description_text = preset.description;
|
||||
let description = Some(description_text.to_string());
|
||||
@@ -2685,7 +2686,7 @@ impl ChatWidget {
|
||||
self.config.codex_home.as_path(),
|
||||
cwd.as_path(),
|
||||
&env_map,
|
||||
&self.config.sandbox_policy,
|
||||
self.config.sandbox_policy.get(),
|
||||
Some(self.config.codex_home.as_path()),
|
||||
) {
|
||||
Ok(_) => None,
|
||||
@@ -2784,7 +2785,7 @@ impl ChatWidget {
|
||||
let mode_label = preset
|
||||
.as_ref()
|
||||
.map(|p| describe_policy(&p.sandbox))
|
||||
.unwrap_or_else(|| describe_policy(&self.config.sandbox_policy));
|
||||
.unwrap_or_else(|| describe_policy(self.config.sandbox_policy.get()));
|
||||
let info_line = if failed_scan {
|
||||
Line::from(vec![
|
||||
"We couldn't complete the world-writable scan, so protections cannot be verified. "
|
||||
@@ -2957,17 +2958,19 @@ impl ChatWidget {
|
||||
}
|
||||
|
||||
/// Set the sandbox policy in the widget's config copy.
|
||||
pub(crate) fn set_sandbox_policy(&mut self, policy: SandboxPolicy) {
|
||||
pub(crate) fn set_sandbox_policy(&mut self, policy: SandboxPolicy) -> ConstraintResult<()> {
|
||||
#[cfg(target_os = "windows")]
|
||||
let should_clear_downgrade = !matches!(policy, SandboxPolicy::ReadOnly)
|
||||
let should_clear_downgrade = !matches!(&policy, SandboxPolicy::ReadOnly)
|
||||
|| codex_core::get_platform_sandbox().is_some();
|
||||
|
||||
self.config.sandbox_policy = policy;
|
||||
self.config.sandbox_policy.set(policy)?;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
if should_clear_downgrade {
|
||||
self.config.forced_auto_mode_downgraded_on_windows = false;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn set_full_access_warning_acknowledged(&mut self, acknowledged: bool) {
|
||||
|
||||
@@ -223,7 +223,7 @@ pub async fn run_main(
|
||||
|
||||
let config = load_config_or_exit(cli_kv_overrides.clone(), overrides.clone()).await;
|
||||
|
||||
if let Some(warning) = add_dir_warning_message(&cli.add_dir, &config.sandbox_policy) {
|
||||
if let Some(warning) = add_dir_warning_message(&cli.add_dir, config.sandbox_policy.get()) {
|
||||
#[allow(clippy::print_stderr)]
|
||||
{
|
||||
eprintln!("Error adding directories: {warning}");
|
||||
|
||||
@@ -119,7 +119,7 @@ impl StatusHistoryCell {
|
||||
.find(|(k, _)| *k == "approval")
|
||||
.map(|(_, v)| v.clone())
|
||||
.unwrap_or_else(|| "<unknown>".to_string());
|
||||
let sandbox = match &config.sandbox_policy {
|
||||
let sandbox = match config.sandbox_policy.get() {
|
||||
SandboxPolicy::DangerFullAccess => "danger-full-access".to_string(),
|
||||
SandboxPolicy::ReadOnly => "read-only".to_string(),
|
||||
SandboxPolicy::WorkspaceWrite { .. } => "workspace-write".to_string(),
|
||||
|
||||
@@ -90,12 +90,15 @@ async fn status_snapshot_includes_reasoning_details() {
|
||||
config.model_provider_id = "openai".to_string();
|
||||
config.model_reasoning_effort = Some(ReasoningEffort::High);
|
||||
config.model_reasoning_summary = ReasoningSummary::Detailed;
|
||||
config.sandbox_policy = SandboxPolicy::WorkspaceWrite {
|
||||
writable_roots: Vec::new(),
|
||||
network_access: false,
|
||||
exclude_tmpdir_env_var: false,
|
||||
exclude_slash_tmp: false,
|
||||
};
|
||||
config
|
||||
.sandbox_policy
|
||||
.set(SandboxPolicy::WorkspaceWrite {
|
||||
writable_roots: Vec::new(),
|
||||
network_access: false,
|
||||
exclude_tmpdir_env_var: false,
|
||||
exclude_slash_tmp: false,
|
||||
})
|
||||
.expect("set sandbox policy");
|
||||
|
||||
config.cwd = PathBuf::from("/workspace/tests");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user