Skip to content

permissions: migrate approval and sandbox consumers to profiles#19393

Merged
bolinfest merged 1 commit intomainfrom
pr19393
Apr 26, 2026
Merged

permissions: migrate approval and sandbox consumers to profiles#19393
bolinfest merged 1 commit intomainfrom
pr19393

Conversation

@bolinfest
Copy link
Copy Markdown
Collaborator

@bolinfest bolinfest commented Apr 24, 2026

Why

Runtime decisions should not infer permissions from the lossy legacy sandbox projection once PermissionProfile is available. In particular, Disabled and External need to remain distinct, and managed profiles with split filesystem or deny-read rules should not be collapsed before approval, network, safety, or analytics code makes decisions.

What Changed

  • Changes managed network proxy setup and network approval logic to use PermissionProfile when deciding whether a managed sandbox is active.
  • Migrates patch safety, Guardian/user-shell approval paths, Landlock helper setup, analytics sandbox classification, and selected turn/session code to profile-backed permissions.
  • Validates command-level profile overrides against the constrained PermissionProfile rather than a strict SandboxPolicy round trip.
  • Preserves configured deny-read restrictions when command profiles are narrowed.
  • Adds coverage for profile-backed trust, network proxy/approval behavior, patch safety, analytics classification, and command-profile narrowing.

Verification

  • cargo test -p codex-core direct_write_roots
  • cargo test -p codex-core runtime_roots_to_legacy_projection
  • cargo test -p codex-app-server requested_permissions_trust_project_uses_permission_profile_intent

Stack created with Sapling. Best reviewed with ReviewStack.

@bolinfest bolinfest requested a review from a team as a code owner April 24, 2026 16:02
@bolinfest bolinfest force-pushed the pr19392 branch 2 times, most recently from c31129d to d51f2b9 Compare April 24, 2026 16:13
@bolinfest bolinfest force-pushed the pr19393 branch 2 times, most recently from 6481b36 to fc44eac Compare April 24, 2026 16:19
@bolinfest bolinfest force-pushed the pr19393 branch 2 times, most recently from bb5e9e1 to 2665e60 Compare April 24, 2026 16:47
@bolinfest bolinfest force-pushed the pr19392 branch 2 times, most recently from 37ef901 to f805b17 Compare April 24, 2026 17:05
@bolinfest bolinfest force-pushed the pr19393 branch 2 times, most recently from 79f119e to 7989a49 Compare April 24, 2026 17:18
@bolinfest bolinfest force-pushed the pr19392 branch 2 times, most recently from a28edf9 to eb0ab78 Compare April 24, 2026 18:08
@bolinfest bolinfest force-pushed the pr19392 branch 2 times, most recently from e8e9902 to 6832fed Compare April 24, 2026 20:19
bolinfest added a commit that referenced this pull request Apr 24, 2026
## Why

The profile conversion path still required a `cwd` even when it was only
translating a legacy `SandboxPolicy` into a `PermissionProfile`. That
made profile producers invent an ambient `cwd`, which is exactly the
anchoring we are trying to remove from permission-profile data. A legacy
workspace-write policy can be represented symbolically instead: `:cwd =
write` plus read-only `:project_roots` metadata subpaths.

This PR creates that cwd-free base so the rest of the stack can stop
threading cwd through profile construction. Callers that actually need a
concrete runtime filesystem policy for a specific cwd still have an
explicitly named cwd-bound conversion.

## What Changed

- `PermissionProfile::from_legacy_sandbox_policy` now takes only
`&SandboxPolicy`.
- `FileSystemSandboxPolicy::from_legacy_sandbox_policy` is now the
symbolic, cwd-free projection for profiles.
- The old concrete projection is retained as
`FileSystemSandboxPolicy::from_legacy_sandbox_policy_for_cwd` for
runtime/boundary code that must materialize legacy cwd behavior.
- Workspace-write profiles preserve `CurrentWorkingDirectory` and
`ProjectRoots` special entries instead of materializing cwd into
absolute paths.

## Verification

- `cargo check -p codex-protocol -p codex-core -p
codex-app-server-protocol -p codex-app-server -p codex-exec -p
codex-exec-server -p codex-tui -p codex-sandboxing -p
codex-linux-sandbox -p codex-analytics --tests`
- `just fix -p codex-protocol -p codex-core -p codex-app-server-protocol
-p codex-app-server -p codex-exec -p codex-exec-server -p codex-tui -p
codex-sandboxing -p codex-linux-sandbox -p codex-analytics`




---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/19414).
* #19395
* #19394
* #19393
* #19392
* #19391
* __->__ #19414
@bolinfest bolinfest force-pushed the pr19393 branch 2 times, most recently from 7ef8fba to a655a3e Compare April 25, 2026 03:42
@bolinfest bolinfest force-pushed the pr19393 branch 2 times, most recently from b55d950 to 828b90d Compare April 25, 2026 04:23
@bolinfest bolinfest force-pushed the pr19392 branch 2 times, most recently from ac08756 to 6ceba5b Compare April 25, 2026 15:57
@bolinfest bolinfest force-pushed the pr19393 branch 2 times, most recently from 0f8b225 to 480c5cb Compare April 25, 2026 22:28
@bolinfest bolinfest force-pushed the pr19392 branch 2 times, most recently from 25ada29 to f51435f Compare April 25, 2026 22:46
bolinfest added a commit that referenced this pull request Apr 25, 2026
## Why

`PermissionProfile` is now the canonical permissions shape after #19231
because it can distinguish `Managed`, `Disabled`, and `External`
enforcement while also carrying filesystem rules that legacy
`SandboxPolicy` cannot represent cleanly. Core config and session state
still needed to accept profile-backed permissions without forcing every
profile through the strict legacy bridge, which rejected valid runtime
profiles such as direct write roots.

## What Changed

- Adds `Permissions.permission_profile` and
`SessionConfiguration.permission_profile` as constrained runtime state,
while keeping `sandbox_policy` as a legacy compatibility projection.
- Introduces profile setters that keep `PermissionProfile`, split
filesystem/network policies, and legacy `SandboxPolicy` projections
synchronized.
- Uses a compatibility projection for requirement checks and legacy
consumers instead of rejecting profiles that cannot round-trip through
`SandboxPolicy` exactly.
- Updates config loading, config overrides, session updates, turn
context plumbing, prompt permission text, sandbox tags, and exec request
construction to carry profile-backed runtime permissions.
- Preserves configured deny-read entries and `glob_scan_max_depth` when
command/session profiles are narrowed.
- Adds `PermissionProfile::read_only()` and
`PermissionProfile::workspace_write()` presets that match legacy
defaults.

## Verification

- `cargo test -p codex-core direct_write_roots`
- `cargo test -p codex-core runtime_roots_to_legacy_projection`
- `cargo test -p codex-app-server
requested_permissions_trust_project_uses_permission_profile_intent`













---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/19391).
* #19395
* #19394
* #19393
* #19392
* __->__ #19391
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants