Clarify the interaction between `allow_login_shell` and `shell_environment_policy` in documentation

Open 💬 3 comments Opened Mar 16, 2026 by cermeng
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What is the type of issue?

Documentation is confusing

What is the issue?

Description

While configuring shell_environment_policy, I noticed a potentially confusing interaction with allow_login_shell.

shell_environment_policy is documented as controlling the environment variables passed to subprocesses (for example through inherit, exclude, include_only, and set). However, when allow_login_shell = true — which appears to be the default — commands may be executed through a login shell

In that case, the shell will load user profile files such as:

  • ~/.bash_profile
  • ~/.profile
  • ~/.zprofile
  • ~/.zshrc

These files often contain export statements that modify or introduce additional environment variables. As a result, environment variables that were intentionally filtered out by shell_environment_policy can be reintroduced by the shell profile after the process starts.

For example, even with a restrictive configuration like:

[shell_environment_policy]
inherit = "core"
include_only = [xxx]

users may still observe many additional variables inside the executed shell environment because they are added by the login shell initialization scripts.

Since allow_login_shell = true is the default, this behavior may cause users to believe that shell_environment_policy is not working as expected.

Suggested documentation improvement

It would be helpful if the documentation explicitly described that:

  • shell_environment_policy controls the initial environment passed to the subprocess.
  • When allow_login_shell = true, the login shell may modify the environment by loading profile scripts.
  • Therefore, some environment restrictions configured in shell_environment_policy may appear ineffective if the login shell reintroduces variables.
  • The above information could be documented to make this behavior clearer to users on https://developers.openai.com/codex/config-advanced#shell-environment-policy

A short note explaining this interaction would help users better understand and correctly configure environment isolation.

Where did you find it?

_No response_

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 5 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #13426

Powered by Codex Action

andriimazurslalom · 5 months ago

Thank you for your comment. I was trying to understand how shell_environment_policy works, so I simulated creating a secret by adding a dummy environment variable called ``SUPER_IMPORTANT_SECRET`` and attempted to hide it from Codex using the following config.toml:

[shell_environment_policy]
inherit = "all"
ignore_default_excludes = false
exclude = ["SUPER_IMPORTANT_SECRET"]

It didn't work!

After finding this github issue, I set ``allow_login_shell = false``, and SUPER_IMPORTANT_SECRET was no longer exposed to Codex.

Documentation indeed has an improvement potential.

Herrtian · 3 months ago

I prepared a narrow docs/schema branch for this interaction:

https://github.com/Herrtian/codex/tree/docs/login-shell-env-policy

The branch does not change runtime behavior. It updates the config comments that feed the generated schema so the reference makes two things explicit:

  • shell_environment_policy builds the initial environment passed to shell subprocesses.
  • when allow_login_shell is true, shell profile files may later modify that environment; users who need strict filtering should set allow_login_shell = false.

Validation I ran:

git diff --check -- codex-rs/config/src/config_toml.rs codex-rs/core/config.schema.json
cargo run -p codex-core --bin codex-write-config-schema
cargo test -p codex-core config_schema_matches_fixture -- --nocapture

PR creation appears to be limited by the repo's invitation-only contribution policy, so I'm sharing the branch here. If this scope looks right, could a maintainer invite a PR or pick it up internally?