mirror of
https://github.com/openai/codex.git
synced 2026-11-07 20:30:33 +00:00
Prevent launch context from reaching child processes (#37607)
## Why Model-reachable child processes should not inherit Codex launch context. ## What changed - Treat `OPENAI_FEDERATION_RULE_ID` and `OPENAI_IDENTITY_TOKEN_FILE` as non-inheritable environment variables, with case-insensitive matching. - Remove them after shell environment policy overrides and before spawning commands across execution, MCP, hooks, Git helpers, and remote helper processes. ## Testing - Cover inherited and explicitly configured variants, including mixed-case names. - Verify the variables are absent from real child environments and app-server command and process execution. GitOrigin-RevId: 2535527893985fef0995617f4c5b2462bea7c136
This commit is contained in:
@@ -8,6 +8,7 @@ use tokio::process::Command;
|
||||
use tracing::trace;
|
||||
|
||||
use codex_protocol::permissions::NetworkSandboxPolicy;
|
||||
use codex_protocol::shell_environment::is_non_inheritable_env_var;
|
||||
|
||||
/// Experimental environment variable that will be set to some non-empty value
|
||||
/// if both of the following are true:
|
||||
@@ -60,6 +61,8 @@ pub(crate) async fn spawn_child_async(request: SpawnChildRequest<'_>) -> std::io
|
||||
mut env,
|
||||
} = request;
|
||||
|
||||
env.retain(|name, _| !is_non_inheritable_env_var(name));
|
||||
|
||||
trace!(
|
||||
"spawn_child_async: {program:?} {args:?} {arg0:?} {cwd:?} {network_sandbox_policy:?} {stdio_policy:?} {env:?}"
|
||||
);
|
||||
|
||||
@@ -23,6 +23,7 @@ pub(crate) use codex_network_proxy::is_managed_proxy_env_var;
|
||||
pub(crate) use codex_network_proxy::strip_managed_proxy_env;
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
use codex_protocol::models::AdditionalPermissionProfile;
|
||||
use codex_protocol::shell_environment::is_non_inheritable_env_var;
|
||||
use codex_sandboxing::SandboxCommand;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use codex_utils_path_uri::PathUri;
|
||||
@@ -304,6 +305,7 @@ fn build_override_exports(
|
||||
.keys()
|
||||
.map(String::as_str)
|
||||
.chain(restore_even_when_absent.iter().copied())
|
||||
.filter(|key| !is_non_inheritable_env_var(key))
|
||||
.filter(|key| is_valid_shell_variable_name(key))
|
||||
.collect::<Vec<_>>();
|
||||
keys.sort_unstable();
|
||||
|
||||
@@ -1082,10 +1082,16 @@ fn maybe_wrap_shell_lc_with_snapshot_does_not_embed_override_values_in_argv() {
|
||||
"-lc".to_string(),
|
||||
"printf '%s' \"$OPENAI_API_KEY\"".to_string(),
|
||||
];
|
||||
let explicit_env_overrides = HashMap::from([(
|
||||
"OPENAI_API_KEY".to_string(),
|
||||
"super-secret-value".to_string(),
|
||||
)]);
|
||||
let explicit_env_overrides = HashMap::from([
|
||||
(
|
||||
"OPENAI_API_KEY".to_string(),
|
||||
"super-secret-value".to_string(),
|
||||
),
|
||||
(
|
||||
"openai_identity_token_file".to_string(),
|
||||
"/run/identity-token".to_string(),
|
||||
),
|
||||
]);
|
||||
let rewritten = maybe_wrap_shell_lc_with_snapshot(
|
||||
&command,
|
||||
&session_shell,
|
||||
@@ -1099,6 +1105,7 @@ fn maybe_wrap_shell_lc_with_snapshot_does_not_embed_override_values_in_argv() {
|
||||
);
|
||||
|
||||
assert!(!rewritten[2].contains("super-secret-value"));
|
||||
assert!(!rewritten[2].contains("openai_identity_token_file"));
|
||||
let output = Command::new(&rewritten[0])
|
||||
.args(&rewritten[1..])
|
||||
.env("OPENAI_API_KEY", "super-secret-value")
|
||||
|
||||
@@ -66,6 +66,7 @@ use codex_protocol::error::SandboxErr;
|
||||
use codex_protocol::protocol::EventMsg;
|
||||
use codex_protocol::protocol::ExecCommandSource;
|
||||
use codex_protocol::protocol::TerminalInteractionEvent;
|
||||
use codex_protocol::shell_environment::is_non_inheritable_env_var;
|
||||
use codex_sandboxing::SandboxCommand;
|
||||
use codex_tools::ToolName;
|
||||
use codex_utils_output_truncation::approx_tokens_from_byte_count;
|
||||
@@ -123,7 +124,10 @@ fn exec_env_policy_from_shell_policy(
|
||||
.collect::<Vec<_>>();
|
||||
exclude.push(CODEX_PERMISSION_PROFILE_ENV_VAR.to_string());
|
||||
let mut r#set = policy.r#set.clone();
|
||||
r#set.retain(|key, _| !key.eq_ignore_ascii_case(CODEX_PERMISSION_PROFILE_ENV_VAR));
|
||||
r#set.retain(|key, _| {
|
||||
!key.eq_ignore_ascii_case(CODEX_PERMISSION_PROFILE_ENV_VAR)
|
||||
&& !is_non_inheritable_env_var(key)
|
||||
});
|
||||
codex_exec_server::ExecEnvPolicy {
|
||||
inherit: policy.inherit.clone(),
|
||||
ignore_default_excludes: policy.ignore_default_excludes,
|
||||
@@ -144,8 +148,9 @@ fn env_overlay_for_exec_server(
|
||||
request_env
|
||||
.iter()
|
||||
.filter(|(key, value)| {
|
||||
key.as_str() == CODEX_PERMISSION_PROFILE_ENV_VAR
|
||||
|| local_policy_env.get(*key) != Some(*value)
|
||||
!is_non_inheritable_env_var(key)
|
||||
&& (key.as_str() == CODEX_PERMISSION_PROFILE_ENV_VAR
|
||||
|| local_policy_env.get(*key) != Some(*value))
|
||||
})
|
||||
.map(|(key, value)| (key.clone(), value.clone()))
|
||||
.collect()
|
||||
|
||||
@@ -51,6 +51,7 @@ fn env_overlay_for_exec_server_keeps_runtime_changes_only() {
|
||||
let request_env = HashMap::from([
|
||||
("HOME".to_string(), "/client-home".to_string()),
|
||||
("PATH".to_string(), "/sandbox-path".to_string()),
|
||||
("OpenAI_Federation_Rule_Id".to_string(), "rule".to_string()),
|
||||
("SHELL_SET".to_string(), "policy".to_string()),
|
||||
("CODEX_THREAD_ID".to_string(), "thread-1".to_string()),
|
||||
(
|
||||
@@ -81,13 +82,17 @@ fn env_overlay_for_exec_server_keeps_runtime_changes_only() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_env_policy_excludes_runtime_permission_profile() {
|
||||
fn exec_env_policy_excludes_non_inheritable_and_runtime_variables() {
|
||||
let policy = ShellEnvironmentPolicy {
|
||||
r#set: HashMap::from([
|
||||
(
|
||||
"codex_permission_profile".to_string(),
|
||||
"stale-profile".to_string(),
|
||||
),
|
||||
(
|
||||
"openai_identity_token_file".to_string(),
|
||||
"/run/identity-token".to_string(),
|
||||
),
|
||||
("KEEP".to_string(), "value".to_string()),
|
||||
]),
|
||||
..Default::default()
|
||||
|
||||
Reference in New Issue
Block a user