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:
cooper-oai authored and copyberry committed 2026-08-08 16:58:26 +00:00
1 parent 3aae5d885b
commit c4513cb982
25 files changed
+269 -36

No files matched your search

@@ -18,6 +18,7 @@ use codex_app_server_protocol::RequestId;
use codex_app_server_protocol::SandboxPolicy;
use codex_exec_server::CODEX_EXEC_SERVER_URL_ENV_VAR;
use codex_protocol::models::BUILT_IN_PERMISSION_PROFILE_READ_ONLY;
use codex_protocol::shell_environment::OPENAI_FEDERATION_RULE_ID_ENV_VAR;
use pretty_assertions::assert_eq;
use std::collections::HashMap;
use std::path::Path;
@@ -151,7 +152,7 @@ async fn command_exec_env_overrides_merge_with_server_environment_and_support_un
command: vec![
"/bin/sh".to_string(),
"-lc".to_string(),
"printf '%s|%s|%s|%s' \"$COMMAND_EXEC_BASELINE\" \"$COMMAND_EXEC_EXTRA\" \"${RUST_LOG-unset}\" \"$CODEX_HOME\"".to_string(),
"printf '%s|%s|%s|%s|%s|%s' \"$COMMAND_EXEC_BASELINE\" \"$COMMAND_EXEC_EXTRA\" \"${RUST_LOG-unset}\" \"$CODEX_HOME\" \"$OPENAI_FEDERATION_RULE_ID\" \"$openai_identity_token_file\"".to_string(),
],
process_id: None,
tty: false,
@@ -169,6 +170,14 @@ async fn command_exec_env_overrides_merge_with_server_environment_and_support_un
),
("COMMAND_EXEC_EXTRA".to_string(), Some("added".to_string())),
("RUST_LOG".to_string(), None),
(
OPENAI_FEDERATION_RULE_ID_ENV_VAR.to_string(),
Some("rule".to_string()),
),
(
"openai_identity_token_file".to_string(),
Some("/run/identity-token".to_string()),
),
])),
size: None,
sandbox_policy: None,
@@ -181,7 +190,7 @@ async fn command_exec_env_overrides_merge_with_server_environment_and_support_un
response,
CommandExecResponse {
exit_code: 0,
stdout: format!("request|added|unset|{}", codex_home.path().display()),
stdout: format!("request|added|unset|{}||", codex_home.path().display()),
stderr: String::new(),
}
);
@@ -42,7 +42,7 @@ async fn process_spawn_returns_before_exit_and_emits_exit_notification() -> Resu
"while (!(Test-Path -LiteralPath $env:CODEX_PROCESS_EXEC_RELEASE_FILE)) { ",
"Start-Sleep -Milliseconds 20 ",
"}; ",
"[Console]::Out.Write('process-out'); ",
"[Console]::Out.Write(('process-out|{0}|{1}' -f $env:OpenAI_Federation_Rule_Id, $env:OPENAI_IDENTITY_TOKEN_FILE)); ",
"[Console]::Error.Write('process-err')",
)
.to_string(),
@@ -54,7 +54,7 @@ async fn process_spawn_returns_before_exit_and_emits_exit_notification() -> Resu
concat!(
"printf process > \"$CODEX_PROCESS_EXEC_PROBE_FILE\"; ",
"while [ ! -e \"$CODEX_PROCESS_EXEC_RELEASE_FILE\" ]; do sleep 0.05; done; ",
"printf process-out; ",
"printf 'process-out|%s|%s' \"$OpenAI_Federation_Rule_Id\" \"$OPENAI_IDENTITY_TOKEN_FILE\"; ",
"printf process-err >&2",
)
.to_string(),
@@ -69,6 +69,14 @@ async fn process_spawn_returns_before_exit_and_emits_exit_notification() -> Resu
"CODEX_PROCESS_EXEC_RELEASE_FILE".to_string(),
Some(release_file.display().to_string()),
),
(
"OpenAI_Federation_Rule_Id".to_string(),
Some("rule".to_string()),
),
(
"OPENAI_IDENTITY_TOKEN_FILE".to_string(),
Some("/run/identity-token".to_string()),
),
]);
let spawn_request_id = mcp
.send_process_spawn_request(ProcessSpawnParams {
@@ -94,7 +102,7 @@ async fn process_spawn_returns_before_exit_and_emits_exit_notification() -> Resu
ProcessExitedNotification {
process_handle,
exit_code: 0,
stdout: "process-out".to_string(),
stdout: "process-out||".to_string(),
stdout_cap_reached: false,
stderr: "process-err".to_string(),
stderr_cap_reached: false,