mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
Migrate the Windows MXC sandbox to split MXC crates (#52707)
## Why PSEC API symbols can be present on transitional Windows builds where MXC is not enabled. Availability detection needs to verify that a native process security environment can actually be created. ## What changed - Replace `mxc-sdk` with pinned `appcontainer_common`, `learning_mode_windows`, and `wxc_common` dependencies, and update Cargo and Bazel dependency metadata. - Use MXC's cached create/close probe for `is_available()` and query native deny-path support through `SecurityEnvironmentApi` before launching requests with denied paths. - Adapt request construction and the existing policy test to the vector-based environment field, and update the sandbox documentation. GitOrigin-RevId: e8cc6a35d46884d0a069b747d33e711512ec1596
This commit is contained in:
Generated
+102
-44
@@ -303,6 +303,27 @@ dependencies = [
|
||||
"wiremock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "appcontainer_common"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4"
|
||||
dependencies = [
|
||||
"flatbuffers",
|
||||
"getrandom 0.2.17",
|
||||
"learning_mode_core",
|
||||
"learning_mode_windows",
|
||||
"process_security_environment_spec",
|
||||
"sandbox_spec",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.18",
|
||||
"widestring",
|
||||
"windows 0.62.2",
|
||||
"windows-core 0.62.2",
|
||||
"winreg 0.55.0",
|
||||
"wxc_common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.5.1"
|
||||
@@ -4108,12 +4129,13 @@ name = "codex-mxc-sandbox"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"appcontainer_common",
|
||||
"codex-network-proxy",
|
||||
"codex-protocol",
|
||||
"codex-utils-absolute-path",
|
||||
"codex-utils-path-uri",
|
||||
"codex-windows-sandbox",
|
||||
"mxc-sdk",
|
||||
"learning_mode_windows",
|
||||
"pretty_assertions",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -4121,6 +4143,7 @@ dependencies = [
|
||||
"thiserror 2.0.18",
|
||||
"tracelogging",
|
||||
"windows-sys 0.61.2",
|
||||
"wxc_common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5481,12 +5504,6 @@ version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
|
||||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
|
||||
|
||||
[[package]]
|
||||
name = "const_format"
|
||||
version = "0.2.35"
|
||||
@@ -6247,7 +6264,7 @@ version = "0.7.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
|
||||
dependencies = [
|
||||
"const-oid 0.9.6",
|
||||
"const-oid",
|
||||
"pem-rfc7468",
|
||||
"zeroize",
|
||||
]
|
||||
@@ -6391,7 +6408,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer 0.10.4",
|
||||
"const-oid 0.9.6",
|
||||
"const-oid",
|
||||
"crypto-common 0.1.7",
|
||||
"subtle",
|
||||
]
|
||||
@@ -6403,7 +6420,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
|
||||
dependencies = [
|
||||
"block-buffer 0.12.0",
|
||||
"const-oid 0.10.2",
|
||||
"crypto-common 0.2.2",
|
||||
"ctutils",
|
||||
]
|
||||
@@ -9881,6 +9897,32 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "learning_mode_core"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.9",
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "learning_mode_windows"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4"
|
||||
dependencies = [
|
||||
"learning_mode_core",
|
||||
"sha2 0.10.9",
|
||||
"thiserror 2.0.18",
|
||||
"windows 0.62.2",
|
||||
"windows-core 0.62.2",
|
||||
"wxc_common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leb128fmt"
|
||||
version = "0.1.0"
|
||||
@@ -10349,37 +10391,22 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mxc-sdk"
|
||||
version = "1.0.0"
|
||||
source = "git+https://github.com/microsoft/mxc?rev=a846837d827b496fc4a08dfe60554515758c6647#a846837d827b496fc4a08dfe60554515758c6647"
|
||||
name = "mxc_config_contract"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.22.1",
|
||||
"cc",
|
||||
"chrono",
|
||||
"cidr",
|
||||
"flatbuffers",
|
||||
"getrandom 0.2.17",
|
||||
"libc",
|
||||
"nix 0.29.0",
|
||||
"same-file",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_path_to_error",
|
||||
"sha2 0.11.0",
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mxc_telemetry"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4"
|
||||
dependencies = [
|
||||
"tracelogging",
|
||||
"unicode-general-category",
|
||||
"url",
|
||||
"uuid",
|
||||
"widestring",
|
||||
"windows 0.62.2",
|
||||
"windows-core 0.62.2",
|
||||
"winreg 0.55.0",
|
||||
"winresource",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -11880,6 +11907,14 @@ dependencies = [
|
||||
"windows 0.62.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "process_security_environment_spec"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4"
|
||||
dependencies = [
|
||||
"flatbuffers",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prodash"
|
||||
version = "31.0.0"
|
||||
@@ -13628,6 +13663,14 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sandbox_spec"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4"
|
||||
dependencies = [
|
||||
"flatbuffers",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sansio"
|
||||
version = "1.0.1"
|
||||
@@ -17486,15 +17529,6 @@ dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winresource"
|
||||
version = "0.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0986a8b1d586b7d3e4fe3d9ea39fb451ae22869dcea4aa109d287a374d866087"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winsafe"
|
||||
version = "0.0.19"
|
||||
@@ -17642,6 +17676,30 @@ version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9"
|
||||
|
||||
[[package]]
|
||||
name = "wxc_common"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/microsoft/mxc?rev=6cd3d58f05d3447e67109cfb75e042803b843ca4#6cd3d58f05d3447e67109cfb75e042803b843ca4"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"cidr",
|
||||
"getrandom 0.2.17",
|
||||
"libc",
|
||||
"mxc_config_contract",
|
||||
"mxc_telemetry",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_path_to_error",
|
||||
"thiserror 2.0.18",
|
||||
"unicode-general-category",
|
||||
"url",
|
||||
"widestring",
|
||||
"windows 0.62.2",
|
||||
"windows-core 0.62.2",
|
||||
"winreg 0.55.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11rb"
|
||||
version = "0.13.2"
|
||||
|
||||
+3
-1
@@ -320,9 +320,12 @@ codex-windows-sandbox-test-support = { path = "windows-sandbox-rs/tests/support"
|
||||
core_test_support = { path = "core/tests/common" }
|
||||
|
||||
# External
|
||||
learning_mode_windows = { git = "https://github.com/microsoft/mxc", rev = "6cd3d58f05d3447e67109cfb75e042803b843ca4" }
|
||||
wxc_common = { git = "https://github.com/microsoft/mxc", rev = "6cd3d58f05d3447e67109cfb75e042803b843ca4" }
|
||||
age = "0.12.1"
|
||||
ansi-to-tui = "8.0.1"
|
||||
anyhow = "1"
|
||||
appcontainer_common = { git = "https://github.com/microsoft/mxc", rev = "6cd3d58f05d3447e67109cfb75e042803b843ca4" }
|
||||
arboard = { version = "3", features = ["wayland-data-control"] }
|
||||
arc-swap = "1.9.0"
|
||||
assert_cmd = "2"
|
||||
@@ -409,7 +412,6 @@ maplit = "1.0.2"
|
||||
memchr = "2.7.6"
|
||||
mime_guess = "2.0.5"
|
||||
multimap = "0.10.0"
|
||||
mxc-sdk = { git = "https://github.com/microsoft/mxc", rev = "a846837d827b496fc4a08dfe60554515758c6647" }
|
||||
notify = "8.2.0"
|
||||
nucleo = { git = "https://github.com/helix-editor/nucleo.git", rev = "4253de9faabb4e5c6d81d946a5e35a90f87347ee" }
|
||||
once_cell = "1.20.2"
|
||||
|
||||
@@ -21,12 +21,14 @@ codex-protocol = { workspace = true }
|
||||
codex-utils-absolute-path = { workspace = true }
|
||||
codex-utils-path-uri = { workspace = true }
|
||||
codex-windows-sandbox = { workspace = true }
|
||||
mxc-sdk = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
wxc_common = { workspace = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
appcontainer_common = { workspace = true }
|
||||
learning_mode_windows = { workspace = true }
|
||||
# 1.2.4 imports OneCore_apiset, which the GNU Windows toolchain does not ship.
|
||||
tracelogging = "=1.2.3"
|
||||
windows-sys = { workspace = true, features = [
|
||||
|
||||
@@ -10,11 +10,11 @@ Windows executors record `codex.windows_mxc.available` once per process with an
|
||||
`available=true|false` tag. This measures runtime availability independently of
|
||||
selection. Unsupported Windows executors reject MXC requests before execution.
|
||||
|
||||
`is_available()` uses MXC's cached PSEC API-set check. The SDK validates native
|
||||
creation and capabilities for each request at launch. Its broad
|
||||
`platform_support()` result also includes older AppContainer backends and is not
|
||||
used here. A requested deny path requires native `PSE_SUPPORT_FS_DENY` support;
|
||||
host-loopback ingress requires PSEC 1.1 and native ingress support.
|
||||
`is_available()` uses MXC's cached create/close probe, rather than an OS build
|
||||
number or the SDK's broad `platform_support()` result. The latter also reports
|
||||
older AppContainer backends as supported. A requested deny path additionally
|
||||
requires the native `PSE_SUPPORT_FS_DENY` capability; otherwise the command
|
||||
fails before launch.
|
||||
|
||||
The wrapper inherits the command's pipes or ConPTY console. MXC creates its
|
||||
child suspended, assigns a kill-on-close job before resuming it, and retains
|
||||
@@ -70,9 +70,8 @@ to 4096 bytes; the helper removes them before native process creation. Use
|
||||
command are not implicitly granted.
|
||||
- The native API represents paths and environment values as Unicode strings.
|
||||
Non-Unicode values fail instead of undergoing lossy conversion.
|
||||
- An empty child environment uses the Windows user-profile defaults, preserving
|
||||
the previous SDK behavior. Nonempty environments remain explicit; the SDK now
|
||||
requires `SystemRoot` and `LOCALAPPDATA` before launch.
|
||||
- An empty child environment uses the Windows user-profile defaults. Nonempty
|
||||
environments remain explicit.
|
||||
- The upstream runner terminates remaining descendants when the foreground
|
||||
process exits, as well as on cancellation. Both existing Windows backends
|
||||
preserve descendants after normal exit, so detached servers currently lose
|
||||
@@ -87,10 +86,6 @@ to 4096 bytes; the helper removes them before native process creation. Use
|
||||
suite on supported Windows and the corresponding platform hosts.
|
||||
Test the normal `powershell.exe` and `pwsh.exe` command paths, not only `cmd.exe`.
|
||||
|
||||
The MXC 1.0.0 Git revision is pinned with the workspace dependencies.
|
||||
Native launch errors are returned without dumping the SDK's diagnostic buffer,
|
||||
which may contain command or environment data.
|
||||
|
||||
Cargo builds on Windows GNU targets require `RC_PATH` to point to `rc.exe` or
|
||||
`llvm-rc.exe`; the SDK's automatic resource compiler lookup supports MSVC only.
|
||||
Bazel supplies its hermetic LLVM resource compiler.
|
||||
The MXC git revision is pinned with the workspace dependencies. Native launch
|
||||
errors are returned without dumping the SDK's diagnostic buffer, which may
|
||||
contain command or environment data.
|
||||
|
||||
@@ -86,12 +86,12 @@ pub fn create_command_args(args: CreateMxcCommandArgsParams<'_>) -> Result<Vec<S
|
||||
Ok(vec![CODEX_WINDOWS_MXC_ARG1.to_owned()])
|
||||
}
|
||||
|
||||
/// Whether the executor exposes MXC's process security-environment API set.
|
||||
/// Whether the executor can create a native MXC process security environment.
|
||||
/// This deliberately excludes MXC's older AppContainer fallback backends.
|
||||
pub fn is_available() -> bool {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
mxc_sdk::process_container_common::base_container_runner::BaseContainerRunner::is_base_container_api_present()
|
||||
appcontainer_common::base_container_runner::BaseContainerRunner::is_process_security_environment_usable()
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
use anyhow::ensure;
|
||||
use mxc_sdk::mxc_common as wxc_common;
|
||||
use mxc_sdk::process_container_common::base_container_runner::BaseContainerRunner;
|
||||
use appcontainer_common::base_container_runner::BaseContainerRunner;
|
||||
use learning_mode_windows::SecurityEnvironmentApi;
|
||||
use wxc_common::logger::Logger;
|
||||
use wxc_common::logger::Mode;
|
||||
use wxc_common::models::ExecutionRequest;
|
||||
@@ -25,9 +25,11 @@ pub(super) fn launch(request: &ExecutionRequest) -> Result<i32> {
|
||||
.any(|capability| capability.eq_ignore_ascii_case("permissiveLearningMode")),
|
||||
"MXC native launch does not support permissiveLearningMode"
|
||||
);
|
||||
// With no least-privilege mode, legacy proxy, or capture enabled, this
|
||||
// probe guarantees BaseContainerRunner chooses PSEC rather than SBOX.
|
||||
if !request.policy.denied_paths.is_empty() {
|
||||
ensure!(
|
||||
BaseContainerRunner::supports_native_denied_paths(),
|
||||
SecurityEnvironmentApi::load()?.supports_deny_paths()?,
|
||||
"this Windows build cannot enforce native MXC deny paths"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ use codex_protocol::protocol::FileSystemSpecialPath;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use codex_utils_path_uri::PathUri;
|
||||
use codex_windows_sandbox::resolve_windows_deny_read_paths;
|
||||
use mxc_sdk::mxc_common as wxc_common;
|
||||
use thiserror::Error;
|
||||
use wxc_common::cmdline::CommandLineContext;
|
||||
use wxc_common::cmdline::CommandLineError;
|
||||
@@ -275,7 +274,7 @@ pub(super) fn build_request(
|
||||
.to_str()
|
||||
.ok_or(PolicyError::NonUnicodeCommandCwd)?
|
||||
.to_owned(),
|
||||
env: (!env.is_empty()).then_some(env),
|
||||
env,
|
||||
policy: ContainerPolicy {
|
||||
capabilities: vec!["registryRead".to_owned()],
|
||||
readwrite_paths: unicode_paths(write)?,
|
||||
|
||||
@@ -16,7 +16,6 @@ use codex_protocol::protocol::FileSystemSpecialPath;
|
||||
use codex_protocol::protocol::NetworkSandboxPolicy;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use codex_utils_path_uri::PathUri;
|
||||
use mxc_sdk::mxc_common as wxc_common;
|
||||
use pretty_assertions::assert_eq;
|
||||
use wxc_common::models::NetworkAction;
|
||||
use wxc_common::models::NetworkCidr;
|
||||
@@ -197,13 +196,9 @@ fn wrapper_preserves_exact_argv_and_separate_command_cwd() -> Result<()> {
|
||||
(
|
||||
r#""C:\Program Files\tool.exe" --permissions "" "quotes\" and slash\\""#.to_owned(),
|
||||
cwd.to_str().unwrap().to_owned(),
|
||||
Some(vec!["CUSTOM=value".to_owned()]),
|
||||
vec!["CUSTOM=value".to_owned()],
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
build_request(&parsed, &cwd, Vec::new(), &[], &[])?.env,
|
||||
None,
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ use std::sync::atomic::Ordering;
|
||||
static AVAILABILITY_RECORDED: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
pub(super) fn record_availability_once() {
|
||||
// Record the SDK's cached PSEC API-set check. Creation and request-specific
|
||||
// capability checks happen when launching the MXC command.
|
||||
// Probe actual PSEC create/close support; symbol presence alone also
|
||||
// succeeds on transitional Windows builds where MXC is not enabled.
|
||||
let available = codex_mxc_sandbox::is_available();
|
||||
if let Some(metrics) = codex_otel::global()
|
||||
&& !AVAILABILITY_RECORDED.swap(true, Ordering::Relaxed)
|
||||
|
||||
Reference in New Issue
Block a user