From 9fb9ed6ceadca419a2a8c55bf6289f3b3d66acce Mon Sep 17 00:00:00 2001 From: Andrew Ambrosino Date: Thu, 18 Dec 2025 14:28:30 -0800 Subject: [PATCH] Set exclude to true by default in app server (#8281) --- codex-rs/core/src/config/types.rs | 21 +++++++++++++++++---- codex-rs/core/src/exec_env.rs | 30 ++++++++++++++++++++++++++++-- docs/config.md | 6 +++--- docs/example-config.md | 4 ++-- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/codex-rs/core/src/config/types.rs b/codex-rs/core/src/config/types.rs index 9243e9878a..8fa43a6772 100644 --- a/codex-rs/core/src/config/types.rs +++ b/codex-rs/core/src/config/types.rs @@ -474,17 +474,17 @@ pub type EnvironmentVariablePattern = WildMatchPattern<'*', '?'>; /// Deriving the `env` based on this policy works as follows: /// 1. Create an initial map based on the `inherit` policy. /// 2. If `ignore_default_excludes` is false, filter the map using the default -/// exclude pattern(s), which are: `"*KEY*"` and `"*TOKEN*"`. +/// exclude pattern(s), which are: `"*KEY*"`, `"*SECRET*"`, and `"*TOKEN*"`. /// 3. If `exclude` is not empty, filter the map using the provided patterns. /// 4. Insert any entries from `r#set` into the map. /// 5. If non-empty, filter the map using the `include_only` patterns. -#[derive(Debug, Clone, PartialEq, Default)] +#[derive(Debug, Clone, PartialEq)] pub struct ShellEnvironmentPolicy { /// Starting point when building the environment. pub inherit: ShellEnvironmentPolicyInherit, /// True to skip the check to exclude default environment variables that - /// contain "KEY" or "TOKEN" in their name. + /// contain "KEY", "SECRET", or "TOKEN" in their name. Defaults to true. pub ignore_default_excludes: bool, /// Environment variable names to exclude from the environment. @@ -504,7 +504,7 @@ impl From for ShellEnvironmentPolicy { fn from(toml: ShellEnvironmentPolicyToml) -> Self { // Default to inheriting the full environment when not specified. let inherit = toml.inherit.unwrap_or(ShellEnvironmentPolicyInherit::All); - let ignore_default_excludes = toml.ignore_default_excludes.unwrap_or(false); + let ignore_default_excludes = toml.ignore_default_excludes.unwrap_or(true); let exclude = toml .exclude .unwrap_or_default() @@ -531,6 +531,19 @@ impl From for ShellEnvironmentPolicy { } } +impl Default for ShellEnvironmentPolicy { + fn default() -> Self { + Self { + inherit: ShellEnvironmentPolicyInherit::All, + ignore_default_excludes: true, + exclude: Vec::new(), + r#set: HashMap::new(), + include_only: Vec::new(), + use_profile: false, + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/codex-rs/core/src/exec_env.rs b/codex-rs/core/src/exec_env.rs index 11334896bf..60ea8a3b68 100644 --- a/codex-rs/core/src/exec_env.rs +++ b/codex-rs/core/src/exec_env.rs @@ -82,7 +82,7 @@ mod tests { } #[test] - fn test_core_inherit_and_default_excludes() { + fn test_core_inherit_defaults_keep_sensitive_vars() { let vars = make_vars(&[ ("PATH", "/usr/bin"), ("HOME", "/home/user"), @@ -90,7 +90,32 @@ mod tests { ("SECRET_TOKEN", "t"), ]); - let policy = ShellEnvironmentPolicy::default(); // inherit Core, default excludes on + let policy = ShellEnvironmentPolicy::default(); // inherit All, default excludes ignored + let result = populate_env(vars, &policy); + + let expected: HashMap = hashmap! { + "PATH".to_string() => "/usr/bin".to_string(), + "HOME".to_string() => "/home/user".to_string(), + "API_KEY".to_string() => "secret".to_string(), + "SECRET_TOKEN".to_string() => "t".to_string(), + }; + + assert_eq!(result, expected); + } + + #[test] + fn test_core_inherit_with_default_excludes_enabled() { + let vars = make_vars(&[ + ("PATH", "/usr/bin"), + ("HOME", "/home/user"), + ("API_KEY", "secret"), + ("SECRET_TOKEN", "t"), + ]); + + let policy = ShellEnvironmentPolicy { + ignore_default_excludes: false, // apply KEY/SECRET/TOKEN filter + ..Default::default() + }; let result = populate_env(vars, &policy); let expected: HashMap = hashmap! { @@ -162,6 +187,7 @@ mod tests { let policy = ShellEnvironmentPolicy { inherit: ShellEnvironmentPolicyInherit::All, + ignore_default_excludes: false, ..Default::default() }; diff --git a/docs/config.md b/docs/config.md index 8d4cfe349e..f9bbb2ed00 100644 --- a/docs/config.md +++ b/docs/config.md @@ -383,8 +383,8 @@ Codex spawns subprocesses (e.g. when executing a `local_shell` tool-call suggest [shell_environment_policy] # inherit can be "all" (default), "core", or "none" inherit = "core" -# set to true to *skip* the filter for `"*KEY*"` and `"*TOKEN*"` -ignore_default_excludes = false +# set to true to *skip* the filter for `"*KEY*"`, `"*SECRET*"`, and `"*TOKEN*"` +ignore_default_excludes = true # exclude patterns (case-insensitive globs) exclude = ["AWS_*", "AZURE_*"] # force-set / override values @@ -396,7 +396,7 @@ include_only = ["PATH", "HOME"] | Field | Type | Default | Description | | ------------------------- | -------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | `inherit` | string | `all` | Starting template for the environment:
`all` (clone full parent env), `core` (`HOME`, `PATH`, `USER`, …), or `none` (start empty). | -| `ignore_default_excludes` | boolean | `false` | When `false`, Codex removes any var whose **name** contains `KEY`, `SECRET`, or `TOKEN` (case-insensitive) before other rules run. | +| `ignore_default_excludes` | boolean | `true` | When `false`, Codex removes any var whose **name** contains `KEY`, `SECRET`, or `TOKEN` (case-insensitive) before other rules run. | | `exclude` | array | `[]` | Case-insensitive glob patterns to drop after the default filter.
Examples: `"AWS_*"`, `"AZURE_*"`. | | `set` | table | `{}` | Explicit key/value overrides or additions – always win over inherited values. | | `include_only` | array | `[]` | If non-empty, a whitelist of patterns; only variables that match _one_ pattern survive the final step. (Generally used with `inherit = "all"`.) | diff --git a/docs/example-config.md b/docs/example-config.md index fd69faddde..c5e1840544 100644 --- a/docs/example-config.md +++ b/docs/example-config.md @@ -106,8 +106,8 @@ exclude_slash_tmp = false [shell_environment_policy] # inherit: all (default) | core | none inherit = "all" -# Skip default excludes for names containing KEY/TOKEN (case-insensitive). Default: false -ignore_default_excludes = false +# Skip default excludes for names containing KEY/SECRET/TOKEN (case-insensitive). Default: true +ignore_default_excludes = true # Case-insensitive glob patterns to remove (e.g., "AWS_*", "AZURE_*"). Default: [] exclude = [] # Explicit key/value overrides (always win). Default: {}