Commit Graph
19 Commits
Author SHA1 Message Date
Michael Bolin dcc894c337 Extract codex-config from codex-core
## Why

`codex-core` has accumulated config loading, requirements parsing, constraint logic, and config-layer state handling in one large crate. This refactor pulls that cohesive subsystem into a dedicated crate so we can reduce the compile/test surface area of `codex-core` and make future config work more isolated.

This is part of the broader goal of right-sizing crates to reduce monolithic rebuild cost and improve incremental development speed.

## What Changed

### New crate

- Added a new workspace crate: `codex-rs/config` (`codex-config`)
- Added workspace wiring in `codex-rs/Cargo.toml`
- Added dependency from `codex-core` to `codex-config`

### Moved config internals from `core` to `config`

Moved these modules into `codex-config`:

- `core/src/config/constraint.rs` -> `config/src/constraint.rs`
- `core/src/config_loader/cloud_requirements.rs` -> `config/src/config_loader/cloud_requirements.rs`
- `core/src/config_loader/config_requirements.rs` -> `config/src/config_loader/config_requirements.rs`
- `core/src/config_loader/fingerprint.rs` -> `config/src/config_loader/fingerprint.rs`
- `core/src/config_loader/merge.rs` -> `config/src/config_loader/merge.rs`
- `core/src/config_loader/overrides.rs` -> `config/src/config_loader/overrides.rs`
- `core/src/config_loader/requirements_exec_policy.rs` -> `config/src/config_loader/requirements_exec_policy.rs`
- `core/src/config_loader/state.rs` -> `config/src/config_loader/state.rs`

### Removed shim modules in `core`

After the move, the temporary one-line `pub use` shim files under `core/src/config_loader/` were deleted so history is a clean move/delete rather than introducing extra permanent forwarding modules.

`core/src/config_loader/mod.rs` now imports/re-exports directly from `codex_config`, including direct use of `build_cli_overrides_layer` and test-only access to `version_for_toml`.

### Follow-on fixes for direct imports

- Updated `core/src/config_loader/macos.rs` to use `super::{ConfigRequirementsToml, ConfigRequirementsWithSources, RequirementSource}`.
- Updated `core/src/config_loader/tests.rs` imports to reference `crate::config_loader` re-exports and `codex_config` exec-policy TOML types.

## Behavior and API Notes

- Config behavior is intended to be unchanged.
- `codex-core` continues to expose the same config-loader-facing API surface to its internal callers via `core/src/config_loader/mod.rs` re-exports.
- The main functional change is crate ownership and dependency direction, not config semantics.

## Validation

Ran:

- `cargo test -p codex-config`
- `cargo test -p codex-core --no-run`
- `cargo test -p codex-core config_loader::tests::load_requirements_toml_produces_expected_constraints`
- `cargo test -p codex-core config_loader::tests::requirements_exec_policy_tests::parses_single_prefix_rule_from_raw_toml`
- `just fmt`
- `just fix -p codex-config -p codex-core`
- `just fix -p codex-core`

