Skip to content

shell-escalation: carry resolved permission profiles#18287

Open
bolinfest wants to merge 1 commit intopr18286from
pr18287
Open

shell-escalation: carry resolved permission profiles#18287
bolinfest wants to merge 1 commit intopr18286from
pr18287

Conversation

@bolinfest
Copy link
Copy Markdown
Collaborator

@bolinfest bolinfest commented Apr 17, 2026

Why

Shell escalation still has adapter code that expects a legacy sandbox policy, but command approvals should carry the resolved PermissionProfile so callers can reason about the granted permissions canonically.

What changed

This introduces profile-shaped resolved escalation permissions while retaining the derived legacy sandbox policy for the Unix escalation adapter. It updates approval types, the escalation server protocol, and tests that inspect escalated command permissions.

Verification

  • cargo test -p codex-core --test all handle_container_exec_ -- --nocapture
  • cargo test -p codex-core --test all handle_sandbox_ -- --nocapture

Stack created with Sapling. Best reviewed with ReviewStack.

Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 41dbb548af

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +371 to +374
permission_profile: PermissionProfile::from_runtime_permissions(
file_system_sandbox_policy,
network_sandbox_policy,
),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep ExternalSandbox when building resolved permission profiles

Converting the rerun policy through PermissionProfile::from_runtime_permissions(...) drops the filesystem kind, so an ExternalSandbox policy is serialized as a generic root-write profile and later reconstructed as Restricted in prepare_escalated_exec (to_runtime_permissions). In the ExternalSandbox + network restricted case, this changes select_initial behavior from no extra sandbox to requiring a platform sandbox, so intercepted child processes can be unexpectedly re-sandboxed/denied after approval. Previously this path carried the concrete runtime policies directly and preserved ExternalSandbox semantics.

Useful? React with 👍 / 👎.

@bolinfest bolinfest force-pushed the pr18287 branch 2 times, most recently from 055fda9 to c1cbd7a Compare April 21, 2026 06:18
@bolinfest bolinfest force-pushed the pr18286 branch 2 times, most recently from bbb84c4 to c30a9a1 Compare April 21, 2026 16:19
@bolinfest bolinfest force-pushed the pr18287 branch 2 times, most recently from 0d5510c to bd8f2f9 Compare April 21, 2026 17:44
bolinfest added a commit that referenced this pull request Apr 22, 2026
## Why

#18275 anchors session-scoped `:cwd` and `:project_roots` grants to the
request cwd before recording them for reuse. Relative deny glob entries
need the same treatment. Without anchoring, a stored session permission
can keep a pattern such as `**/*.env` relative, then reinterpret that
deny against a later turn cwd. That makes the persisted profile depend
on the cwd at reuse time instead of the cwd that was reviewed and
approved.

## What changed

`intersect_permission_profiles` now materializes retained
`FileSystemPath::GlobPattern` entries against the request cwd, matching
the existing materialization for cwd-sensitive special paths.

Materialized accepted grants are now deduplicated before deny retention
runs. This keeps the sticky-grant preapproval shape stable when a
repeated request is merged with the stored grant and both `:cwd = write`
and the materialized absolute cwd write are present.

The preapproval check compares against the same materialized form, so a
later request for the same cwd-relative deny glob still matches the
stored anchored grant instead of re-prompting or rejecting.

Tests cover both the storage path and the preapproval path: a
session-scoped `:cwd = write` grant with `**/*.env = none` is stored
with both the cwd write and deny glob anchored to the original request
cwd, cannot be reused from a later cwd, and remains preapproved when
re-requested from the original cwd after merging with the stored grant.

## Verification

- `cargo test -p codex-sandboxing policy_transforms`
- `cargo test -p codex-core --lib
relative_deny_glob_grants_remain_preapproved_after_materialization`
- `cargo clippy -p codex-sandboxing --tests -- -D
clippy::redundant_clone`
- `cargo clippy -p codex-core --lib -- -D clippy::redundant_clone`

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/18867).
* #18288
* #18287
* #18286
* #18285
* #18284
* #18283
* #18282
* #18281
* #18280
* #18279
* #18278
* #18277
* #18276
* __->__ #18867
@bolinfest bolinfest force-pushed the pr18287 branch 2 times, most recently from 1ffa050 to 4eea596 Compare April 22, 2026 03:23
bolinfest added a commit that referenced this pull request Apr 22, 2026
## Why

`Permissions` should not store a separate `PermissionProfile` that can
drift from the constrained `SandboxPolicy` and network settings. The
active profile needs to be derived from the same constrained values that
already honor `requirements.toml`.

## What changed

This adds derivation of the active `PermissionProfile` from the
constrained runtime permission settings and exposes that derived value
through config snapshots and thread state. The app-server can then
report the active profile without introducing a second source of truth.

## Verification

- `cargo test -p codex-core --test all permissions_messages --
--nocapture`
- `cargo test -p codex-core --test all request_permissions --
--nocapture`



























---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/18277).
* #18288
* #18287
* #18286
* #18285
* #18284
* #18283
* #18282
* #18281
* #18280
* #18279
* #18278
* __->__ #18277
@bolinfest bolinfest force-pushed the pr18287 branch 2 times, most recently from d9e2355 to e42d384 Compare April 22, 2026 06:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant