mirror of
https://github.com/openai/codex.git
synced 2026-10-31 16:14:50 +00:00
Migrate legacy exec policy allow rules (#34271)
## What changed - On session startup, remove exact `allow` entries from `rules/default.rules` for command prefixes that Codex no longer suggests as policy amendments. - Record the migration in `.sandbox_migration` so it runs only once, preserving rules created after the migration. - Skip the migration when user and project exec policy rules are ignored. - Expand the protected prefix list across shells, interpreters, package runners, and destructive or privilege-related commands. ## Testing - Cover selective removal, case-insensitive matching, one-time behavior, and the startup path with ignored policy rules. GitOrigin-RevId: a0c60e3f82b9630e621fd034b40462e3ab775102
This commit is contained in:
@@ -50,53 +50,95 @@ const REJECT_RULES_APPROVAL_REASON: &str =
|
||||
const RULES_DIR_NAME: &str = "rules";
|
||||
const RULE_EXTENSION: &str = "rules";
|
||||
const DEFAULT_POLICY_FILE: &str = "default.rules";
|
||||
static BANNED_PREFIX_SUGGESTIONS: &[&[&str]] = &[
|
||||
&["python3"],
|
||||
&["python3", "-"],
|
||||
&["python3", "-c"],
|
||||
&["python"],
|
||||
&["python", "-"],
|
||||
&["python", "-c"],
|
||||
&["py"],
|
||||
&["py", "-3"],
|
||||
&["pythonw"],
|
||||
&["pyw"],
|
||||
&["pypy"],
|
||||
&["pypy3"],
|
||||
&["git"],
|
||||
&["bash"],
|
||||
&["bash", "-lc"],
|
||||
&["sh"],
|
||||
&["sh", "-c"],
|
||||
&["sh", "-lc"],
|
||||
&["zsh"],
|
||||
&["zsh", "-lc"],
|
||||
&["/bin/zsh"],
|
||||
&["/bin/zsh", "-lc"],
|
||||
pub(crate) static BANNED_PREFIX_SUGGESTIONS: &[&[&str]] = &[
|
||||
&["/bin/bash"],
|
||||
&["/bin/bash", "-c"],
|
||||
&["/bin/bash", "-lc"],
|
||||
&["pwsh"],
|
||||
&["pwsh", "-Command"],
|
||||
&["pwsh", "-c"],
|
||||
&["/bin/sh"],
|
||||
&["/bin/sh", "-c"],
|
||||
&["/bin/sh", "-lc"],
|
||||
&["/bin/zsh"],
|
||||
&["/bin/zsh", "-c"],
|
||||
&["/bin/zsh", "-lc"],
|
||||
&["Rscript"],
|
||||
&["bash"],
|
||||
&["bash", "-c"],
|
||||
&["bash", "-lc"],
|
||||
&["bun"],
|
||||
&["bun", "-e"],
|
||||
&["bun", "run"],
|
||||
&["cmd"],
|
||||
&["cmd", "/c"],
|
||||
&["cmd", "/k"],
|
||||
&["cmd.exe"],
|
||||
&["cmd.exe", "/c"],
|
||||
&["cmd.exe", "/k"],
|
||||
&["dash"],
|
||||
&["dash", "-c"],
|
||||
&["deno"],
|
||||
&["deno", "eval"],
|
||||
&["env"],
|
||||
&["fish"],
|
||||
&["fish", "-c"],
|
||||
&["git"],
|
||||
&["julia"],
|
||||
&["julia", "-e"],
|
||||
&["ksh"],
|
||||
&["ksh", "-c"],
|
||||
&["lua"],
|
||||
&["lua", "-e"],
|
||||
&["node"],
|
||||
&["node", "-e"],
|
||||
&["nodejs"],
|
||||
&["nodejs", "-e"],
|
||||
&["npm", "run"],
|
||||
&["osascript"],
|
||||
&["perl"],
|
||||
&["perl", "-e"],
|
||||
&["php"],
|
||||
&["php", "-r"],
|
||||
&["pnpm", "run"],
|
||||
&["powershell"],
|
||||
&["powershell", "-Command"],
|
||||
&["powershell", "-EncodedCommand"],
|
||||
&["powershell", "-File"],
|
||||
&["powershell", "-c"],
|
||||
&["powershell.exe"],
|
||||
&["powershell.exe", "-Command"],
|
||||
&["powershell.exe", "-EncodedCommand"],
|
||||
&["powershell.exe", "-File"],
|
||||
&["powershell.exe", "-c"],
|
||||
&["env"],
|
||||
&["sudo"],
|
||||
&["node"],
|
||||
&["node", "-e"],
|
||||
&["perl"],
|
||||
&["perl", "-e"],
|
||||
&["pwsh"],
|
||||
&["pwsh", "-Command"],
|
||||
&["pwsh", "-EncodedCommand"],
|
||||
&["pwsh", "-File"],
|
||||
&["pwsh", "-c"],
|
||||
&["pwsh", "-e"],
|
||||
&["pwsh", "-ec"],
|
||||
&["pwsh", "-f"],
|
||||
&["py"],
|
||||
&["py", "-3"],
|
||||
&["pypy"],
|
||||
&["pypy3"],
|
||||
&["python"],
|
||||
&["python", "-"],
|
||||
&["python", "-c"],
|
||||
&["python3"],
|
||||
&["python3", "-"],
|
||||
&["python3", "-c"],
|
||||
&["pythonw"],
|
||||
&["pyw"],
|
||||
&["rm"],
|
||||
&["ruby"],
|
||||
&["ruby", "-e"],
|
||||
&["php"],
|
||||
&["php", "-r"],
|
||||
&["lua"],
|
||||
&["lua", "-e"],
|
||||
&["osascript"],
|
||||
&["sh"],
|
||||
&["sh", "-c"],
|
||||
&["sh", "-lc"],
|
||||
&["sudo"],
|
||||
&["yarn", "run"],
|
||||
&["zsh"],
|
||||
&["zsh", "-c"],
|
||||
&["zsh", "-lc"],
|
||||
];
|
||||
|
||||
/// Describes which unmatched-command heuristics should classify the command
|
||||
@@ -796,7 +838,7 @@ fn profile_has_managed_filesystem_restrictions(permission_profile: &PermissionPr
|
||||
&& !file_system_sandbox_policy.has_full_disk_write_access()
|
||||
}
|
||||
|
||||
fn default_policy_path(codex_home: &Path) -> PathBuf {
|
||||
pub(crate) fn default_policy_path(codex_home: &Path) -> PathBuf {
|
||||
codex_home.join(RULES_DIR_NAME).join(DEFAULT_POLICY_FILE)
|
||||
}
|
||||
|
||||
|
||||
@@ -1946,6 +1946,7 @@ fn derive_requested_execpolicy_amendment_returns_none_for_shell_and_powershell_v
|
||||
vec!["pwsh".to_string()],
|
||||
vec!["pwsh".to_string(), "-Command".to_string()],
|
||||
vec!["pwsh".to_string(), "-c".to_string()],
|
||||
vec!["pwsh".to_string(), "-ec".to_string()],
|
||||
vec!["powershell".to_string()],
|
||||
vec!["powershell".to_string(), "-Command".to_string()],
|
||||
vec!["powershell".to_string(), "-c".to_string()],
|
||||
|
||||
@@ -33,7 +33,9 @@ use crate::context::world_state::WorldState;
|
||||
use crate::current_time::TimeProvider;
|
||||
use crate::default_skill_metadata_budget;
|
||||
use crate::environment_selection::TurnEnvironmentSnapshot;
|
||||
use crate::exec_policy::BANNED_PREFIX_SUGGESTIONS;
|
||||
use crate::exec_policy::ExecPolicyManager;
|
||||
use crate::exec_policy::default_policy_path;
|
||||
use crate::image_preparation::prepare_response_items as prepare_image_response_items;
|
||||
use crate::parse_turn_item;
|
||||
use crate::realtime_conversation::RealtimeConversationManager;
|
||||
@@ -57,6 +59,7 @@ use codex_connectors::connector_runtime_context_key;
|
||||
use codex_core_skills::injection::HostSkillsCatalogInWorldState;
|
||||
use codex_exec_server::Environment;
|
||||
use codex_exec_server::EnvironmentManager;
|
||||
use codex_execpolicy::prefix_rule_migration;
|
||||
use codex_extension_api::ExtensionDataInit;
|
||||
use codex_extension_api::LoadedUserInstructions;
|
||||
use codex_extension_api::PromptFragment;
|
||||
@@ -549,6 +552,22 @@ impl Session {
|
||||
} else if let Some(exec_policy) = &inherited_exec_policy {
|
||||
Arc::clone(exec_policy)
|
||||
} else {
|
||||
if !config
|
||||
.config_layer_stack
|
||||
.ignore_user_and_project_exec_policy_rules()
|
||||
{
|
||||
let codex_home = config.codex_home.clone();
|
||||
let policy_path = default_policy_path(codex_home.as_path());
|
||||
if let Err(err) = prefix_rule_migration(
|
||||
codex_home.as_path(),
|
||||
policy_path.as_path(),
|
||||
BANNED_PREFIX_SUGGESTIONS,
|
||||
)
|
||||
.await
|
||||
{
|
||||
tracing::warn!(error = %err, "failed to run prefix rule migration");
|
||||
}
|
||||
}
|
||||
Arc::new(
|
||||
ExecPolicyManager::load(&config.config_layer_stack)
|
||||
.await
|
||||
|
||||
Reference in New Issue
Block a user