Commit Graph

98 Commits

Author SHA1 Message Date
iceweasel-oai
60888d0868 Add a native Windows MXC sandbox adapter (#42841)
## What changed

- Add `codex-mxc-sandbox` with native MXC availability detection and a launcher that inherits standard I/O and waits for the sandboxed process.
- Reject unsupported learning-mode and fallback policies, and verify deny-path support before launch.
- Route the existing Windows MXC availability metric through the new crate and move its Windows linking dependencies alongside the adapter.

GitOrigin-RevId: e2a220b85718e00b0e710c30bbe66b6c56958176
2026-09-04 20:09:04 +00:00
zm-oai
f1aac1e885 Preserve SystemRoot for Windows sandbox wrapper setup (#42833)
## Why

`ShellExecuteExW` needs `SystemRoot` to elevate the Windows sandbox setup helper.

## What changed

Add `SYSTEMROOT` to the environment variables copied from the host for wrapper
setup. Keep the serialized inner command environment unchanged so the host value
is available only to the wrapper.

## Testing

Extend Windows sandbox manager tests to cover case-insensitive replacement of
`SystemRoot` and verify that it is excluded from the inner command environment.

GitOrigin-RevId: c69f9f92665e97a178e2de488fbb9fd6b7ff7ac6
2026-09-04 19:22:34 +00:00
jif
d13aeb77ea Allow trusted symlinks beneath CODEX_HOME on macOS (#42716)
## What changed

- Add the macOS-only `allow_symlinked_codex_home` user setting. When enabled in the execution host's `$CODEX_HOME/config.toml`, writable roots at or beneath that home may traverse symlinks.
- Keep the exception disabled by default and prevent project config, command-line overrides, and ignored user config from enabling it. Other writable roots remain subject to symlink checks.
- Propagate the resolved setting through local, interactive, and exec-server sandbox paths, including `CODEX_HOME` aliases.
- Explain the opt-out in symlink rejection errors, including that it trusts targets outside `CODEX_HOME` and targets that change between commands.

## Testing

- Add macOS coverage for shell commands, patches, filesystem helpers, process execution, and interactive startup with enabled, disabled, aliased, and out-of-scope homes.

GitOrigin-RevId: 99fcdf611200c9e1b7713cf06f7fdea5bfa7f089
2026-09-04 10:12:03 +00:00
iceweasel-oai
f60dfe80b5 Record Windows sandbox private desktop usage (#42596)
## What changed

Increment the `codex.windows_sandbox.private_desktop` counter when preparing a
Windows restricted-token sandbox execution, tagging it with whether private
desktop isolation is enabled.

GitOrigin-RevId: 1eb5e183b57e19753dc133dbe152eabe23dd2a23
2026-09-03 18:25:13 +00:00
iceweasel-oai
7a7c188682 Preserve target-native paths in command approvals (#42577)
## What changed

- Pass the selected executor's `PathUri` through user command approval requests instead of converting the working directory to a host-native path.
- Make native-path permission helpers explicitly local and require executor-aware permission transforms to receive a `FileSystemSandboxPolicyContext`.
- Cover approved remote commands to verify that the approval request reports the selected remote working directory and execution resumes after approval.

GitOrigin-RevId: 0aa3042f2d7594af6c7d0abf31d7f99cf67d5556
2026-09-03 16:21:10 +00:00
iceweasel-oai
cd8bd62c6e Resolve permission requests in the executor context (#42146)
## Why

`request_permissions` paths and grants need to be evaluated against the selected executor environment, including its path convention, home directory, workspace roots, and temporary directories.

## What changed

- Resolve relative and home-relative permission paths using the executor context, reject mismatched path conventions and lossy paths, and support legacy `read` and `write` path lists.
- Move grant intersection into core so requested and granted permissions use the originating environment's sandbox context. Preserve deny entries conservatively when a special path cannot be resolved.
- Keep the full originating environment with pending permission requests so delayed responses are normalized against the same context.

## Testing

- Cover POSIX, Windows, UNC, relative, and home-relative path resolution and invalid path contexts.
- Verify end-to-end app-server grants are limited to the requested workspace scope and unresolved temporary-directory denies are preserved.

GitOrigin-RevId: 730a2aacd391262e92a6314f3a5b6c262e3dca10
2026-09-01 22:08:08 +00:00
iceweasel-oai
ade0ccacf9 Record Windows MXC availability (#42094)
## What changed

- Probe whether the native Windows MXC process security environment is usable
  when selecting a sandbox.
- Emit `codex.windows_mxc.available` at most once per process, labeled with the
  probe result.
- Add the MXC workspace dependencies for Cargo and Bazel, and pin
  `tracelogging` to a version compatible with the GNU Windows toolchain.

GitOrigin-RevId: d7cfeed6f0333feda5764e1ee44fe5bbd50f9a58
2026-09-01 16:40:05 +00:00
iceweasel-oai
c4350b4ca2 Use executor path context for permission preapproval (#41928)
## Why

Permission grants can belong to an executor whose path convention differs from
the local host, such as a Windows remote environment. Matching those grants
against a host-native working directory can reject valid permissions.

## What changed

- Normalize, materialize, and compare additional filesystem permissions using
  the selected executor's URI-based sandbox context.
- Apply the same context-aware preapproval flow to `exec_command`,
  `apply_patch`, and extension tools.
- Fail closed when symbolic temporary-directory or project-root permissions
  cannot be resolved from executor metadata, while accepting opaque working
  directory URIs when requested paths use the executor's convention.

## Testing

- Added coverage for reusing a Windows permission grant from a non-Windows
  host, resolving symbolic temporary-directory grants, and normalizing paths
  with an opaque Windows working directory.

GitOrigin-RevId: aee54350a25430a0443f8319e2bb0bbdc4f44282
2026-08-31 22:58:26 +00:00
iceweasel-oai
b51b07785b Make permission transforms aware of executor path context (#41909)
## What changed

- Add context-aware normalization, materialization, and intersection helpers for additional filesystem permissions.
- Resolve project roots, home-relative deny globs, temporary directories, and filesystem roots from the executor's `FileSystemSandboxPolicyContext` while preserving URI path conventions and symlinked paths.
- Keep deny constraints when intersecting grants across POSIX, Windows, and UNC paths, and reject incompatible path conventions when executor context is available.

## Testing

- Cover cross-convention validation, empty temporary-directory contexts, home-relative deny globs, and rooted deny globs for POSIX, Windows, and UNC paths.

GitOrigin-RevId: 14fd866a17a0ac4a595aa4f0e2fb82bfae1a8838
2026-08-31 20:50:44 +00:00
ted nyman
75388bf321 Rename the read-only Seatbelt platform defaults policy (#41449)
GitOrigin-RevId: b0c22d9bf9e276023d2ddd943489e51ee8bb200f
2026-08-29 02:49:33 +00:00
Eric Traut
0ae94fdd49 Respond to terminal queries from TTY subprocesses (#41436)
## Why

Programs running in a PTY can block while waiting for replies to terminal
queries.

## What changed

- Intercept device-status, window-size, cursor-position, and DEC private-mode
  queries from TTY subprocess output and write bounded responses to the
  subprocess input.
- Remove handled queries from the output stream while preserving other escape
  sequences and output, including queries split across chunks.
- Apply the responder to both direct and driver-backed TTY process spawning.

## Testing

Added tests for driver-backed query handling and for a PTY subprocess that
waits for a cursor-position response before exiting.

GitOrigin-RevId: de92e06d183647271ef49024da9c30f01699f886
2026-08-28 23:34:37 +00:00
iceweasel-oai
2926014075 Make filesystem policy matching URI-native (#41001)
## Why

Filesystem policies can describe paths using a convention that differs from the
host running Codex. Native path comparisons can therefore mis-handle cases such
as case-variant Windows paths or ambiguous encoded components.

## What changed

- Resolve policy entries and special roots as `PathUri` values using the
  executor's path convention.
- Use validated URI components for containment, overlap, and precedence, and
  fail closed when component boundaries are ambiguous.
- Restrict relative joins to descendants and apply the same matching rules to
  protected metadata paths and permission-profile intersections.

## Testing

Added coverage for Windows case variants, encoded and opaque paths, repeated
separators, descendant joins, special roots, metadata protection, and preserved
deny entries.

GitOrigin-RevId: fb09d44d11df25faaac806fe00457e6f6b0d8596
2026-08-26 23:49:05 +00:00
dank-openai
7f82397363 Restrict macOS scratch access to process sandboxes (#40961)
## Why

Filesystem helpers should not inherit access to system scratch directories beyond the paths granted by their filesystem policy, while ordinary processes still need scratch access for compatibility.

## What changed

- Move the `/tmp` and `/var/tmp` read/write grants, including their `/private` aliases, from the shared platform defaults into the process-only Seatbelt defaults.
- Keep process access to `/Applications` alongside the scratch-directory grants.

## Testing

Add a macOS Seatbelt test that verifies the generated policies and, when nested Seatbelt execution is available, confirms process scratch access, helper denial, and helper access to an approved project path.

GitOrigin-RevId: 26d83f09c131c1f1d000163b2f8929f601749719
2026-08-26 19:38:42 +00:00
Adam Perry @ OpenAI
8444cf63b5 Derive sandbox contexts from turn environments (#40551)
## What changed

- Add Windows sandbox mode, private-desktop behavior, and legacy Landlock selection to each `EnvironmentConfig`.
- Centralize sandbox context construction on `TurnEnvironment`, preserving environment-owned permissions, paths, and backend settings while applying additional permission grants.
- Use the environment-derived context for project instructions, capability discovery, file uploads, and filesystem-oriented tools.

## Testing

- Verify capability discovery uses the selected environment's permission profile and sandbox backends when they differ from the thread defaults.

GitOrigin-RevId: 7ae2fed90c8ada950f2e8431e571e9b2c793c291
2026-08-25 05:16:45 +00:00
viyatb-oai
696b4502df Allow semaphore limit queries in the macOS sandbox (#39976)
## Why

Python's `ProcessPoolExecutor` queries `SEM_NSEMS_MAX` through `sysconf`, which reads the `kern.sysv.semmns` sysctl on macOS.

## What changed

- Allow reads of `kern.sysv.semmns` in the base Seatbelt policy.
- Verify `/usr/bin/getconf SEM_NSEMS_MAX` succeeds with both read-only and workspace-write sandbox policies.

GitOrigin-RevId: ab3ae92dc8991729f90a47c1994eedb6c7a2b9cd
2026-08-21 17:16:51 +00:00
Jeremy Rose
21facf2273 Restrict macOS preference reads to full-disk policies (#39811)
## Why

The macOS preferences service can expose data outside a sandbox's allowed
filesystem read roots.

## What changed

- Move the Seatbelt preference and `cfprefsd` grants into a separate policy
  section that is included only when filesystem reads are unrestricted.
- Remove the equivalent grants from the restricted platform defaults.

## Testing

- Verify both Seatbelt profiles include preference grants only for full-disk
  read policies, including policies with denied paths or globs.
- Verify a restricted sandbox cannot retrieve a preference whose plist is
  denied, while an unrestricted read policy can.

GitOrigin-RevId: 90388366a7302bca1830ad0439544be8babc7321
2026-08-20 23:18:55 +00:00
jif
02de49f718 Harden Seatbelt writable root path binding (#39706)
## Why

Resolving attacker-mutable path components while preparing a Seatbelt profile can let a writable root be rebound to a different location before the sandbox is applied. File roots also need to remain confined to the file itself rather than granting access to descendants after replacement.

## What changed

- Preserve mutable components of writable-root paths until Seatbelt binds them, while still normalizing trusted top-level aliases such as `/tmp`.
- Use literal grants for existing file and device roots, and subpath grants for directories and missing roots.
- Exclude both logical and resolved forms of protected subpaths so symlinked metadata directories remain read-only.

## Testing

Add coverage for ancestor rebinding, file-root symlink and directory replacement, missing directory roots, top-level aliases, and symlinked metadata carveouts.

GitOrigin-RevId: 63c00e44dd30766e873b8acdad09d6657657fad9
2026-08-20 12:08:35 +00:00
Dylan Hurd
52e387daca Prevent protected-path rename bypasses in macOS Seatbelt (#39623)
## Why

Renaming a writable directory could move protected descendants outside the
paths covered by their read-only or unreadable policy entries.

## What changed

- Deny unlink-style writes to directory ancestors of protected paths, placing
  these rules after broader write allowances in the generated Seatbelt policy.
- Apply full write denies to unreadable glob matches and protect their directory
  ancestors against renames.
- Support brace alternation and backslash escapes when translating filesystem
  globs into Seatbelt regular expressions.

## Testing

Add coverage for ancestor rename attempts across explicit read-only and deny
entries, multiple glob forms, canonicalized glob paths, and the new glob syntax.

GitOrigin-RevId: edfda9d4c2bc7ba2ecd6b67744446871e526084f
2026-08-20 06:47:30 +00:00
jif
f6950546e5 Protect macOS Seatbelt writable root anchors (#39599)
## Why

A sandboxed process could replace a writable directory root, changing the
authority boundary used to construct a later sandbox policy.

## What changed

- Deny unlinking or renaming directory roots granted write access by Seatbelt,
  while preserving replacement and deletion behavior for writable files.
- Reject writable roots with nested symlink components and report these as
  Seatbelt preparation errors instead of network proxy failures.
- Normalize writable roots before adding them to the generated Seatbelt policy.

## Testing

Add coverage for symlink rejection, error classification, directory-root
replacement and rename protection, newly created roots, and writable file
replacement.

GitOrigin-RevId: ab1ed4e55f20034bc43e028e6529d3d1f0d8181c
2026-08-20 05:36:23 +00:00
Dylan Hurd
d68b85a097 Require fresh approval beneath denied permission paths (#39266)
## Why

A stored permission grant may allow access to a parent while explicitly denying
a child path. A later request for that child must not be treated as already
approved by the broader parent grant.

## What changed

- Compare materialized permission profiles without intersecting away denied or
  reopened paths before deciding that a request is preapproved.
- Execute preapproved commands with the stored grant itself so its denied paths
  remain enforced.
- Fail closed when permission profiles cannot be materialized.

## Testing

Added unit and integration coverage for turn and session grants across
`exec_command`, `shell_command`, and `apply_patch`, including approval-disabled
and `Never` approval modes.

GitOrigin-RevId: 5455880328a89c7958f859c7ce87805dff9704fb
2026-08-18 19:17:09 +00:00
iceweasel-oai
2013e04354 Preserve filesystem permission path conventions (#39084)
## Why

Filesystem permission paths can use a convention that differs from the host
running Codex. Converting them immediately to native absolute paths can change
the meaning of ambiguous paths such as `/C:/secret` or Windows UNC paths.

## What changed

- Store literal filesystem permission paths as `PathUri` values through the
  runtime policy and execution protocol.
- Keep legacy string-based serialization at explicit protocol boundaries and
  reject conversions that cannot be represented losslessly.
- Encode native paths as opaque URIs when a normal file URI would imply the
  wrong path convention.

## Testing

Added coverage for cross-platform and ambiguous path round trips, UNC path
variants, permission-profile serialization, and deny-policy enforcement.

GitOrigin-RevId: 5247713796d1f2bb4e02f94eb9fc82d4698060f0
2026-08-17 21:49:30 +00:00
jif
3134ab6572 Restrict filesystem helper sandbox access (#38561)
## Why

Filesystem helpers only need access to their own executables. Granting access to
the containing directories also makes unrelated sibling files readable.

## What changed

- Allow filesystem helpers to read the Codex and Linux sandbox executables
  directly instead of their parent directories.
- Give macOS filesystem helpers a narrower Seatbelt profile that omits the
  normal process sandbox's `/Applications` read access.
- Preserve the existing platform defaults for normal sandboxed processes.

## Testing

Add unit and integration coverage for direct and symlinked sibling-file access,
sandboxed copies, allowed workspace reads, and the macOS-specific Seatbelt
profiles.

GitOrigin-RevId: 9380c6868a695bdf2275baa74bd5e8a30a64ba1b
2026-08-14 11:47:12 +00:00
iceweasel-oai
18bbb585e7 Add an AbsolutePathBuf conversion for FileSystemPath (#38460)
## What changed

Implement `From<AbsolutePathBuf>` for `FileSystemPath` and use the conversion
when constructing concrete filesystem permission paths.

GitOrigin-RevId: 244bcbd0c3f76cd87cc1240458fcac6c9ef0a8e3
2026-08-14 00:18:29 +00:00
iceweasel-oai
34db7e5563 Sandbox remote apply_patch operations (#38043)
## Why

Cross-platform remote `apply_patch` calls were rejected when filesystem writes
were restricted because patch verification and writes could not be safely
performed against executor files.

## What changed

- Route intercepted and direct remote patches through the executor-managed
  filesystem sandbox, including the configured workspace roots.
- Select the restricted-token sandbox for Windows executor paths when no
  Windows sandbox level was configured.
- Fail closed when an executor cannot enforce the requested sandbox, and treat
  executor-managed access failures as sandbox denials so approval can retry the
  patch without sandboxing.

## Testing

- Cover sandboxed remote patches, denied writes, approval retries, Windows
  sandbox selection, and executor filesystem enforcement.

GitOrigin-RevId: caddeed0b266c456a689080a14a3a58e2bd7887c
2026-08-11 17:47:22 +00:00
iceweasel-oai
a603d7ca5c Honor the configured Windows sandbox level for managed networking (#37875)
## Why

Managed networking implicitly selected the elevated Windows sandbox backend,
even when the sandbox was configured to use a restricted token.

## What changed

- Select the Windows sandbox backend solely from `WindowsSandboxLevel`.
- Reject managed networking with a restricted-token sandbox before spawning a
  process, since managed networking requires the elevated backend.
- Cover the rejection through sandbox preparation, unified exec, and Windows
  sandbox session tests.

GitOrigin-RevId: 308858652d7b629af623d22896dafde3a23d3758
2026-08-10 19:57:40 +00:00
iceweasel-oai
413492cd6c Ignore symbolic slash-tmp permissions on Windows (#36237)
## Why

The `:slash_tmp` filesystem entry represents the Unix `/tmp` directory and
should not affect Windows sandbox policy decisions.

## What changed

- Ignore symbolic `SlashTmp` entries when resolving Windows filesystem access,
  converting permission profiles, and intersecting requested permissions.
- Continue treating a literal `/tmp` entry as a regular filesystem path.

## Testing

Add Windows-specific coverage for policy conversion, access checks, and
permission-profile intersection.

GitOrigin-RevId: f4cdd37ea41abc9debfe8a0d3a456b70da5e534c
2026-07-30 22:45:04 +00:00
viyatb-oai
0042b00986 Record normalized sandbox violation events (#36207)
## Why

Filesystem denials and managed-network blocks did not share a structured event
shape, requiring downstream consumers to rediscover enforcement paths and parse
backend-specific output. See https://github.com/openai/codex/pull/17573.

## What changed

- Add normalized filesystem and network violation types in `codex-sandboxing`
  and emit them through a shared tracing seam.
- Classify filesystem denials by backend and reason, retaining an optional path
  and bounded output snippet, and preserve managed-network block context.
- Report the sandbox type through exec-server responses so unified exec can
  classify remote denials without guessing; omitted values remain compatible
  with older peers.
- Record violations from exec, apply-patch, shell-escalation, unified-exec, and
  managed-network enforcement paths without changing denial behavior.

## Testing

- Cover filesystem classification, path extraction, `SIGSYS`, network event
  conversion, protocol compatibility, and remote sandbox-type propagation.

GitOrigin-RevId: d673173b4fa6bdf0a24421194a8a61c81fab9c96
2026-07-30 19:23:33 +00:00
viyatb-oai
0dcad0c972 Use permission profiles throughout sandbox execution (#36183)
## What changed

- Pass the canonical `PermissionProfile` through execution requests, sandbox
  selection, escalation, and the exec server instead of carrying separate
  derived filesystem and network policies.
- Derive runtime sandbox policies from the effective profile at their points of
  use, including after applying additional permissions.
- Update sandbox and escalation tests to inspect policies through the profile.

GitOrigin-RevId: 695b82ea94f5289516b0933bb23074cb2dcce8ac
2026-07-30 16:30:32 +00:00
iceweasel-oai
999a715089 Route Windows sandbox proxy traffic by restricting SID (#34613)
## Why

Elevated Windows sandboxes need stable managed-proxy ports while preserving the network policy and environment attribution of each sandboxed process.

## What changed

- Keep shared HTTP and SOCKS5 loopback ingress listeners alive across managed-proxy instances.
- Add a per-route restricting SID to elevated sandbox tokens and dispatch incoming connections to the matching proxy policy after attributing the client process.
- Reject connections without exactly one registered route, remove routes when their proxy handle is dropped, and keep unsandboxed Windows launches off the managed ingress.
- Provision the elevated sandbox with the configured proxy ports and local-binding setting, honoring the selected profile and CLI overrides.

## Testing

- Add Windows unit tests for TCP ownership attribution, route selection, restricting-token propagation, and setup settings.
- Add an end-to-end Windows test covering stable ports, isolated environment policies, HTTP and SOCKS5 routing, and route teardown.

GitOrigin-RevId: 783fac6e0f904dc9bb1955b75d4a5895e8bb9690
2026-07-21 21:06:04 +00:00
iceweasel-oai
87f71e35b8 Skip missing paths in filesystem sandbox entries (#34598)
## Why

Default read-only protections for project metadata should apply when paths such
as `.git`, `.agents`, and `.codex` exist, without causing sandbox setup to
materialize missing paths as ACL targets.

## What changed

- Add an optional `missing_path_behavior` to filesystem sandbox entries and
  mark default project-metadata protections with `skip`.
- Preserve the behavior through permission transforms and exec/MCP protocol
  serialization while keeping existing path wire variants stable.
- Ignore skip-missing entries when projecting configuration or Windows sandbox
  overrides, while retaining explicit metadata carveouts.

## Testing

- Cover protocol round trips for path and special-path entries.
- Verify default metadata protections and Windows explicit carveout handling.

GitOrigin-RevId: 6df13dadacdd131c44aab9f15a967c81051355c1
2026-07-21 19:17:18 +00:00
iceweasel-oai
35c2278dd5 Support Windows sandboxing in the exec server (#34423)
## Why

Sandboxed process launch through the exec server was unsupported on Windows.

## What changed

- Add a shared native process launcher that selects the Windows sandbox session backend when required and otherwise launches PTY or pipe-based processes.
- Pass Windows permission, workspace-root, proxy, filesystem-override, and desktop settings through exec-server process preparation.
- Preserve piped stdin and inherited file descriptors across the shared launch path.

## Testing

- Verify that a remote Windows sandbox process accepts stdin while blocking a write under a read-only policy.
- Enable workspace-root sandbox tests on native Windows while continuing to skip environments that cannot emulate Windows sandbox semantics.

GitOrigin-RevId: 6719ccbe87ad0d5a57af56503e3f23f894c60a71
2026-07-20 22:35:14 +00:00
pakrym-oai
5a85351dfe Remove generated-default filesystem path variants (#33632)
## What changed

- Represent built-in filesystem policy entries with the same `Path` and
  `Special` variants used by other entries.
- Remove generated-default filtering from Windows sandbox policy resolution and
  simplify elevated deny-write handling to rely on direct-runtime enforcement
  and the legacy policy projection.
- Update protocol conversions, policy transforms, and profile expectations for
  the reduced filesystem path model.

GitOrigin-RevId: a65793e6855a03d52a575e82cb3d4b9b2e32db5c
2026-07-16 16:13:53 +00:00
iceweasel-oai
4bc2c723ef Select the elevated Windows sandbox for network proxies (#33445)
## Why

Windows firewall enforcement is tied to the logon-user sandbox identities. Proxy-enforced commands therefore need the elevated backend even when the configured sandbox mode is the default restricted-token mode.

## What changed

- Select the elevated Windows sandbox backend whenever a command uses the managed network proxy.
- Remove configuration and startup checks that required users or managed requirements to select the elevated sandbox explicitly.
- Start and expose managed network proxy state consistently on Windows.

## Testing

- Verify that proxy enforcement selects the elevated backend for the restricted-token sandbox mode.

GitOrigin-RevId: e01ac052587721c468a8fbcf4e2c7c5a185a3e05
2026-07-15 23:19:00 +00:00
iceweasel-oai
cb79b3cdf9 Avoid creating metadata paths in the Windows sandbox (#33430)
## Why

Elevated Windows sandbox setup could turn the built-in read-only protections
for workspace metadata into deny-write paths, creating metadata directories
that did not already exist.

## What changed

- Track whether filesystem permission entries come from a built-in profile or
  were explicitly configured.
- Exclude generated metadata defaults from direct Windows deny-write overrides
  while continuing to enforce explicit read-only carveouts for the same paths.
- Preserve the distinction while materializing and normalizing permission
  paths, without exposing generated defaults as user configuration.

## Testing

Added Windows coverage confirming that elevated sandbox setup leaves missing
workspace metadata absent and still produces overrides for explicit metadata
carveouts.

GitOrigin-RevId: 701bcb229f631b18ab5ced22f3edf6f303d932f3
2026-07-15 21:19:14 +00:00
iceweasel-oai
abbb8c569c Require the elevated Windows sandbox for network proxies (#32857)
## Why

Network proxy enforcement on Windows requires the elevated sandbox backend. Silently selecting that backend for an unelevated configuration makes the effective sandbox differ from the configured mode.

## What changed

- Reject enabled network proxy configurations on Windows unless managed requirements allow only the elevated sandbox and `windows.sandbox` resolves to `"elevated"`.
- Preserve the configured sandbox backend during execution and validate proxy compatibility at config loading, sandbox setup, and process launch boundaries.
- Defer this validation during cloud-config bootstrap so authoritative managed requirements can be loaded first.
- Do not start or expose disabled Windows proxies, and render transitions to disabled networking as `<network enabled="false"></network>`.

## Testing

- Cover Windows requirement and sandbox compatibility matrices, bootstrap behavior, backend selection, disabled proxy handling, and environment-context updates.

GitOrigin-RevId: bfa1dda98594e0db61883f8e7f65bd560e3453e6
2026-07-13 19:04:22 +00:00
Felipe Coury
2c85975eea fix(sandboxing): initialize network proxy config inline (#31830)
## Why

PR #31767 flattened `NetworkProxyConfig`, leaving the [seatbelt test
setup](d72d669ca7/codex-rs/sandboxing/src/seatbelt_tests.rs (L660-L662))
to assign fields directly after `NetworkProxyConfig::default()`. Rust
1.95 flags that pattern as `clippy::field_reassign_with_default`, and
the macOS Bazel Clippy job treats the warning as an error, blocking
`main` and PRs based on it.

## What Changed

Initialize `enabled` and `mode` in the `NetworkProxyConfig` struct
literal, then apply the Unix socket allowlist through the existing
setter. This preserves the test behavior while satisfying Clippy.

## How to Test

This is a test-only initialization change, so there is no manual product
flow.

Targeted tests:

- `just test -p codex-sandboxing` (65 passed)
- `just clippy -p codex-sandboxing`

The local argument-comment lint could not complete because Bazel's LLVM
repository is missing the `compiler-rt` BUILD package. The touched Rust
diff was manually audited and adds no positional literal calls.
2026-07-09 19:36:36 +01:00
jif
cf6d8ad921 Remove the network proxy config wrapper (#31767)
## Why

`NetworkProxyConfig` only wrapped `NetworkProxySettings` in a single
`network` field. That extra level made runtime callers repeat `.network`
everywhere without representing a real boundary.

## What changed

- move the managed-network fields directly onto `NetworkProxyConfig`
- collapse the matching partial-config wrapper
- update runtime callers and tests to use the direct fields
- keep the user-facing permissions/profile TOML layout unchanged

The internal serialized shape now matches the runtime type itself. This
does not change managed-network behavior or the `config.toml` shape.
2026-07-09 17:33:37 +01:00
iceweasel-oai
18fe1d9fe3 [codex] Preserve proxy state for filesystem sandbox helpers (#29671)
## Why

Filesystem helpers intentionally run with a minimal environment that
excludes proxy variables. After filesystem operations started using the
Windows sandbox wrapper, the wrapper derived an empty proxy
configuration from that helper environment and compared it with the
persistent sandbox setup marker. When the marker contained proxy ports,
every filesystem operation appeared to require a firewall update, which
could launch elevated setup, show a UAC or loader dialog, and fail
operations such as `apply_patch` with error 1223.

Filesystem helpers do not use network access, so they should preserve
the proxy/firewall state established by normal sandboxed process
launches.

## What changed

- Add an explicit Windows sandbox proxy-settings mode for reconciling or
preserving persistent proxy state.
- Use preserve mode for filesystem helpers while normal process launches
continue to reconcile proxy settings from their environment.
- Carry the selected proxy state consistently through setup validation,
elevated setup, and non-elevated ACL refreshes.
- Cover wrapper argument propagation and marker-derived proxy
preservation.

## Validation

- `cargo build -p codex-cli --bin codex`
- `just test -p codex-windows-sandbox
preserving_proxy_settings_uses_the_existing_marker`
- `just test -p codex-windows-sandbox windows_wrapper_args_round_trip`
- `just test -p codex-windows-sandbox
setup_request_prefers_explicit_proxy_settings`
- `just test -p codex-sandboxing transform_for_direct_spawn_windows`
- `just test -p codex-exec-server fs_sandbox::tests`
- Ran the same sandboxed `fs/writeFile` reproduction against published
`0.142.0-alpha.6` and the new CLI. The published CLI launched elevated
setup and failed with `ShellExecuteExW ... 1223`; the new CLI completed
without elevation.

Related to #28359.
2026-06-23 12:29:46 -07:00
jif
e476fc16ce Prepare managed network sandbox context (#29456)
## Why

Managed network configures commands to use local HTTP and SOCKS proxies.
For commands delegated to the exec server, the proxy environment and the
sandbox policy were prepared separately. On macOS, that meant a command
could receive `HTTPS_PROXY=http://127.0.0.1:43123` while Seatbelt still
denied access to port `43123`.

## What changed

`NetworkProxy` now prepares the command environment and sandbox context
together from the same runtime snapshot:

```text
Prepared managed network
├── command environment: HTTPS_PROXY=http://127.0.0.1:43123
└── sandbox context: allow outbound to 127.0.0.1:43123
```

That context travels with remote exec requests. The exec server
preserves the managed proxy and CA environment, and macOS Seatbelt
allows only the prepared loopback proxy ports without enabling broad
network access or local binding.

The protocol field is optional and the existing enforcement flag remains
in place, preserving compatibility with callers that do not send the new
context.
2026-06-23 20:07:09 +01:00
jif
9f06cf1a09 Report remote sandbox denials semantically (#29424)
## Why

#29113 moved remote sandbox setup and enforcement to the exec server.
That gives the executor ownership of the platform-specific work: a Linux
executor chooses and runs a Linux sandbox even when the Codex
orchestrator is running on macOS or Windows.

It also means the orchestrator no longer knows which concrete sandbox
the executor selected. When that sandbox blocks a remote command, the
orchestrator currently sees only a failed process and can treat the
denial as an ordinary command failure. The existing sandbox approval and
retry path is then skipped.

This PR lets the executor report one portable fact:

> This command probably failed because the executor sandbox blocked it.

The executor keeps its concrete sandbox type private. The protocol sends
only the semantic result.

## Example

Suppose a local macOS Codex session asks a Linux devbox to write outside
the allowed workspace.

Before this PR:

```text
Linux sandbox blocks the write
    -> remote process exits with "Permission denied"
    -> local orchestrator sees an ordinary command failure
    -> the normal sandbox approval and retry path can be skipped
```

With this PR:

```text
Linux sandbox blocks the write
    -> executor reports sandboxDenied: true
    -> unified exec returns UnifiedExecError::SandboxDenied
    -> the existing approval prompt is shown
    -> an approved retry runs through the existing unsandboxed retry path
```

## What changes

### The executor remembers its selected sandbox

The prepared remote process now retains the executor-selected
`SandboxType`. This value never crosses the executor boundary.

Commands started without a sandbox retain `SandboxType::None` and are
never reported as sandbox denials.

### The executor uses the existing denial heuristic

The existing local denial heuristic moves from `codex-core` into the
shared `codex-sandboxing` crate.

When a sandboxed remote process exits, the executor:

1. waits the same short output grace period used by local unified exec;
2. reads the output currently available in the existing retained output
buffer;
3. runs the existing heuristic using the exit code and common denial
messages;
4. stores the yes/no result before publishing the process exit.

This deliberately matches the old local unified-exec behavior. It does
not add a new streaming classifier, another output buffer, or stronger
output-retention guarantees.

### The protocol reports a portable boolean

`process/read` gains `sandboxDenied`:

```json
{
  "exited": true,
  "exitCode": 1,
  "closed": false,
  "sandboxDenied": true
}
```

The field defaults to `false` when an older executor omits it. The
response does not expose the executor sandbox implementation or
executor-native paths.

### Unified exec uses the existing error path

The exec-server client carries `sandboxDenied` into the unified process
state. If it is true, unified exec returns the existing `SandboxDenied`
error instead of trying to classify remote output using an
orchestrator-side sandbox type.

Remote process exit remains visible as soon as the process exits. This
PR does not wait for stdout or stderr to close and does not change the
existing process lifecycle.

## Scope

This PR is intentionally limited to matching the existing local
unified-exec behavior for the initial command execution path.

It does not add:

- incremental denial tracking across the full output stream;
- new denial handling for commands completed later through
`write_stdin`;
- new guarantees for preserving the semantic flag during the narrow
reconnect-recovery race.

Those can be considered separately if the same behavior is added for
local execution.

## Test coverage

One remote end-to-end integration test covers the complete intended
flow:

```text
remote read-only sandbox
    -> denied write
    -> executor reports the denial
    -> Codex requests approval
    -> user approves
    -> retry succeeds on the remote executor
```

Existing lifecycle coverage continues to verify that remote process exit
is reported before late output streams close.
2026-06-22 19:33:28 +02:00
jif
bd2968a4db Carry sandbox intent to remote exec servers (#29108)
## What changed

PR #29099 stopped sending the orchestrator's concrete sandbox wrapper to
a remote exec-server. Remote commands now arrive as plain native argv.

This PR adds the next piece: Codex also sends portable sandbox intent
next to that plain argv.

For a remote unified-exec command, the request can now include:

- the canonical permission profile before local workspace-root
materialization
- the sandbox cwd and workspace roots as `PathUri` values
- Windows sandbox settings
- the legacy Landlock setting
- whether managed networking must be enforced

The important part is that symbolic entries such as `:workspace_roots`
stay symbolic while crossing the boundary. The executor can then bind
them to its own workspace-root paths instead of receiving
orchestrator-local absolute paths.

The data travels through `ExecRequest` into `ExecParams`. Older
exec-servers can still deserialize requests because the new fields have
defaults.

## Why

The orchestrator should not decide how another machine implements
sandboxing.

For example:

- a local macOS Codex would normally build a Seatbelt command
- a remote Linux executor needs a Linux sandbox command instead

The orchestrator now sends the plain command plus the policy it intended
to enforce. A later PR can let the exec-server choose and build the
correct sandbox for its own operating system.

## Important detail

This keeps the portable intent separate from the local `SandboxType`.

`SandboxType::None` is ambiguous:

- it can mean the command was explicitly approved to run without a
sandbox
- it can also mean the orchestrator host has no concrete sandbox
implementation available

Those cases are different for remote execution. This PR adds
`sandbox_requested` so an executor can still receive sandbox intent when
the orchestrator cannot build a local wrapper. Explicit unsandboxed
retries still send no sandbox context.

## Behavior today

This PR only transports the intent. The exec-server accepts the new
fields but does not apply them yet.

Remote commands therefore remain unsandboxed after this PR, just as they
are after PR #29099.

## Follow-up

The next PR will make exec-server read this portable intent, bind
symbolic workspace permissions to executor-native roots, choose the
sandbox for its own operating system, build the wrapper locally, and
then spawn the command.
2026-06-21 12:33:21 +02:00
jif
bd5d31b250 Scope network approvals by environment (#28899)
Stacked on #28766.

## Why

Network approvals are environment-scoped: allowing a host in one
execution environment should not allow the same host in another
environment.

#28766 adds the inert IDs and constructor plumbing. This PR applies the
behavior on top.

## What changed

- Route managed network traffic through per-environment HTTP and SOCKS
proxy listeners.
- Stamp HTTP, HTTPS CONNECT, SOCKS TCP, and SOCKS UDP policy requests
with the source environment at the proxy boundary.
- Carry the selected execution environment through shell, unified exec,
zsh-fork, and sandbox transform paths.
- Include the environment in pending, approved-for-session, and
denied-for-session network approval cache keys.
- Include the environment in approval IDs and approval prompts.
- Preserve legacy fallback for unattributed requests, but deny when
active-call attribution is ambiguous.
- Fail closed if an environment-specific proxy endpoint cannot be
prepared.

## Validation

- just fmt
- CI will run tests and clippy
2026-06-19 13:49:45 +02:00
jif
0369b24d54 Add network environment ID plumbing (#28766)
## Why

Prepare network approval scoping to distinguish execution environments
without changing behavior yet.

## What changed

- Add optional environment IDs to network policy requests.
- Add optional network environment IDs to exec and sandbox request
structs.
- Thread default None values through existing construction points.
- Fix stale constructor call sites that caused the CI compile failures.

## Not included

- Per-environment proxy listeners.
- Network approval cache or prompt behavior changes.
- Ambiguous request attribution handling.

Those behavior changes moved to stacked follow-up #28899.

## Validation

- just fmt
- CI will run tests and clippy
2026-06-18 14:09:38 +02:00
Adam Perry @ OpenAI
5867b529ae unified-exec: preserve PathUri through exec-server (#28681)
## Why

It should be possible for app-server to handle "foreign" OS paths in
unified_exec working directories, allowing e.g. a Linux app-server to
run processes on e.g. a Windows exec-server.

## What

Convert the core unified_exec cwd values to use `PathUri`.

Adds fallible path conversion in several places to try to minimize the
scope of this change. The only time this change suppresses errors from
converting `PathUri` to an `AbsolutePathBuf` is when the turn is
configured with no sandboxing at all to allow us to make progress
testing without sandboxing.

Future changes to apply_patch and sandboxing will clean up these error
paths.

A tool's cwd is resolved from joining a model-provided workdir to the
environment's cwd. When using `AbsolutePathBuf::join()`, an
absolute-path workdir would overwrite the environment's cwd and we would
resolve permissions/sandboxing against the model-provided path. This
change extends `PathUri::join()` to also treat an absolute rhs as an
override of the base/lhs.

This also removes some coverage from the remove_env_windows tests until
a follow-up converts foreign paths in command exec events correctly.

## Breaking Changes

When using `AbsolutePathBuf::join()` for workdir resolution, we ended up
resolving tilde-prefixed paths against the app-server's `$HOME`, e.g.
`~/foo/bar` becomes `/home/anp/foo/bar`. It's difficult to do this with
`PathUri` joining, so after offline discussion this PR no longer
implements it.

A quick check of some power users' rollouts suggests that models don't
actually generate home-prefixed absolute working directories for their
spawns, so this shouldn't have any real blast radius.
2026-06-17 19:36:16 +00:00
iceweasel-oai
ef75171f18 Run fs helper through Windows sandbox wrapper (#28359)
## Why

This is the final PR in the Windows fs-helper sandbox stack and contains
the actual bug fix.

The exec-server filesystem helper is a direct-spawn path: it asks
`SandboxManager` for a `SandboxExecRequest`, then launches the returned
argv itself. That works on macOS and Linux because the transformed argv
is already a self-contained sandbox wrapper. On Windows, the transformed
request carried `WindowsRestrictedToken` metadata, but the direct-spawn
fs-helper runner still launched the helper argv directly.

That means Windows filesystem built-ins backed by the fs-helper could
run with the parent Codex process permissions instead of the configured
Windows sandbox. This PR makes the direct-spawn transform produce a
self-contained Windows wrapper argv before fs-helper launches it.

## What Changed

- Added `SandboxManager::transform_for_direct_spawn()` for callers that
launch the returned argv themselves.
- Wrapped Windows restricted-token direct-spawn requests with `codex.exe
--run-as-windows-sandbox` and then marked the outer request as
unsandboxed, matching the macOS/Linux wrapper argv shape.
- Updated `exec-server/src/fs_sandbox.rs` to use the direct-spawn
transform for fs-helper launches.
- Materialized the inner `codex.exe --codex-run-as-fs-helper` executable
into `.sandbox-bin` so the sandboxed user can run it.
- Carried runtime workspace roots through `FileSystemSandboxContext` as
`PathUri` values so `:workspace_roots` policies resolve correctly
without sending native client paths over exec-server JSON.
- Preserved wrapper setup identity environment needed by Windows sandbox
setup without changing the serialized inner helper environment.

## Verification

- `just bazel-lock-update`
- `just bazel-lock-check`
- `just test -p codex-sandboxing transform_for_direct_spawn_windows`
- `just test -p codex-exec-server fs_sandbox::tests`
- `just fix -p codex-windows-sandbox -p codex-sandboxing -p
codex-exec-server -p codex-core -p codex-file-system`

Local note: `just fmt` completed Rust formatting, but this workstation
still fails the non-Rust formatter phases because uv cannot open its
cache and the local buildifier/dotslash path is missing.
2026-06-17 10:00:42 -07:00
Adam Perry @ OpenAI
740c4f269d build: run buildifier from just fmt (#28125)
## Intent

Keep Bazel and Starlark files consistently formatted without requiring
contributors to install or version buildifier themselves.

## Implementation

- Add a SHA-256-pinned, cross-platform DotSlash manifest for buildifier
v8.5.1.
- Run buildifier from the shared `just fmt` and `just fmt-check` driver,
with Windows-safe explicit DotSlash invocation.
- Provision DotSlash in formatting CI and contributor devcontainers, and
document the source-build prerequisite.
- Apply the initial mechanical buildifier formatting baseline.
2026-06-13 21:43:39 -07:00
Adam Perry @ OpenAI
968a3ac9c1 [codex] make PathUri::from_abs_path infallible (#27976)
## Why

`PathUri::from_abs_path` can fail for absolute paths that do not have a
normal `file:` URI representation, forcing filesystem call sites to
handle a conversion error even though the original path can be preserved
losslessly.

## What

Make `from_abs_path` infallible and migrate its callers. Unrepresentable
paths use `file:///%00/bad/path/<base64>`, encoding Unix bytes or
Windows UTF-16LE; `to_abs_path` validates and decodes that fallback. The
leading encoded null reserves a namespace that cannot collide with a
real Unix or Windows path, and fallback URIs remain opaque to lexical
path operations.

## Validation

Added path-URI coverage for Unix null and non-UTF-8 paths, Windows
device/verbatim and non-Unicode paths, serialization, malformed
fallbacks, opaque lexical operations, invalid native payloads, and
literal `/bad/path` collision resistance.
2026-06-12 16:58:42 -07:00
Adam Perry @ OpenAI
52a50aec70 sandboxing: migrate cwd inputs to PathUri (#27816)
## Why

Sandbox cwd values can cross app-server and exec-server host boundaries.
They should retain URI semantics until the receiving host validates them
instead of being interpreted early as native paths.

## What

- Carry `PathUri` through filesystem sandbox contexts, sandbox commands,
and transform inputs.
- Convert command and policy cwd once in `SandboxManager::transform`,
then keep launch requests native.
- Preserve sandbox cwd over remote filesystem transport and reject
non-native URIs without fallback.
- Cache paired native/URI turn-environment cwd values during migration,
with immutable access to keep them synchronized.
- Extend existing protocol, forwarding, transform, and core runtime
tests.
2026-06-12 11:38:01 -07:00
Adam Perry @ OpenAI
5a56caf18c [codex] Remove async_trait from first-party code (#27475)
## Why

First-party async traits should expose their `Send` contracts explicitly
without requiring `async_trait`. This completes the migration pattern
established in #27303 and #27304.

## What changed

- Replaced the remaining first-party `async_trait` traits with native
return-position `impl Future + Send` where statically dispatched and
explicit boxed `Send` futures where object safety is required.
- Kept implementations behavior-preserving, outlining existing async
bodies into inherent methods where that keeps the diff reviewable.
- Removed all direct first-party `async-trait` dependencies and the
workspace dependency declaration.
- Added a cargo-deny policy that permits `async-trait` only through the
remaining transitive wrapper crates.
- Updated `rand` from 0.8.5 to 0.8.6 to resolve RUSTSEC-2026-0097 and
keep the full cargo-deny check passing.

## Validation

- `just test -p codex-exec-server`: 216 passed, 2 skipped.
- `just test -p codex-model-provider`: 39 passed.
- `just test -p codex-core` and `just test`: changed tests passed;
remaining failures are environment-sensitive suites unrelated to this
migration.
- `cargo deny check`
- `just fix`
- `just fmt`
- `cargo shear`
- `just bazel-lock-check`
2026-06-11 18:16:39 -07:00
viyatb-oai
85fd52f7e4 Enforce configured network proxy in codex sandbox (#27035)
## Why

`codex sandbox` can start a network proxy from a configured permission
profile. Previously, sandbox-level containment was tied to managed
network requirements rather than whether a proxy was actually active.
This meant config-driven proxy policies were not consistently enforced
as the sandbox's only network path.

## What changed

- Enable proxy-only network containment whenever `codex sandbox` starts
a network proxy.
- Apply the same active-proxy check to the macOS and Linux sandbox
paths.
- Add a Linux regression test that verifies a sandboxed command cannot
establish a direct connection while the configured proxy is active.

## Test plan

- `just test -p codex-cli debug_sandbox::tests`
- `sandbox_with_network_proxy_blocks_direct_loopback_access` runs on
Linux to cover the config-driven proxy path end to end.
2026-06-08 14:03:37 -07:00