Skip to content

Filter environment variables passed to CLI subprocess #2

Description

@ppsplus-bradh

Problem

ClaudeCode.Adapter.Port.build_env/2 calls System.get_env() and passes every system environment variable to the CLI subprocess. The CLI only uses a specific set of documented env vars. Passing everything is wasteful (the shell command string grows unnecessarily large) and leaks host environment state that the CLI doesn't need.

Proposed Solution

Filter environment variables to only those the CLI actually uses. Based on the official env vars documentation, the CLI recognizes vars from these categories:

Namespace prefixes (filter by prefix)

  • ANTHROPIC_ — API keys, auth, base URL, model config, Foundry/Bedrock
  • CLAUDE_CODE_ — Feature flags, config, tool settings
  • CLAUDE_ (broader) — CLAUDE_AUTOCOMPACT_PCT_OVERRIDE, CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR, CLAUDE_CONFIG_DIR, CLAUDE_ENV_FILE, CLAUDE_STREAM_IDLE_TIMEOUT_MS
  • VERTEX_REGION_ — Vertex AI region overrides

Non-namespaced vars (explicit allowlist required)

  • AWS_BEARER_TOKEN_BEDROCK
  • BASH_DEFAULT_TIMEOUT_MS, BASH_MAX_OUTPUT_LENGTH, BASH_MAX_TIMEOUT_MS
  • CLAUDECODE
  • DISABLE_AUTOUPDATER, DISABLE_COST_WARNINGS, DISABLE_ERROR_REPORTING, DISABLE_FEEDBACK_COMMAND, DISABLE_INSTALLATION_CHECKS, DISABLE_PROMPT_CACHING, DISABLE_PROMPT_CACHING_HAIKU, DISABLE_PROMPT_CACHING_OPUS, DISABLE_PROMPT_CACHING_SONNET, DISABLE_TELEMETRY
  • ENABLE_CLAUDEAI_MCP_SERVERS, ENABLE_TOOL_SEARCH
  • FORCE_AUTOUPDATE_PLUGINS
  • HTTP_PROXY, HTTPS_PROXY, NO_PROXY
  • IS_DEMO
  • MAX_MCP_OUTPUT_TOKENS, MAX_THINKING_TOKENS
  • MCP_CLIENT_SECRET, MCP_OAUTH_CALLBACK_PORT, MCP_TIMEOUT, MCP_TOOL_TIMEOUT
  • SLASH_COMMAND_TOOL_CHAR_BUDGET
  • USE_BUILTIN_RIPGREP

Standard system vars (needed for CLI to function)

  • PATH — tool resolution (git, rg, etc.)
  • HOME — config/data directory
  • SHELL — shell detection
  • TERM — terminal capabilities
  • LANG, LC_* — locale
  • USER, LOGNAME — user identity
  • TMPDIR, TMP, TEMP — temp directory
  • XDG_CONFIG_HOME, XDG_DATA_HOME — XDG directories
  • NODE_EXTRA_CA_CERTS, NODE_TLS_REJECT_UNAUTHORIZED — Node.js TLS config (CLI is Node-based)

Implementation Approach

  1. Define prefix list: ["ANTHROPIC_", "CLAUDE_CODE_", "CLAUDE_", "VERTEX_REGION_"]
  2. Define explicit allowlist for non-namespaced vars
  3. Define system essentials allowlist (PATH, HOME, etc.)
  4. In build_env/2, filter System.get_env() through these lists before merging SDK and user vars
  5. User-provided :env vars should still be passed through unfiltered (they are intentional overrides)

Notes

  • The env vars doc page may change over time — the allowlist should be easy to maintain
  • Consider a module attribute or config for the allowlist so it's easy to update
  • The SDK-injected vars (CLAUDE_CODE_ENTRYPOINT, CLAUDE_AGENT_SDK_VERSION) are added after filtering via sdk_env_vars/0 so they're unaffected

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions