mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
permissions: make runtime config profile-backed (#19606)
## Why This supersedes #19391. During stack repair, GitHub marked #19391 as merged into a temporary stack branch rather than into `main`, so the runtime-config change needed a fresh PR. `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. The unrelated CI/test hardening that previously rode along with this PR has been split into #19683 so this PR stays focused on the permissions model migration. ## 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/19606). * #19395 * #19394 * #19393 * #19392 * __->__ #19606
This commit is contained in:
1 parent
fed0a8f4fa
commit
4d7ce3447d
62 files changed
+1601
-671
No files matched your search
@@ -5,13 +5,12 @@ use crate::bwrap::is_wsl1;
|
||||
use crate::landlock::CODEX_LINUX_SANDBOX_ARG0;
|
||||
use crate::landlock::allow_network_for_proxy;
|
||||
use crate::landlock::create_linux_sandbox_command_args_for_policies;
|
||||
use crate::policy_transforms::EffectiveSandboxPermissions;
|
||||
use crate::policy_transforms::effective_file_system_sandbox_policy;
|
||||
use crate::policy_transforms::effective_network_sandbox_policy;
|
||||
use crate::policy_transforms::effective_permission_profile;
|
||||
use crate::policy_transforms::should_require_platform_sandbox;
|
||||
use codex_network_proxy::NetworkProxy;
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
use codex_protocol::models::AdditionalPermissionProfile;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::permissions::FileSystemSandboxPolicy;
|
||||
use codex_protocol::permissions::NetworkSandboxPolicy;
|
||||
use codex_protocol::protocol::SandboxPolicy;
|
||||
@@ -80,6 +79,7 @@ pub struct SandboxExecRequest {
|
||||
pub sandbox: SandboxType,
|
||||
pub windows_sandbox_level: WindowsSandboxLevel,
|
||||
pub windows_sandbox_private_desktop: bool,
|
||||
pub permission_profile: PermissionProfile,
|
||||
pub sandbox_policy: SandboxPolicy,
|
||||
pub file_system_sandbox_policy: FileSystemSandboxPolicy,
|
||||
pub network_sandbox_policy: NetworkSandboxPolicy,
|
||||
@@ -91,9 +91,7 @@ pub struct SandboxExecRequest {
|
||||
/// This keeps call sites self-documenting when several fields are optional.
|
||||
pub struct SandboxTransformRequest<'a> {
|
||||
pub command: SandboxCommand,
|
||||
pub policy: &'a SandboxPolicy,
|
||||
pub file_system_policy: &'a FileSystemSandboxPolicy,
|
||||
pub network_policy: NetworkSandboxPolicy,
|
||||
pub permissions: &'a PermissionProfile,
|
||||
pub sandbox: SandboxType,
|
||||
pub enforce_managed_network: bool,
|
||||
// TODO(viyatb): Evaluate switching this to Option<Arc<NetworkProxy>>
|
||||
@@ -174,9 +172,7 @@ impl SandboxManager {
|
||||
) -> Result<SandboxExecRequest, SandboxTransformError> {
|
||||
let SandboxTransformRequest {
|
||||
mut command,
|
||||
policy,
|
||||
file_system_policy,
|
||||
network_policy,
|
||||
permissions,
|
||||
sandbox,
|
||||
enforce_managed_network,
|
||||
network,
|
||||
@@ -187,15 +183,16 @@ impl SandboxManager {
|
||||
windows_sandbox_private_desktop,
|
||||
} = request;
|
||||
let additional_permissions = command.additional_permissions.take();
|
||||
let EffectiveSandboxPermissions {
|
||||
sandbox_policy: effective_policy,
|
||||
} = EffectiveSandboxPermissions::new(policy, additional_permissions.as_ref());
|
||||
let effective_file_system_policy = effective_file_system_sandbox_policy(
|
||||
file_system_policy,
|
||||
additional_permissions.as_ref(),
|
||||
let effective_permission_profile =
|
||||
effective_permission_profile(permissions, additional_permissions.as_ref());
|
||||
let (effective_file_system_policy, effective_network_policy) =
|
||||
effective_permission_profile.to_runtime_permissions();
|
||||
let effective_policy = compatibility_sandbox_policy_for_permission_profile(
|
||||
&effective_permission_profile,
|
||||
&effective_file_system_policy,
|
||||
effective_network_policy,
|
||||
sandbox_policy_cwd,
|
||||
);
|
||||
let effective_network_policy =
|
||||
effective_network_sandbox_policy(network_policy, additional_permissions.as_ref());
|
||||
let mut argv = Vec::with_capacity(1 + command.args.len());
|
||||
argv.push(command.program);
|
||||
argv.extend(command.args.into_iter().map(OsString::from));
|
||||
@@ -264,6 +261,7 @@ impl SandboxManager {
|
||||
sandbox,
|
||||
windows_sandbox_level,
|
||||
windows_sandbox_private_desktop,
|
||||
permission_profile: effective_permission_profile,
|
||||
sandbox_policy: effective_policy,
|
||||
file_system_sandbox_policy: effective_file_system_policy,
|
||||
network_sandbox_policy: effective_network_policy,
|
||||
@@ -272,6 +270,50 @@ impl SandboxManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compatibility_sandbox_policy_for_permission_profile(
|
||||
permissions: &PermissionProfile,
|
||||
file_system_policy: &FileSystemSandboxPolicy,
|
||||
network_policy: NetworkSandboxPolicy,
|
||||
cwd: &Path,
|
||||
) -> SandboxPolicy {
|
||||
permissions
|
||||
.to_legacy_sandbox_policy(cwd)
|
||||
.unwrap_or_else(|_| {
|
||||
compatibility_workspace_write_policy(file_system_policy, network_policy, cwd)
|
||||
})
|
||||
}
|
||||
|
||||
fn compatibility_workspace_write_policy(
|
||||
file_system_policy: &FileSystemSandboxPolicy,
|
||||
network_policy: NetworkSandboxPolicy,
|
||||
cwd: &Path,
|
||||
) -> SandboxPolicy {
|
||||
let cwd_abs = AbsolutePathBuf::from_absolute_path(cwd).ok();
|
||||
let writable_roots = file_system_policy
|
||||
.get_writable_roots_with_cwd(cwd)
|
||||
.into_iter()
|
||||
.map(|root| root.root)
|
||||
.filter(|root| cwd_abs.as_ref() != Some(root))
|
||||
.collect();
|
||||
let tmpdir_writable = std::env::var_os("TMPDIR")
|
||||
.filter(|tmpdir| !tmpdir.is_empty())
|
||||
.and_then(|tmpdir| {
|
||||
AbsolutePathBuf::from_absolute_path(std::path::PathBuf::from(tmpdir)).ok()
|
||||
})
|
||||
.is_some_and(|tmpdir| file_system_policy.can_write_path_with_cwd(tmpdir.as_path(), cwd));
|
||||
let slash_tmp = Path::new("/tmp");
|
||||
let slash_tmp_writable = slash_tmp.is_absolute()
|
||||
&& slash_tmp.is_dir()
|
||||
&& file_system_policy.can_write_path_with_cwd(slash_tmp, cwd);
|
||||
|
||||
SandboxPolicy::WorkspaceWrite {
|
||||
writable_roots,
|
||||
network_access: network_policy.is_enabled(),
|
||||
exclude_tmpdir_env_var: !tmpdir_writable,
|
||||
exclude_slash_tmp: !slash_tmp_writable,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn ensure_linux_bubblewrap_is_supported(
|
||||
file_system_sandbox_policy: &FileSystemSandboxPolicy,
|
||||
|
||||
Reference in new issue
Block a user