Prevent Noise auth tokens from reaching child processes (#38941)

## Why

`CODEX_EXEC_SERVER_NOISE_AUTH_TOKEN` is an execution-server credential and
must not be exposed to model-reachable commands or command hooks, including
when shell environment policy explicitly sets a case variant of the name.

## What changed

- Add `CODEX_EXEC_SERVER_NOISE_AUTH_TOKEN` to the shared list of
  non-inheritable environment variables.
- Keep the environment variable constant in `codex-protocol` so the exec
  server and environment scrubber use the same definition.
- Verify case-insensitive removal after policy overrides for shell commands
  and command hooks.

GitOrigin-RevId: 759b224b6a7fb4f56f7b1a6d94ffbb0b188c658f
This commit is contained in:
Anton Panasenko
2026-08-17 04:12:47 +00:00
committed by copyberry
parent 3b4569a920
commit 89e297729e
6 changed files with 102 additions and 2 deletions

View File

@@ -5,12 +5,14 @@ use std::collections::HashMap;
pub const CODEX_SESSION_ID_ENV_VAR: &str = "CODEX_SESSION_ID";
pub const CODEX_THREAD_ID_ENV_VAR: &str = "CODEX_THREAD_ID";
pub const CODEX_EXEC_SERVER_NOISE_AUTH_TOKEN_ENV_VAR: &str = "CODEX_EXEC_SERVER_NOISE_AUTH_TOKEN";
pub const OPENAI_FEDERATION_RULE_ID_ENV_VAR: &str = "OPENAI_FEDERATION_RULE_ID";
pub const OPENAI_IDENTITY_TOKEN_FILE_ENV_VAR: &str = "OPENAI_IDENTITY_TOKEN_FILE";
pub const OPENAI_WORKLOAD_IDENTITY_CONTEXT_ENV_VAR: &str = "OPENAI_WORKLOAD_IDENTITY_CONTEXT";
/// Environment variables that model-reachable child processes must not inherit.
pub const NON_INHERITABLE_ENV_VARS: &[&str] = &[
CODEX_EXEC_SERVER_NOISE_AUTH_TOKEN_ENV_VAR,
OPENAI_FEDERATION_RULE_ID_ENV_VAR,
OPENAI_IDENTITY_TOKEN_FILE_ENV_VAR,
OPENAI_WORKLOAD_IDENTITY_CONTEXT_ENV_VAR,

View File

@@ -21,6 +21,10 @@ fn non_inheritable_environment_is_removed_after_policy_overrides() {
"OPENAI_WORKLOAD_IDENTITY_CONTEXT".to_string(),
r#"{"instance_id":"box-one"}"#.to_string(),
),
(
"codex_exec_server_noise_auth_token".to_string(),
"inherited-noise-token".to_string(),
),
];
let policy = ShellEnvironmentPolicy {
inherit: ShellEnvironmentPolicyInherit::All,
@@ -31,6 +35,10 @@ fn non_inheritable_environment_is_removed_after_policy_overrides() {
"OpenAI_Identity_Token_File".to_string(),
"/run/identity-token".to_string(),
),
(
"Codex_Exec_Server_Noise_Auth_Token".to_string(),
"configured-noise-token".to_string(),
),
]),
..Default::default()
};
@@ -52,6 +60,10 @@ fn command_scrubber_removes_names_from_real_child_environment() {
"OpenAI_Workload_Identity_Context",
r#"{"instance_id":"box-one"}"#,
)
.env(
"Codex_Exec_Server_Noise_Auth_Token",
"inherited-noise-token",
)
.output()
.expect("run inherited-environment test process");
assert!(
@@ -66,6 +78,10 @@ fn command_scrubber_removes_names_from_real_child_environment() {
let mut command = environment_command();
command
.env("openai_identity_token_file", "/run/identity-token")
.env(
CODEX_EXEC_SERVER_NOISE_AUTH_TOKEN_ENV_VAR,
"configured-noise-token",
)
.env("SAFE", "value");
scrub_non_inheritable_env_vars(&mut command);
let output = command.output().expect("read child environment");