anthropics / anthropics/claude-agent-sdk-python

discussion: ClaudeAgentOptions.env only supports implicit parent-env inheritance with no documented isolated environment mode

Đang mở
#934 2 bình luận 0 reaction 0 người được giao Xem trên GitHub
documentation enhancement question
Ngôn ngữ chính
Python
Star
8.1k
Fork
1.3k
Merge trung bình
2 ngày 31 phút
Pull request đã merge (30 ngày)
1

Mô tả

hey, i was exploring `src/claude_agent_sdk/_internal/transport/subprocess_cli.py` to understand how the SDK spawns the Claude Code CLI subprocess and noticed that `connect()` always builds the subprocess environment by inheriting the full parent `os.environ` and then merging user provided `ClaudeAgentOptions.env` on top of it

```python
inherited_env = {k: v for k, v in os.environ.items() if k != "CLAUDECODE"}

process_env = {
**inherited_env,
"CLAUDE_CODE_ENTRYPOINT": "sdk-py",
**self._options.env,
"CLAUDE_AGENT_SDK_VERSION": __version__,
}
```
at a normal usage level this makes sense because `env={"MY_VAR": "value"}` works as an override/addition mechanism, the confusing part is that this inheritance behaviour does not seem to be explicitly documented on `ClaudeAgentOptions.env` and there also does not appear to be a supported way to request a clean or isolated subprocess environment
this looks related to #573 but in this case the concern is broader as users currently get implicit full inheritance but no explicit way to choose between merge with parent env and isolated/clean subprocess env
### Impact
due to this, users cannot create a deterministic or sandboxed subprocess environment and also, sensitive parent variables may be inherited unintentionally and CI/reproducibility use cases become harder
(main point: current behaviour may be intentional but the API contract is not explicit enough to make that clear)

### How to reproduce

Reproduction

```python

import os
import anyio

from claude_agent_sdk import ClaudeAgentOptions
from claude_agent_sdk._errors import CLIConnectionError
from claude_agent_sdk._internal.transport.subprocess_cli import SubprocessCLITransport

class EnvCaptured(Exception):
pass

async def fake_open_process(*args, **kwargs):
env = kwargs["env"]

print("MY_CUSTOM_VAR:", env.get("MY_CUSTOM_VAR"))
print("HOME inherited:", "HOME" in env)
print("PATH inherited:", "PATH" in env)
print("ANTHROPIC_API_KEY inherited:", "ANTHROPIC_API_KEY" in env)

raise EnvCaptured("Stopped after capturing subprocess env")

async def fake_check_claude_version():
return None

async def main():
os.environ["ANTHROPIC_API_KEY"] = "dummy-secret"

options = ClaudeAgentOptions(
env={"MY_CUSTOM_VAR": "hello"},
max_turns=1,
)

transport = SubprocessCLITransport(prompt="hello", options=options)

transport._cli_path = "dummy-claude"
transport._build_command = lambda: ["dummy-claude"]
transport._check_claude_version = fake_check_claude_version

original_open_process = anyio.open_process
anyio.open_process = fake_open_process

try:
await transport.connect()
except CLIConnectionError as e:
if "Stopped after capturing subprocess env" in str(e):
print("Captured env successfully; reproduction complete.")
else:
raise
finally:
anyio.open_process = original_open_process

anyio.run(main)
```
Output:
Image

was the current inheritance-only behaviour intentional or is the lack of an isolated environment mode an oversight? happy to make a pr if this direction sounds useful

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.