permissions: canonicalize workspace_roots and danger-full-access names (#22624)

## Why

This is a small precursor to the larger permissions-migration work. Both
the comparison stack in
[#22401](https://github.com/openai/codex/pull/22401) /
[#22402](https://github.com/openai/codex/pull/22402) and the alternate
stack in [#22610](https://github.com/openai/codex/pull/22610) /
[#22611](https://github.com/openai/codex/pull/22611) /
[#22612](https://github.com/openai/codex/pull/22612) are easier to
review if the terminology is already settled underneath them.

Because `:project_roots` and `:danger-no-sandbox` have not shipped as
stable user-facing surface area, carrying them forward as aliases would
just add more migration logic to the later stacks. This PR removes that
ambiguity now so the follow-on work can rely on one spelling for each
built-in concept.

## What Changed

- renamed the config-facing special filesystem key from `:project_roots`
to `:workspace_roots`
- dropped unpublished `:project_roots` parsing support in
`core/src/config/permissions.rs`, so new config only recognizes
`:workspace_roots`
- renamed the built-in full-access permission profile id from
`:danger-no-sandbox` to `:danger-full-access`
- dropped unpublished `:danger-no-sandbox` support entirely, including
the old active-profile canonicalization path, and added explicit
rejection coverage for the legacy id
- introduced shared built-in permission-profile id constants in
`codex-rs/protocol/src/models.rs`
- updated `core`, `app-server`, and `tui` call sites that special-case
built-in profiles to use the shared constants and canonical ids
- updated tests and the Linux sandbox README to use `:workspace_roots` /
`:danger-full-access`

## Verification

I focused verification on the three places this rename can regress:
config parsing, active-profile identity surfaced back out of `core`, and
user/server call sites that special-case built-in profiles.

Targeted checks:

-
`config::tests::default_permissions_can_select_builtin_profile_without_permissions_table`
-
`config::tests::default_permissions_read_only_applies_additional_writable_roots_as_modifications`
-
`config::tests::default_permissions_can_select_builtin_full_access_profile`
- `config::tests::legacy_danger_no_sandbox_is_rejected`
- `workspace_root` filtered `codex-core` tests
-
`request_processors::thread_processor::thread_processor_tests::thread_processor_behavior_tests::requested_permissions_trust_project_uses_permission_profile_intent`
-
`suite::v2::turn_start::turn_start_rejects_invalid_permission_selection_before_starting_turn`
- `status::tests::status_snapshot_shows_auto_review_permissions`
-
`status::tests::status_permissions_full_disk_managed_with_network_is_danger_full_access`
-
`app_server_session::tests::embedded_turn_permissions_use_active_profile_selection`
This commit is contained in:
Michael Bolin
2026-05-14 08:45:54 -07:00
committed by GitHub
Unverified
parent 12bfb57139
commit 01d93fd9fc
16 changed files with 187 additions and 73 deletions
+11 -2
View File
@@ -297,6 +297,15 @@ impl ManagedFileSystemPermissions {
}
}
/// Reserved identifier for the built-in read-only permission profile.
pub const BUILT_IN_PERMISSION_PROFILE_READ_ONLY: &str = ":read-only";
/// Reserved identifier for the built-in workspace-write permission profile.
pub const BUILT_IN_PERMISSION_PROFILE_WORKSPACE: &str = ":workspace";
/// Reserved identifier for the built-in full-access permission profile.
pub const BUILT_IN_PERMISSION_PROFILE_DANGER_FULL_ACCESS: &str = ":danger-full-access";
/// Canonical active runtime permissions for a conversation, turn, or command.
#[derive(Debug, Clone, Eq, PartialEq, Serialize, JsonSchema, TS)]
#[serde(tag = "type", rename_all = "snake_case")]
@@ -402,7 +411,7 @@ impl PermissionProfile {
/// Managed workspace-write filesystem access with restricted network
/// access.
///
/// The returned profile contains symbolic `:project_roots` entries that
/// The returned profile contains symbolic `:workspace_roots` entries that
/// must be resolved against the active permission root before enforcement.
pub fn workspace_write() -> Self {
Self::workspace_write_with(
@@ -416,7 +425,7 @@ impl PermissionProfile {
/// Managed workspace-write filesystem access with the legacy
/// `sandbox_workspace_write` knobs applied directly to the profile.
///
/// The returned profile contains symbolic `:project_roots` entries that
/// The returned profile contains symbolic `:workspace_roots` entries that
/// must be resolved against the active permission root before enforcement.
pub fn workspace_write_with(
writable_roots: &[AbsolutePathBuf],
+2 -2
View File
@@ -695,7 +695,7 @@ impl FileSystemSandboxPolicy {
)
}
/// Replaces symbolic `:project_roots` entries with absolute paths resolved
/// Replaces symbolic `:workspace_roots` entries with absolute paths resolved
/// against `cwd`.
///
/// Use this when a durable permission profile must survive a cwd-only
@@ -763,7 +763,7 @@ impl FileSystemSandboxPolicy {
///
/// Unlike [`Self::with_additional_writable_roots`], this mirrors legacy
/// writable-roots semantics by adding exact roots even when they are
/// already writable through `:project_roots`, and by adding the default
/// already writable through `:workspace_roots`, and by adding the default
/// read-only protected subpaths for each new root.
pub fn with_additional_legacy_workspace_writable_roots(
mut self,