feat: expose extra_env in LocalInteractiveSession and tool instance in tool_execute extensions#1377
Conversation
|
I don't like the idea of all env vars being passed automatically when you specify extra_envs, this way all framework env vars like api keys are exposed to the code exec runtime. |
|
@frdel — both concerns addressed: 1. Replaced the full merge with a whitelist approach: _SAFE_ENV_KEYS = {"PATH", "HOME", "USER", "SHELL", "TERM", "LANG", "LC_ALL", "TMPDIR", "PWD"}
env = (
{k: v for k, v in os.environ.items() if k in _SAFE_ENV_KEYS} | self.extra_env
) if self.extra_env else NoneOnly the minimal set of keys needed for a functional shell is forwarded from the parent environment — no API keys, tokens, or framework secrets can leak. When 2. Added Both classes now have identical |
4c9f95c to
eac8a8a
Compare
\u26a0\ufe0f ANSI Regex Regression Risk in
|
…in SSHInteractiveSession; preserve \x1b anchor in clean_string()
eac8a8a to
5ed937a
Compare
|
Rebased onto The # clean_string() ansi_escape — after fix (shell_ssh.py:232)
ansi_escape = re.compile(r"\x1b(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")Verified with Python functional test — strips ANSI sequences without garbling bare uppercase letters. All Force-pushed to fork as commit |
feat: extra_env support for LocalInteractiveSession and SSHInteractiveSession
Problem
Code execution subprocesses had no way to receive caller-injected environment variables (e.g. project-specific env, secrets resolved by a plugin at runtime) without either modifying the subprocess command or exposing the full agent environment to the subprocess.
Solution
Adds
extra_env: dict | None = Noneto bothLocalInteractiveSessionandSSHInteractiveSession, letting callers pass per-session environment variables that are available from the start of the shell session.Security
The
LocalInteractiveSessionimplementation uses an explicit whitelist rather than mergingos.environin full. Only the following keys are forwarded from the host environment:API keys, tokens, passwords, and all other framework environment variables are not forwarded. The
extra_envdict is then merged on top — callers receive exactly what they pass, nothing more.SSHInteractiveSessioninjects extra vars viaexport KEY='value'in the session'sinitial_commandblock. Values areshlex.quote()-escaped to prevent injection.Backward Compatibility
Fully backward compatible.
extra_envdefaults toNone. Existing call sites passing onlycwd=are unaffected — whenextra_env=None, the env argument passed toTTYSessionisNoneand the originalos.environ.copy()fallback inTTYSession.__init__applies.Files Changed
plugins/_code_execution/helpers/shell_local.py—_SAFE_ENV_KEYSwhitelist +extra_envparamplugins/_code_execution/helpers/shell_ssh.py—extra_envparam + export-prefix injection