Skip to content

Commit 7134842

Browse files
feat: configure network_access independent of sandbox policy
1 parent 927a6ac commit 7134842

File tree

8 files changed

+197
-28
lines changed

8 files changed

+197
-28
lines changed

codex-rs/app-server-protocol/src/protocol/v1.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::path::PathBuf;
33

44
use codex_protocol::ConversationId;
55
use codex_protocol::config_types::ForcedLoginMethod;
6+
use codex_protocol::config_types::NetworkAccess;
67
use codex_protocol::config_types::ReasoningSummary;
78
use codex_protocol::config_types::SandboxMode;
89
use codex_protocol::config_types::Verbosity;
@@ -326,6 +327,7 @@ pub struct UserSavedConfig {
326327
pub approval_policy: Option<AskForApproval>,
327328
pub sandbox_mode: Option<SandboxMode>,
328329
pub sandbox_settings: Option<SandboxSettings>,
330+
pub network_access: Option<NetworkAccess>,
329331
pub forced_chatgpt_workspace_id: Option<String>,
330332
pub forced_login_method: Option<ForcedLoginMethod>,
331333
pub model: Option<String>,

codex-rs/app-server-protocol/src/protocol/v2.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::protocol::common::AuthMode;
55
use codex_protocol::account::PlanType;
66
use codex_protocol::approvals::ExecPolicyAmendment as CoreExecPolicyAmendment;
77
use codex_protocol::config_types::ForcedLoginMethod;
8+
use codex_protocol::config_types::NetworkAccess;
89
use codex_protocol::config_types::ReasoningSummary;
910
use codex_protocol::config_types::SandboxMode as CoreSandboxMode;
1011
use codex_protocol::config_types::Verbosity;
@@ -279,6 +280,7 @@ pub struct Config {
279280
pub approval_policy: Option<AskForApproval>,
280281
pub sandbox_mode: Option<SandboxMode>,
281282
pub sandbox_workspace_write: Option<SandboxWorkspaceWrite>,
283+
pub network_access: Option<NetworkAccess>,
282284
pub forced_chatgpt_workspace_id: Option<String>,
283285
pub forced_login_method: Option<ForcedLoginMethod>,
284286
pub tools: Option<ToolsV2>,

codex-rs/app-server/tests/suite/config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ async fn get_config_toml_parses_all_fields() -> Result<()> {
9191
exclude_tmpdir_env_var: Some(true),
9292
exclude_slash_tmp: Some(true),
9393
}),
94+
network_access: None,
9495
forced_chatgpt_workspace_id: Some("12345678-0000-0000-0000-000000000000".into()),
9596
forced_login_method: Some(ForcedLoginMethod::Chatgpt),
9697
model: Some("gpt-5.1-codex-max".into()),
@@ -141,6 +142,7 @@ async fn get_config_toml_empty() -> Result<()> {
141142
approval_policy: None,
142143
sandbox_mode: None,
143144
sandbox_settings: None,
145+
network_access: None,
144146
forced_chatgpt_workspace_id: None,
145147
forced_login_method: None,
146148
model: None,

codex-rs/core/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ sha1 = { workspace = true }
6060
sha2 = { workspace = true }
6161
shlex = { workspace = true }
6262
similar = { workspace = true }
63-
strum_macros = { workspace = true }
6463
tempfile = { workspace = true }
6564
test-case = "3.3.1"
6665
test-log = { workspace = true }

codex-rs/core/src/codex.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ use crate::util::backoff;
151151
use codex_async_utils::OrCancelExt;
152152
use codex_execpolicy::Policy as ExecPolicy;
153153
use codex_otel::otel_manager::OtelManager;
154+
use codex_protocol::config_types::NetworkAccess;
154155
use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig;
155156
use codex_protocol::models::ContentItem;
156157
use codex_protocol::models::ResponseInputItem;
@@ -266,6 +267,7 @@ impl Codex {
266267
compact_prompt: config.compact_prompt.clone(),
267268
approval_policy: config.approval_policy.clone(),
268269
sandbox_policy: config.sandbox_policy.clone(),
270+
network_access: config.network_access,
269271
cwd: config.cwd.clone(),
270272
original_config_do_not_use: Arc::clone(&config),
271273
exec_policy,
@@ -367,6 +369,7 @@ pub(crate) struct TurnContext {
367369
pub(crate) user_instructions: Option<String>,
368370
pub(crate) approval_policy: AskForApproval,
369371
pub(crate) sandbox_policy: SandboxPolicy,
372+
pub(crate) network_access: Option<NetworkAccess>,
370373
pub(crate) shell_environment_policy: ShellEnvironmentPolicy,
371374
pub(crate) tools_config: ToolsConfig,
372375
pub(crate) ghost_snapshot: GhostSnapshotConfig,
@@ -418,6 +421,8 @@ pub(crate) struct SessionConfiguration {
418421
approval_policy: Constrained<AskForApproval>,
419422
/// How to sandbox commands executed in the system
420423
sandbox_policy: SandboxPolicy,
424+
/// Optional override describing network access to include in environment context.
425+
network_access: Option<NetworkAccess>,
421426

422427
/// Working directory that should be treated as the *root* of the
423428
/// session. All relative paths supplied by the model as well as the
@@ -529,6 +534,7 @@ impl Session {
529534
user_instructions: session_configuration.user_instructions.clone(),
530535
approval_policy: session_configuration.approval_policy.value(),
531536
sandbox_policy: session_configuration.sandbox_policy.clone(),
537+
network_access: session_configuration.network_access,
532538
shell_environment_policy: per_turn_config.shell_environment_policy.clone(),
533539
tools_config,
534540
ghost_snapshot: per_turn_config.ghost_snapshot.clone(),
@@ -1327,6 +1333,7 @@ impl Session {
13271333
Some(turn_context.cwd.clone()),
13281334
Some(turn_context.approval_policy),
13291335
Some(turn_context.sandbox_policy.clone()),
1336+
turn_context.network_access,
13301337
shell.as_ref().clone(),
13311338
)));
13321339
items
@@ -2181,6 +2188,7 @@ async fn spawn_review_thread(
21812188
compact_prompt: parent_turn_context.compact_prompt.clone(),
21822189
approval_policy: parent_turn_context.approval_policy,
21832190
sandbox_policy: parent_turn_context.sandbox_policy.clone(),
2191+
network_access: parent_turn_context.network_access,
21842192
shell_environment_policy: parent_turn_context.shell_environment_policy.clone(),
21852193
cwd: parent_turn_context.cwd.clone(),
21862194
final_output_json_schema: None,
@@ -2882,6 +2890,7 @@ mod tests {
28822890
compact_prompt: config.compact_prompt.clone(),
28832891
approval_policy: config.approval_policy.clone(),
28842892
sandbox_policy: config.sandbox_policy.clone(),
2893+
network_access: config.network_access,
28852894
cwd: config.cwd.clone(),
28862895
original_config_do_not_use: Arc::clone(&config),
28872896
exec_policy: Arc::new(RwLock::new(ExecPolicy::empty())),
@@ -2954,6 +2963,7 @@ mod tests {
29542963
compact_prompt: config.compact_prompt.clone(),
29552964
approval_policy: config.approval_policy.clone(),
29562965
sandbox_policy: config.sandbox_policy.clone(),
2966+
network_access: config.network_access,
29572967
cwd: config.cwd.clone(),
29582968
original_config_do_not_use: Arc::clone(&config),
29592969
exec_policy: Arc::new(RwLock::new(ExecPolicy::empty())),
@@ -3158,6 +3168,7 @@ mod tests {
31583168
compact_prompt: config.compact_prompt.clone(),
31593169
approval_policy: config.approval_policy.clone(),
31603170
sandbox_policy: config.sandbox_policy.clone(),
3171+
network_access: config.network_access,
31613172
cwd: config.cwd.clone(),
31623173
original_config_do_not_use: Arc::clone(&config),
31633174
exec_policy: Arc::new(RwLock::new(ExecPolicy::empty())),
@@ -3249,6 +3260,7 @@ mod tests {
32493260
compact_prompt: config.compact_prompt.clone(),
32503261
approval_policy: config.approval_policy.clone(),
32513262
sandbox_policy: config.sandbox_policy.clone(),
3263+
network_access: config.network_access,
32523264
cwd: config.cwd.clone(),
32533265
original_config_do_not_use: Arc::clone(&config),
32543266
exec_policy: Arc::new(RwLock::new(ExecPolicy::empty())),

codex-rs/core/src/config/mod.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use crate::protocol::SandboxPolicy;
2929
use codex_app_server_protocol::Tools;
3030
use codex_app_server_protocol::UserSavedConfig;
3131
use codex_protocol::config_types::ForcedLoginMethod;
32+
use codex_protocol::config_types::NetworkAccess;
3233
use codex_protocol::config_types::ReasoningSummary;
3334
use codex_protocol::config_types::SandboxMode;
3435
use codex_protocol::config_types::TrustLevel;
@@ -113,6 +114,9 @@ pub struct Config {
113114

114115
pub sandbox_policy: SandboxPolicy,
115116

117+
/// Optional override for the network status sent in the environment context.
118+
pub network_access: Option<NetworkAccess>,
119+
116120
/// True if the user passed in an override or set a value in config.toml
117121
/// for either of approval_policy or sandbox_mode.
118122
pub did_user_set_custom_approval_policy_or_sandbox_mode: bool,
@@ -560,6 +564,9 @@ pub struct ConfigToml {
560564
/// Sandbox mode to use.
561565
pub sandbox_mode: Option<SandboxMode>,
562566

567+
/// Optional override describing network access to include in environment context.
568+
pub network_access: Option<NetworkAccess>,
569+
563570
/// Sandbox configuration to apply if `sandbox` is `WorkspaceWrite`.
564571
pub sandbox_workspace_write: Option<SandboxWorkspaceWrite>,
565572

@@ -712,6 +719,7 @@ impl From<ConfigToml> for UserSavedConfig {
712719
approval_policy: config_toml.approval_policy,
713720
sandbox_mode: config_toml.sandbox_mode,
714721
sandbox_settings: config_toml.sandbox_workspace_write.map(From::from),
722+
network_access: config_toml.network_access,
715723
forced_chatgpt_workspace_id: config_toml.forced_chatgpt_workspace_id,
716724
forced_login_method: config_toml.forced_login_method,
717725
model: config_toml.model,
@@ -1026,6 +1034,7 @@ impl Config {
10261034
}
10271035
}
10281036
}
1037+
let network_access = cfg.network_access;
10291038
let approval_policy = approval_policy_override
10301039
.or(config_profile.approval_policy)
10311040
.or(cfg.approval_policy)
@@ -1165,6 +1174,7 @@ impl Config {
11651174
cwd: resolved_cwd,
11661175
approval_policy,
11671176
sandbox_policy,
1177+
network_access,
11681178
did_user_set_custom_approval_policy_or_sandbox_mode,
11691179
forced_auto_mode_downgraded_on_windows,
11701180
shell_environment_policy,
@@ -1559,6 +1569,23 @@ trust_level = "trusted"
15591569
}
15601570
}
15611571

1572+
#[test]
1573+
fn network_access_override_is_loaded() -> std::io::Result<()> {
1574+
let codex_home = TempDir::new()?;
1575+
let config = Config::load_from_base_config_with_overrides(
1576+
ConfigToml {
1577+
network_access: Some(NetworkAccess::Restricted),
1578+
..Default::default()
1579+
},
1580+
ConfigOverrides::default(),
1581+
codex_home.path().to_path_buf(),
1582+
)?;
1583+
1584+
assert_eq!(config.network_access, Some(NetworkAccess::Restricted));
1585+
1586+
Ok(())
1587+
}
1588+
15621589
#[test]
15631590
fn add_dir_override_extends_workspace_writable_roots() -> std::io::Result<()> {
15641591
let temp_dir = TempDir::new()?;
@@ -2956,6 +2983,7 @@ model_verbosity = "high"
29562983
model_provider: fixture.openai_provider.clone(),
29572984
approval_policy: Constrained::allow_any(AskForApproval::Never),
29582985
sandbox_policy: SandboxPolicy::new_read_only_policy(),
2986+
network_access: None,
29592987
did_user_set_custom_approval_policy_or_sandbox_mode: true,
29602988
forced_auto_mode_downgraded_on_windows: false,
29612989
shell_environment_policy: ShellEnvironmentPolicy::default(),
@@ -3031,6 +3059,7 @@ model_verbosity = "high"
30313059
model_provider: fixture.openai_chat_completions_provider.clone(),
30323060
approval_policy: Constrained::allow_any(AskForApproval::UnlessTrusted),
30333061
sandbox_policy: SandboxPolicy::new_read_only_policy(),
3062+
network_access: None,
30343063
did_user_set_custom_approval_policy_or_sandbox_mode: true,
30353064
forced_auto_mode_downgraded_on_windows: false,
30363065
shell_environment_policy: ShellEnvironmentPolicy::default(),
@@ -3121,6 +3150,7 @@ model_verbosity = "high"
31213150
model_provider: fixture.openai_provider.clone(),
31223151
approval_policy: Constrained::allow_any(AskForApproval::OnFailure),
31233152
sandbox_policy: SandboxPolicy::new_read_only_policy(),
3153+
network_access: None,
31243154
did_user_set_custom_approval_policy_or_sandbox_mode: true,
31253155
forced_auto_mode_downgraded_on_windows: false,
31263156
shell_environment_policy: ShellEnvironmentPolicy::default(),
@@ -3197,6 +3227,7 @@ model_verbosity = "high"
31973227
model_provider: fixture.openai_provider.clone(),
31983228
approval_policy: Constrained::allow_any(AskForApproval::OnFailure),
31993229
sandbox_policy: SandboxPolicy::new_read_only_policy(),
3230+
network_access: None,
32003231
did_user_set_custom_approval_policy_or_sandbox_mode: true,
32013232
forced_auto_mode_downgraded_on_windows: false,
32023233
shell_environment_policy: ShellEnvironmentPolicy::default(),

0 commit comments

Comments
 (0)