mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Wire managed MITM CA trust into child env (#22668)
## Stack 1. Parent PR: #18240 uses named MITM permissions config. 2. This PR wires managed MITM CA trust into spawned child processes. ## Why When Codex terminates HTTPS for limited mode or MITM hooks, child HTTPS clients need to trust Codex's managed MITM CA. Exporting proxy URLs alone is not enough, but blindly replacing user CA settings would be wrong: it can break custom enterprise/test roots, leak unreadable CA files into generated bundles, or make the child env disagree with its sandbox policy. ## Summary 1. Build immutable managed CA bundles under `$CODEX_HOME/proxy` that include native roots, the managed MITM CA, and only inherited or command-scoped CA bundles the child is allowed to read. 2. Export curated CA env vars alongside managed proxy env vars while preserving user CA override semantics, including nested Codex `SSL_CERT_FILE` precedence. 3. Thread generated CA bundle paths into child sandbox readable roots, including debug sandbox execution, so the exported env vars work inside sandboxed commands. 4. Remove only Codex-generated MITM CA bundle env when a child intentionally drops managed proxying for escalation or no-proxy retry. 5. Document the managed CA bundle behavior and cover env injection, per-child bundle generation, sandbox readable roots, and no-proxy cleanup in tests. ## Validation 1. Ran `just test -p codex-network-proxy`. 2. Ran `just test -p codex-protocol`. 3. Ran `just fix -p codex-network-proxy -p codex-protocol`. 4. Tried focused `codex-core` validation, but the crate currently fails to compile in `core/tests/suite/guardian_review.rs` because an existing `Op::UserInput` initializer is missing `additional_context`. --------- Co-authored-by: Eva Wong <evawong@openai.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
b89bf1ef47
commit
bca18cba40
@@ -19,6 +19,7 @@ pub use manager::SandboxType;
|
||||
pub use manager::SandboxablePreference;
|
||||
pub use manager::compatibility_sandbox_policy_for_permission_profile;
|
||||
pub use manager::get_platform_sandbox;
|
||||
pub use manager::with_managed_mitm_ca_readable_root;
|
||||
|
||||
use codex_protocol::error::CodexErr;
|
||||
|
||||
|
||||
@@ -61,6 +61,27 @@ pub fn get_platform_sandbox(windows_sandbox_enabled: bool) -> Option<SandboxType
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_managed_mitm_ca_readable_root(
|
||||
permission_profile: PermissionProfile,
|
||||
managed_mitm_ca_trust_bundle_path: Option<&AbsolutePathBuf>,
|
||||
sandbox_policy_cwd: &Path,
|
||||
) -> PermissionProfile {
|
||||
let Some(managed_mitm_ca_trust_bundle_path) = managed_mitm_ca_trust_bundle_path else {
|
||||
return permission_profile;
|
||||
};
|
||||
let (file_system_sandbox_policy, network_sandbox_policy) =
|
||||
permission_profile.to_runtime_permissions();
|
||||
let file_system_sandbox_policy = file_system_sandbox_policy.with_additional_readable_roots(
|
||||
sandbox_policy_cwd,
|
||||
std::slice::from_ref(managed_mitm_ca_trust_bundle_path),
|
||||
);
|
||||
PermissionProfile::from_runtime_permissions_with_enforcement(
|
||||
permission_profile.enforcement(),
|
||||
&file_system_sandbox_policy,
|
||||
network_sandbox_policy,
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SandboxCommand {
|
||||
pub program: OsString,
|
||||
@@ -182,8 +203,15 @@ impl SandboxManager {
|
||||
windows_sandbox_private_desktop,
|
||||
} = request;
|
||||
let additional_permissions = command.additional_permissions.take();
|
||||
let managed_mitm_ca_trust_bundle_path =
|
||||
network.and_then(NetworkProxy::managed_mitm_ca_trust_bundle_path);
|
||||
let effective_permission_profile =
|
||||
effective_permission_profile(permissions, additional_permissions.as_ref());
|
||||
let effective_permission_profile = with_managed_mitm_ca_readable_root(
|
||||
effective_permission_profile,
|
||||
managed_mitm_ca_trust_bundle_path.as_ref(),
|
||||
sandbox_policy_cwd,
|
||||
);
|
||||
let (effective_file_system_policy, effective_network_policy) =
|
||||
effective_permission_profile.to_runtime_permissions();
|
||||
let mut argv = Vec::with_capacity(1 + command.args.len());
|
||||
|
||||
@@ -4,6 +4,7 @@ use super::SandboxTransformRequest;
|
||||
use super::SandboxType;
|
||||
use super::SandboxablePreference;
|
||||
use super::get_platform_sandbox;
|
||||
use super::with_managed_mitm_ca_readable_root;
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
use codex_protocol::models::AdditionalPermissionProfile;
|
||||
use codex_protocol::models::FileSystemPermissions;
|
||||
@@ -242,6 +243,48 @@ fn transform_additional_permissions_preserves_denied_entries() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn managed_mitm_ca_bundle_becomes_readable_for_restricted_sandbox() {
|
||||
let cwd = TempDir::new().expect("create cwd");
|
||||
let cwd =
|
||||
AbsolutePathBuf::from_absolute_path(canonicalize(cwd.path()).expect("canonicalize cwd"))
|
||||
.expect("absolute cwd");
|
||||
let managed_bundle_dir = TempDir::new().expect("create managed bundle dir");
|
||||
let managed_bundle_path =
|
||||
AbsolutePathBuf::from_absolute_path(managed_bundle_dir.path().join("ca-bundle.pem"))
|
||||
.expect("absolute managed bundle path");
|
||||
let permission_profile = PermissionProfile::from_runtime_permissions(
|
||||
&FileSystemSandboxPolicy::restricted(vec![FileSystemSandboxEntry {
|
||||
path: FileSystemPath::Path { path: cwd.clone() },
|
||||
access: FileSystemAccessMode::Read,
|
||||
}]),
|
||||
NetworkSandboxPolicy::Restricted,
|
||||
);
|
||||
|
||||
let permission_profile = with_managed_mitm_ca_readable_root(
|
||||
permission_profile,
|
||||
Some(&managed_bundle_path),
|
||||
cwd.as_path(),
|
||||
);
|
||||
let (file_system_sandbox_policy, _) = permission_profile.to_runtime_permissions();
|
||||
|
||||
assert_eq!(
|
||||
file_system_sandbox_policy,
|
||||
FileSystemSandboxPolicy::restricted(vec![
|
||||
FileSystemSandboxEntry {
|
||||
path: FileSystemPath::Path { path: cwd },
|
||||
access: FileSystemAccessMode::Read,
|
||||
},
|
||||
FileSystemSandboxEntry {
|
||||
path: FileSystemPath::Path {
|
||||
path: managed_bundle_path,
|
||||
},
|
||||
access: FileSystemAccessMode::Read,
|
||||
},
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn transform_linux_seccomp_request(
|
||||
codex_linux_sandbox_exe: &std::path::Path,
|
||||
|
||||
Reference in New Issue
Block a user