feat: add active network proxy guidance

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
viyatb-oai
2026-05-01 09:57:00 -07:00
co-authored by Codex
parent 6784db51c0
commit ba681f1296
6 changed files with 76 additions and 0 deletions
@@ -24,6 +24,7 @@ const APPROVAL_POLICY_ON_REQUEST_RULE: &str =
const APPROVAL_POLICY_ON_REQUEST_RULE_REQUEST_PERMISSION: &str =
include_str!("prompts/permissions/approval_policy/on_request_rule_request_permission.md");
const AUTO_REVIEW_APPROVAL_SUFFIX: &str = "`approvals_reviewer` is `auto_review`: Sandbox escalations with require_escalated will be reviewed for compliance with the policy. If a rejection happens, you should proceed only with a materially safer alternative, or inform the user of the risk and send a final message to ask for approval.";
const NETWORK_PROXY: &str = include_str!("prompts/permissions/network_proxy.md");
const SANDBOX_MODE_DANGER_FULL_ACCESS: &str =
include_str!("prompts/permissions/sandbox_mode/danger_full_access.md");
@@ -50,6 +51,7 @@ struct PermissionsPromptConfig<'a> {
exec_policy: &'a Policy,
exec_permission_approvals_enabled: bool,
request_permissions_tool_enabled: bool,
managed_network_proxy_active: bool,
}
#[derive(Debug, Clone, PartialEq)]
@@ -68,6 +70,7 @@ impl PermissionsInstructions {
cwd: &Path,
exec_permission_approvals_enabled: bool,
request_permissions_tool_enabled: bool,
managed_network_proxy_active: bool,
) -> Self {
let (sandbox_mode, writable_roots) = sandbox_prompt_from_profile(permission_profile, cwd);
@@ -80,6 +83,7 @@ impl PermissionsInstructions {
exec_policy,
exec_permission_approvals_enabled,
request_permissions_tool_enabled,
managed_network_proxy_active,
},
writable_roots,
)
@@ -94,6 +98,7 @@ impl PermissionsInstructions {
cwd: &Path,
exec_permission_approvals_enabled: bool,
request_permissions_tool_enabled: bool,
managed_network_proxy_active: bool,
) -> Self {
Self::from_permission_profile(
&PermissionProfile::from_legacy_sandbox_policy(sandbox_policy),
@@ -103,6 +108,7 @@ impl PermissionsInstructions {
cwd,
exec_permission_approvals_enabled,
request_permissions_tool_enabled,
managed_network_proxy_active,
)
}
@@ -114,6 +120,9 @@ impl PermissionsInstructions {
) -> Self {
let mut text = String::new();
append_section(&mut text, &sandbox_text(sandbox_mode, network_access));
if config.managed_network_proxy_active {
append_section(&mut text, NETWORK_PROXY.trim_end());
}
append_section(
&mut text,
&approval_text(
@@ -38,6 +38,7 @@ fn builds_permissions_with_network_access_override() {
exec_policy: &Policy::empty(),
exec_permission_approvals_enabled: false,
request_permissions_tool_enabled: false,
managed_network_proxy_active: false,
},
/*writable_roots*/ None,
);
@@ -70,6 +71,7 @@ fn builds_permissions_from_policy() {
&PathBuf::from("/tmp"),
/*exec_permission_approvals_enabled*/ false,
/*request_permissions_tool_enabled*/ false,
/*managed_network_proxy_active*/ false,
);
let text = instructions.body();
assert!(text.contains("Network access is enabled."));
@@ -99,6 +101,7 @@ fn builds_permissions_from_profile() {
&cwd,
/*exec_permission_approvals_enabled*/ false,
/*request_permissions_tool_enabled*/ false,
/*managed_network_proxy_active*/ false,
);
let text = instructions.body();
assert!(text.contains("`sandbox_mode` is `workspace-write`"));
@@ -106,6 +109,47 @@ fn builds_permissions_from_profile() {
assert!(text.contains(writable_root.to_string_lossy().as_ref()));
}
#[test]
fn includes_network_proxy_guidance_when_managed_proxy_is_active() {
let instructions = PermissionsInstructions::from_permissions_with_network(
SandboxMode::WorkspaceWrite,
NetworkAccess::Restricted,
PermissionsPromptConfig {
approval_policy: AskForApproval::Never,
approvals_reviewer: ApprovalsReviewer::User,
exec_policy: &Policy::empty(),
exec_permission_approvals_enabled: false,
request_permissions_tool_enabled: false,
managed_network_proxy_active: true,
},
/*writable_roots*/ None,
);
let text = instructions.body();
assert!(text.contains("# Network Proxy"));
assert!(text.contains("blocked-by-allowlist"));
assert!(text.contains("proxy-specific headers or messages"));
}
#[test]
fn omits_network_proxy_guidance_when_managed_proxy_is_inactive() {
let instructions = PermissionsInstructions::from_permissions_with_network(
SandboxMode::WorkspaceWrite,
NetworkAccess::Restricted,
PermissionsPromptConfig {
approval_policy: AskForApproval::Never,
approvals_reviewer: ApprovalsReviewer::User,
exec_policy: &Policy::empty(),
exec_permission_approvals_enabled: false,
request_permissions_tool_enabled: false,
managed_network_proxy_active: false,
},
/*writable_roots*/ None,
);
assert!(!instructions.body().contains("# Network Proxy"));
}
#[test]
fn includes_request_rule_instructions_for_on_request() {
let mut exec_policy = Policy::empty();
@@ -121,6 +165,7 @@ fn includes_request_rule_instructions_for_on_request() {
exec_policy: &exec_policy,
exec_permission_approvals_enabled: false,
request_permissions_tool_enabled: false,
managed_network_proxy_active: false,
},
/*writable_roots*/ None,
);
@@ -142,6 +187,7 @@ fn includes_request_permissions_tool_instructions_for_unless_trusted_when_enable
exec_policy: &Policy::empty(),
exec_permission_approvals_enabled: false,
request_permissions_tool_enabled: true,
managed_network_proxy_active: false,
},
/*writable_roots*/ None,
);
@@ -162,6 +208,7 @@ fn includes_request_permissions_tool_instructions_for_on_failure_when_enabled()
exec_policy: &Policy::empty(),
exec_permission_approvals_enabled: false,
request_permissions_tool_enabled: true,
managed_network_proxy_active: false,
},
/*writable_roots*/ None,
);
@@ -182,6 +229,7 @@ fn includes_request_permission_rule_instructions_for_on_request_when_enabled() {
exec_policy: &Policy::empty(),
exec_permission_approvals_enabled: true,
request_permissions_tool_enabled: false,
managed_network_proxy_active: false,
},
/*writable_roots*/ None,
);
@@ -202,6 +250,7 @@ fn includes_request_permissions_tool_instructions_for_on_request_when_tool_is_en
exec_policy: &Policy::empty(),
exec_permission_approvals_enabled: false,
request_permissions_tool_enabled: true,
managed_network_proxy_active: false,
},
/*writable_roots*/ None,
);
@@ -222,6 +271,7 @@ fn on_request_includes_tool_guidance_alongside_inline_permission_guidance_when_b
exec_policy: &Policy::empty(),
exec_permission_approvals_enabled: true,
request_permissions_tool_enabled: true,
managed_network_proxy_active: false,
},
/*writable_roots*/ None,
);
@@ -0,0 +1,14 @@
# Network Proxy
A managed network proxy is active for model-initiated shell commands. Codex applies proxy environment variables automatically so outbound traffic is checked against the configured network policy.
Honor any `<network>` allow/deny entries in the environment context. Use normal network tools without clearing or overriding proxy-related environment variables. If a required host is not allowed, request additional network permissions instead of working around the proxy.
Interpret proxy failures precisely:
- `blocked-by-allowlist` means the host is not allowed by the current network policy.
- `blocked-by-denylist` means the host is explicitly denied by policy.
- `blocked-by-method-policy` means the current network mode disallows that request method.
- `blocked-by-mitm-required` means limited HTTPS cannot be enforced for that request without MITM support.
- A message about local/private network addresses means the sandbox is blocking local or private targets.
Do not infer a proxy denial from a generic network failure alone. Timeouts, hangs, DNS errors, TLS errors, and connection failures are only evidence of proxy policy when accompanied by proxy-specific headers or messages.
@@ -64,6 +64,7 @@ fn build_permissions_update_item(
&next.cwd,
next.features.enabled(Feature::ExecPermissionApprovals),
next.features.enabled(Feature::RequestPermissionsTool),
next.network.is_some(),
)
.render(),
)
+1
View File
@@ -2579,6 +2579,7 @@ impl Session {
turn_context
.features
.enabled(Feature::RequestPermissionsTool),
turn_context.network.is_some(),
)
.render(),
);
@@ -583,6 +583,7 @@ async fn permissions_message_includes_writable_roots() -> Result<()> {
test.config.cwd.as_path(),
/*exec_permission_approvals_enabled*/ false,
/*request_permissions_tool_enabled*/ false,
/*managed_network_proxy_active*/ false,
)
.render();
let expected_normalized = normalize_line_endings(&expected);