Commit Graph
12232 Commits
Author SHA1 Message Date
Michael Bolin 4a2bbe60c5 Merge f0cadb0270 into sapling-pr-archive-bolinfest 2026-04-21 11:05:02 -07:00
Michael Bolin f0cadb0270 sandboxing: materialize cwd-relative permission globs 2026-04-21 11:00:58 -07:00
Ruslan Nigmatullin 5bab04dcd7 app-server: add codex-device-key crate (#18429)
## Why

Device-key storage and signing are local security-sensitive operations
with platform-specific behavior. Keeping the core API in
`codex-device-key` keeps app-server focused on routing and business
logic instead of owning key-management details.

The crate keeps the signing surface intentionally narrow: callers can
create a bound key, fetch its public key, or sign one of the structured
payloads accepted by the crate. It does not expose a generic
arbitrary-byte signing API.

Key IDs cross into platform-specific labels, tags, and metadata paths,
so externally supplied IDs are constrained to the same auditable
namespace created by the crate: `dk_` followed by unpadded base64url for
32 bytes. Remote-control target paths are also tied to each signed
payload shape so connection proofs cannot be reused for enrollment
endpoints, or vice versa.

## What changed

- Added the `codex-device-key` workspace crate.
- Added account/client-bound key creation with stable `dk_` key IDs.
- Added strict `key_id` validation before public-key lookup or signing
reaches a provider.
- Added public-key lookup and structured signing APIs.
- Split remote-control client endpoint allowlists by connection vs
enrollment payload shape.
- Added validation for key bindings, accepted payload fields, token
expiration, and payload/key binding mismatches.
- Added flow-oriented docs on the validation helpers that gate provider
signing.
- Added protection policy and protection-class types without wiring a
platform provider yet.
- Added an unsupported default provider so platforms without an
implementation fail explicitly instead of silently falling back to
software-backed keys.
- Updated Cargo and Bazel lock metadata for the new crate and
non-platform-specific dependencies.

## Stack

This is stacked on #18428.

## Validation

- `cargo test -p codex-device-key`
- Added unit coverage for strict `key_id` validation before provider
use.
- Added unit coverage that rejects remote-control paths from the wrong
signed payload shape.
- `just bazel-lock-update`
- `just bazel-lock-check`
2026-04-21 17:57:00 +00:00
8612714aa6 Add Windows sandbox unified exec runtime support (#15578)
## Summary

This is the runtime/foundation half of the Windows sandbox unified-exec
work.

- add Windows sandbox `unified_exec` session support in
`windows-sandbox-rs` for both:
  - the legacy restricted-token backend
  - the elevated runner backend
- extend the PTY/process runtime so driver-backed sessions can support:
  - stdin streaming
  - stdout/stderr separation
  - exit propagation
  - PTY resize hooks
- add Windows sandbox runtime coverage in `codex-windows-sandbox` /
`codex-utils-pty`

This PR does **not** enable Windows sandbox `UnifiedExec` for product
callers yet because hooking this up to app-server comes in the next PR.

Windows sandbox advertising is intentionally kept aligned with `main`,
so sandboxed Windows callers still fall back to `ShellCommand`.

This PR isolates the runtime/session layer so it can be reviewed
independently from product-surface enablement.

---------

Co-authored-by: jif-oai <jif@openai.com>
Co-authored-by: Codex <noreply@openai.com>
2026-04-21 10:44:49 -07:00
Michael Bolin c38d67a009 Merge d26056285f into sapling-pr-archive-bolinfest 2026-04-21 10:44:13 -07:00
Michael Bolin d26056285f tests: isolate approval fixtures from host rules 2026-04-21 10:40:32 -07:00
Michael Bolin bd8f2f9861 shell-escalation: carry resolved permission profiles 2026-04-21 10:40:32 -07:00
Michael Bolin ac87f8dc91 mcp: include permission profiles in sandbox state 2026-04-21 10:40:32 -07:00
Michael Bolin 9ed50c0e71 tui: carry permission profiles on user turns 2026-04-21 10:40:32 -07:00
Michael Bolin 93441b62fd tui: sync session permission profiles 2026-04-21 10:40:32 -07:00
Michael Bolin 98f3ab68e7 app-server: accept command permission profiles 2026-04-21 10:40:32 -07:00
Michael Bolin 24a8186010 protocol: report session permission profiles 2026-04-21 10:40:32 -07:00
Michael Bolin fd63861883 rollout: persist turn permission profiles 2026-04-21 10:40:32 -07:00
Michael Bolin 447123caa8 clients: send permission profiles to app-server 2026-04-21 10:40:32 -07:00
Michael Bolin a8aa1b2bf3 app-server: accept permission profile overrides 2026-04-21 10:40:32 -07:00
Michael Bolin c503582661 app-server: expose thread permission profiles 2026-04-21 10:40:32 -07:00
Michael Bolin 8a10b7dd51 core: derive active permission profiles 2026-04-21 10:40:32 -07:00
Michael Bolin cacb5de94e exec-server: carry filesystem sandbox profiles 2026-04-21 10:40:32 -07:00
Michael Bolin 9f863363a1 sandboxing: materialize cwd-relative permission globs 2026-04-21 10:40:25 -07:00
Michael Bolin 54a57a0de6 Merge 1aae3d3b02 into sapling-pr-archive-bolinfest 2026-04-21 10:27:23 -07:00
Michael Bolin 1aae3d3b02 tests: isolate approval fixtures from host rules 2026-04-21 10:26:15 -07:00
Michael Bolin 0d5510c549 shell-escalation: carry resolved permission profiles 2026-04-21 10:25:04 -07:00
Michael Bolin e8c3569a3c mcp: include permission profiles in sandbox state 2026-04-21 10:25:04 -07:00
Michael Bolin 255490b98d tui: carry permission profiles on user turns 2026-04-21 10:25:04 -07:00
Michael Bolin 8d1ce90d59 tui: sync session permission profiles 2026-04-21 10:25:03 -07:00
Michael Bolin 02b498e158 app-server: accept command permission profiles 2026-04-21 10:25:03 -07:00
Michael Bolin fa4dc621f7 protocol: report session permission profiles 2026-04-21 10:25:02 -07:00
Steve Coffey 38ba876ea9 Refresh generated Python app-server SDK types (#18862)
This is the first step in splitting the Python SDK PyPI publish work
into reviewable layers: land the generated SDK refresh by itself before
changing packaging mechanics. The next PRs will make the runtime wheel
publishable, then wire the SDK package/version pinning to that runtime.

## Summary
- Refresh generated Python app-server v2 models and notification
registry from the current schema.
- Update the public API signature expectations for the newly generated
kwargs.

## Stack
- PR 1 of 3 for the Python SDK PyPI publishing split.
- Follow-up PRs will handle runtime wheel publishing mechanics, then
SDK/package version pinning.

## Tests
- `uv run --extra dev pytest` in `sdk/python` -> 51 passed, 37 skipped.
2026-04-21 10:23:27 -07:00
Michael Bolin ff27339587 rollout: persist turn permission profiles 2026-04-21 10:23:20 -07:00
Michael Bolin 4ddcab277b clients: send permission profiles to app-server 2026-04-21 10:23:20 -07:00
Michael Bolin c89723329e app-server: accept permission profile overrides 2026-04-21 10:23:20 -07:00
Michael Bolin 6c59e78192 app-server: expose thread permission profiles 2026-04-21 10:23:20 -07:00
Michael Bolin 2089eb5d64 core: derive active permission profiles 2026-04-21 10:23:20 -07:00
Michael Bolin 5b7a782053 exec-server: carry filesystem sandbox profiles 2026-04-21 10:23:20 -07:00
Michael Bolin f8562bd47b sandboxing: intersect permission profiles semantically (#18275)
## Why

Permission approval responses must not be able to grant more access than
the tool requested. Moving this flow to `PermissionProfile` means the
comparison must be profile-shaped instead of `SandboxPolicy`-shaped, and
cwd-relative special paths such as `:cwd` and `:project_roots` must stay
anchored to the turn that produced the request.

## What changed

This implements semantic `PermissionProfile` intersection in
`codex-sandboxing` for file-system and network permissions. The
intersection accepts narrower path grants, rejects broader grants,
preserves deny-read carve-outs and glob scan depth, and materializes
cwd-dependent special-path grants to absolute paths before they can be
recorded for reuse.

The request-permissions response paths now use that intersection
consistently. App-server captures the request turn cwd before waiting
for the client response, includes that cwd in the v2 approval params,
and core stores the requested profile plus cwd for direct TUI/client
responses and Guardian decisions before recording turn- or
session-scoped grants. The TUI app-server bridge now preserves the
app-server request cwd when converting permission approval params into
core events.

## Verification

- `cargo test -p codex-sandboxing intersect_permission_profiles --
--nocapture`
- `cargo test -p codex-app-server request_permissions_response --
--nocapture`
- `cargo test -p codex-core
request_permissions_response_materializes_session_cwd_grants_before_recording
-- --nocapture`
- `cargo check -p codex-tui --tests`
- `cargo check --tests`
- `cargo test -p codex-tui
app_server_request_permissions_preserves_file_system_permissions`
2026-04-21 10:23:01 -07:00
pakrym-oai 2a226096f6 Split DeveloperInstructions into individual fragments. (#18813)
Split DeveloperInstructions into individual fragments.
2026-04-21 10:22:36 -07:00
pakrym-oai 5fe767e8e1 Refactor app-server config loading into ConfigManager (#18442)
Localize app-server configuration loading in one place.
2026-04-21 10:22:26 -07:00
Eric Traut 4ed722ab8d Move TUI app tests to modules they cover (#18799)
## Summary

The TUI app refactor in #18753 moved the old `app.rs` tests into a
single `app/tests.rs` file. That kept the split mechanically simple, but
it left several focused unit tests far from the modules they exercise.

This PR is a follow-up that moves tests next to the code they cover.

It also adds `tui/src/app/test_support.rs` for shared fixture
construction.

This is just a mechanical refactoring (no functional changes) and does
not affect any production code.
2026-04-21 10:16:51 -07:00
jif-oai 10e1659d4f Stabilize debug clear memories integration test (#18858)
## Why

`debug_clear_memories_resets_state_and_removes_memory_dir` can be flaky
because the test drops its `sqlx::SqlitePool` immediately before
invoking `codex debug clear-memories`. Dropping the pool does not wait
for all SQLite connections to close, so the CLI can race with still-open
test connections.

## What changed

- Await `pool.close()` before spawning `codex debug clear-memories`.
- Close the reopened verification pool before the temp `CODEX_HOME` is
torn down.

## Verification

- `cargo test -p codex-cli --test debug_clear_memories
debug_clear_memories_resets_state_and_removes_memory_dir`
2026-04-21 18:15:37 +01:00
Eric Traut b7fec54354 Queue follow-up input during user shell commands (#18820)
Fixes #17954.

## Why
When a manual shell command like `!sleep 10` is running, submitting
plain text such as `hi` currently sends that text as a steer for the
active shell turn. User shell turns are not steerable like model turns,
so the TUI can remain stuck in `Working` after the shell command
finishes.

## What Changed
- Detect when the only active work is one or more
`ExecCommandSource::UserShell` commands.
- Queue plain submitted input in that state so it drains after the shell
command and shell turn complete.
- Preserve `!cmd` submissions during running work so explicit shell
commands keep their existing behavior.
- Add regression coverage for the `!sleep 10` plus `hi` flow in
`chatwidget::tests::exec_flow::user_message_during_user_shell_command_is_queued_not_steered`.

## Verification
- Manually confirmed hang before the fix and no hang after the fix
2026-04-21 10:13:13 -07:00
Casey ChowandCodex 41652665f5 [codex] Add tmux-aware OSC 9 notifications (#17836)
## Summary
- wrap OSC 9 notifications in tmux's DCS passthrough so terminal
notifications make it through tmux
- use codex-terminal-detection for OSC 9 auto-selection so tmux sessions
inherit the underlying client terminal support
- add focused notification backend tests for plain OSC 9 and
tmux-wrapped output

## Stack
- base PR: #18479
- review order: #18479, then this PR

## Why
Tmux does not forward OSC 9 notifications directly; the sequence has to
be wrapped in tmux's DCS passthrough envelope. Codex also had local
notification heuristics that could miss supported terminals when running
under tmux, even though codex-terminal-detection already knows how to
attribute tmux sessions to the client terminal.

## Validation
- `just fmt`
- `cargo test -p codex-tui` *(currently blocked by an unrelated existing
compile error in `app-server/src/message_processor.rs:754` referencing
`connection_id` out of scope; not caused by this change)*

Co-authored-by: Codex <noreply@openai.com>
2026-04-21 17:10:36 +00:00
Rennie 3a9df58d06 Propagate thread id in MCP tool metadata (#18093)
## Summary
- attach the authoritative Codex thread id to MCP tool request
`_meta.threadId` for model-initiated tool calls
- attach the same thread id for manual `mcpServer/tool/call` requests
before invoking the MCP server
- cover both metadata helper behavior and the manual app-server MCP path
in tests


needed because the Rust app-server is the last place that still has
authoritative knowledge of “this model-generated MCP tool call belongs
to conversation/thread X” before the request leaves Codex and reaches
Hoopa. It adds threadId to MCP request metadata in the model-generated
tool-call path, using sess.conversation_id, and also does the same for
the manual mcpServer/tool/call path.

## Test plan
- `cargo test -p codex-core
mcp_tool_call_thread_id_meta_is_added_to_request_meta --lib`
- `cargo test -p codex-app-server
mcp_server_tool_call_returns_tool_result`

Paired Hoopa consumer PR: https://github.com/openai/openai/pull/833263
2026-04-21 10:09:46 -07:00
Ruslan Nigmatullin 48f82ca7c5 app-server: define device key v2 protocol (#18428)
## Why

Clients need a stable app-server protocol surface for enrolling a local
device key, retrieving its public key, and producing a device-bound
proof.

The protocol reports `protectionClass` explicitly so clients can
distinguish hardware-backed keys from an explicitly allowed OS-protected
fallback. Signing uses a tagged `DeviceKeySignPayload` enum rather than
arbitrary bytes so each signed statement is auditable at the API
boundary.

## What changed

- Added v2 JSON-RPC methods for `device/key/create`,
`device/key/public`, and `device/key/sign`.
- Added request/response types for device-key metadata, SPKI public
keys, protection classes, and ECDSA signatures.
- Added `DeviceKeyProtectionPolicy` with hardware-only default behavior
and an explicit `allow_os_protected_nonextractable` option.
- Added the initial `remoteControlClientConnection` signing payload
variant.
- Regenerated JSON Schema and TypeScript fixtures for app-server
clients.

## Stack

This is PR 1 of 4 in the device-key app-server stack.

## Validation

- `just write-app-server-schema`
- `cargo test -p codex-app-server-protocol`
2026-04-21 10:08:42 -07:00
Michael Bolin b06fc8bd0d core: make test-log a dev dependency (#18846)
The `test-log` crate is only used by `codex-core` tests, so it does not
need
to be part of the normal `codex-core` dependency graph. Keeping
`test-log` in
`dev-dependencies` removes it from normal `codex-core` builds and keeps
the
production dependency set a little smaller.

Verification:

- `cargo tree -p codex-core --edges normal --invert test-log`
- `cargo check -p codex-core --lib`
- `cargo test -p codex-core --lib`
2026-04-21 09:48:31 -07:00
Michael Bolin 5a6128916a merge commit for archive created by Sapling 2026-04-21 09:45:40 -07:00
Michael Bolin fee24f3d5f sandboxing: intersect permission profiles semantically 2026-04-21 09:45:24 -07:00
Michael Bolin ad55e6e55e merge commit for archive created by Sapling 2026-04-21 09:31:06 -07:00
Michael Bolin 9a98ccbefc sandboxing: intersect permission profiles semantically 2026-04-21 09:30:47 -07:00
jif-oai bf2a34b4b2 feat: baseline lib (#18848)
This add with 2 entry point:
* `reset_git_repository` that takes a directory and set it as a new git
root
* `diff_since_latest_init` this returns the diff for a given directory
since the last `reset_git_repository`
2026-04-21 17:24:30 +01:00
Michael Bolin f8f2b36f6b Merge 33512fc391 into sapling-pr-archive-bolinfest 2026-04-21 09:19:21 -07:00