All listed commands completed successfully in this workspace environment.
2026-02-10 22:32:09 -08:00
Josh McKinney 34c88d10ea deflake linux-sandbox NoNewPrivs timeout (#11245)
Deflake `codex-linux-sandbox::all
suite::landlock::test_no_new_privs_is_enabled`.

CI has intermittently failed with `Sandbox(Timeout)` (exit 124) because
the sandboxed
`grep '^NoNewPrivs:' /proc/self/status` can run close to the short
timeout budget.

This updates only this test to use `LONG_TIMEOUT_MS`, which removes the
near-threshold timeout
behavior while keeping the rest of the suite unchanged.

Refs (previous failures):
- PR:
https://github.com/openai/codex/actions/runs/21836764823/job/63009902779
- PR:
https://github.com/openai/codex/actions/runs/21837427251/job/63012470353
- main:
https://github.com/openai/codex/actions/runs/21830746538/job/62988079964

Validation:
- Local: `cd codex-rs && cargo test -p codex-linux-sandbox` (non-Linux
runs 0 tests)
2026-02-10 03:03:58 +00:00
Michael Bolin 383b45279e feat: include NetworkConfig through ExecParams (#11105)
This PR adds the following field to `Config`:

```rust
pub network: Option<NetworkProxy>,
```

Though for the moment, it will always be initialized as `None` (this
will be addressed in a subsequent PR).

This PR does the work to thread `network` through to `execute_exec_env()`, `process_exec_tool_call()`, and `UnifiedExecRuntime.run()` to ensure it is available whenever we span a process.
2026-02-09 03:32:17 +00:00
viyatb-oai ae4de43ccc feat(linux-sandbox): add bwrap support (#9938)
## Summary
This PR introduces a gated Bubblewrap (bwrap) Linux sandbox path. The
curent Linux sandbox path relies on in-process restrictions (including
Landlock). Bubblewrap gives us a more uniform filesystem isolation
model, especially explicit writable roots with the option to make some
directories read-only and granular network controls.

This is behind a feature flag so we can validate behavior safely before
making it the default.

- Added temporary rollout flag:
  - `features.use_linux_sandbox_bwrap`
- Preserved existing default path when the flag is off.
- In Bubblewrap mode:
- Added internal retry without /proc when /proc mount is not permitted
by the host/container.
2026-02-04 11:13:17 -08:00
Max Johnson 66b196a725 Inject CODEX_THREAD_ID into the terminal environment (#10096)
Inject CODEX_THREAD_ID (when applicable) into the terminal environment
so that the agent (and skills) can refer to the current thread / session
ID.

Discussion:
https://openai.slack.com/archives/C095U48JNL9/p1769542492067109
2026-02-03 11:31:12 -08:00
iceweasel-oai c40ad65bd8 remove sandbox globals. (#9797)
Threads sandbox updates through OverrideTurnContext for active turn
Passes computed sandbox type into safety/exec
2026-01-27 11:04:23 -08:00
viyatb-oai 55bda1a0f2 revert: remove pre-Landlock bind mounts apply (#9300)
**Description**

This removes the pre‑Landlock read‑only bind‑mount step from the Linux
sandbox so filesystem restrictions rely solely on Landlock again.
`mounts.rs` is kept in place but left unused. The linux‑sandbox README
is updated to match the new behavior and manual test expectations.
2026-01-15 09:47:57 -08:00
viyatb-oai 2259031d64 fix: fallback to Landlock-only when user namespaces unavailable and set PR_SET_NO_NEW_PRIVS early (#9250)
fixes https://github.com/openai/codex/issues/9236

### Motivation
- Prevent sandbox setup from failing when unprivileged user namespaces
are denied so Landlock-only protections can still be applied.
- Ensure `PR_SET_NO_NEW_PRIVS` is set before installing seccomp and
Landlock restrictions to avoid kernel `EPERM`/`LandlockRestrict`
ordering issues.

### Description
- Add `is_permission_denied` helper that detects `EPERM` /
`PermissionDenied` from `CodexErr` to drive fallback logic.
- In `apply_read_only_mounts` skip read-only bind-mount setup and return
`Ok(())` when `unshare_user_and_mount_namespaces()` fails with
permission-denied so Landlock rules can still be installed.
- Add `set_no_new_privs()` and call it from
`apply_sandbox_policy_to_current_thread` before installing seccomp
filters and Landlock rules when disk or network access is restricted.
2026-01-14 22:24:34 -08:00
viyatb-oai e1447c3009 feat: add support for read-only bind mounts in the linux sandbox (#9112)
### Motivation

- Landlock alone cannot prevent writes to sensitive in-repo files like
`.git/` when the repo root is writable, so explicit mount restrictions
are required for those paths.
- The sandbox must set up any mounts before calling Landlock so Landlock
can still be applied afterwards and the two mechanisms compose
correctly.

### Description

- Add a new `linux-sandbox` helper `apply_read_only_mounts` in
`linux-sandbox/src/mounts.rs` that: unshares namespaces, maps uids/gids
when required, makes mounts private, bind-mounts targets, and remounts
them read-only.
- Wire the mount step into the sandbox flow by calling
`apply_read_only_mounts(...)` before network/seccomp and before applying
Landlock rules in `linux-sandbox/src/landlock.rs`.
2026-01-14 08:30:46 -08:00
Michael Bolin 642b7566df fix: introduce AbsolutePathBuf as part of sandbox config (#7856)
Changes the `writable_roots` field of the `WorkspaceWrite` variant of
the `SandboxPolicy` enum from `Vec<PathBuf>` to `Vec<AbsolutePathBuf>`.
This is helpful because now callers can be sure the value is an absolute
path rather than a relative one. (Though when using an absolute path in
a Seatbelt config policy, we still have to _canonicalize_ it first.)

Because `writable_roots` can be read from a config file, it is important
that we are able to resolve relative paths properly using the parent
folder of the config file as the base path.
2025-12-12 15:25:22 -08:00
zhao-oai e0fb3ca1db refactoring with_escalated_permissions to use SandboxPermissions instead (#7750)
helpful in the future if we want more granularity for requesting
escalated permissions:
e.g when running in readonly sandbox, model can request to escalate to a
sandbox that allows writes
2025-12-10 17:18:48 +00:00
Michael Bolin 67975ed33a refactor: inline sandbox type lookup in process_exec_tool_call (#7122)
`process_exec_tool_call()` was taking `SandboxType` as a param, but in
practice, the only place it was constructed was in
`codex_message_processor.rs` where it was derived from the other
`sandbox_policy` param, so this PR inlines the logic that decides the
`SandboxType` into `process_exec_tool_call()`.



---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/7122).
* #7112
* __->__ #7122
2025-11-21 22:53:05 +00:00
Michael Bolin f56d1dc8fc feat: update process_exec_tool_call() to take a cancellation token (#6972)
This updates `ExecParams` so that instead of taking `timeout_ms:
Option<u64>`, it now takes a more general cancellation mechanism,
`ExecExpiration`, which is an enum that includes a
`Cancellation(tokio_util::sync::CancellationToken)` variant.

If the cancellation token is fired, then `process_exec_tool_call()`
returns in the same way as if a timeout was exceeded.

This is necessary so that in #6973, we can manage the timeout logic
external to the `process_exec_tool_call()` because we want to "suspend"
the timeout when an elicitation from a human user is pending.








---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/6972).
* #7005
* #6973
* __->__ #6972
2025-11-20 16:29:57 -08:00
jif-oai aa76003e28 chore: unify config crates (#5958) 2025-10-30 10:28:32 +00:00
jif-oai 5e4f3bbb0b chore: rework tools execution workflow (#5278)
Re-work the tool execution flow. Read `orchestrator.rs` to understand
the structure
2025-10-20 20:57:37 +01:00
jif-oai be366a31ab chore: clippy on redundant closure (#4058)
Add redundant closure clippy rules and let Codex fix it by minimising
FQP
2025-09-22 19:30:16 +00:00
Michael Bolin 8595237505 fix: ensure cwd for conversation and sandbox are separate concerns (#3874)
Previous to this PR, both of these functions take a single `cwd`:


https://github.com/openai/codex/blob/71038381aa0f51aa62e1a2bcc7cbf26a05b141f3/codex-rs/core/src/seatbelt.rs#L19-L25


https://github.com/openai/codex/blob/71038381aa0f51aa62e1a2bcc7cbf26a05b141f3/codex-rs/core/src/landlock.rs#L16-L23

whereas `cwd` and `sandbox_cwd` should be set independently (fixed in
this PR).

Added `sandbox_distinguishes_command_and_policy_cwds()` to
`codex-rs/exec/tests/suite/sandbox.rs` to verify this.
2025-09-18 14:37:06 -07:00
pakrym-oai 863d9c237e Include command output when sending timeout to model (#3576)
Being able to see the output helps the model decide how to handle the
timeout.
2025-09-14 14:38:26 -07:00
Jeremy Rose 32bbbbad61 test: faster test execution in codex-core (#2633)
this dramatically improves time to run `cargo test -p codex-core` (~25x
speedup).

before:
```
cargo test -p codex-core  35.96s user 68.63s system 19% cpu 8:49.80 total
```

after:
```
cargo test -p codex-core  5.51s user 8.16s system 63% cpu 21.407 total
```

both tests measured "hot", i.e. on a 2nd run with no filesystem changes,
to exclude compile times.

approach inspired by [Delete Cargo Integration
Tests](https://matklad.github.io/2021/02/27/delete-cargo-integration-tests.html),
we move all test cases in tests/ into a single suite in order to have a
single binary, as there is significant overhead for each test binary
executed, and because test execution is only parallelized with a single
binary.
2025-08-24 11:10:53 -07:00