Skip to content

Add environment variable passthrough allowlist for blocked vars#207

Merged
subsy merged 9 commits intomainfrom
claude/fix-env-variable-leak-hl6ZV
Jan 23, 2026
Merged

Add environment variable passthrough allowlist for blocked vars#207
subsy merged 9 commits intomainfrom
claude/fix-env-variable-leak-hl6ZV

Conversation

@subsy
Copy link
Copy Markdown
Owner

@subsy subsy commented Jan 23, 2026

Summary

This PR adds an envPassthrough configuration option that allows users to explicitly allow specific environment variables to reach agent subprocesses, overriding the default exclusion patterns. This complements the existing envExclude option and provides a three-layer filtering system for environment variables.

Problem

Ralph TUI automatically blocks environment variables matching *_API_KEY, *_SECRET_KEY, and *_SECRET to prevent accidental credential leakage (e.g., from .env files auto-loaded by Bun). However, there was no way for users to override these defaults when they legitimately need a blocked variable (e.g., when an agent genuinely requires an API key for authentication).

Solution

Introduces envPassthrough as a new configuration option that creates an allowlist for variables that would otherwise be blocked. This enables a three-layer filtering system:

  1. Default patterns*_API_KEY, *_SECRET_KEY, *_SECRET (always applied)
  2. User envExclude — additional patterns configured by the user (stacked on defaults)
  3. envPassthrough — overrides both defaults and user excludes

Key Changes

  • New exports from base.ts:

    • DEFAULT_ENV_EXCLUDE_PATTERNS — exported constant for the default blocking patterns
    • getEnvExclusionReport() — analyzes current environment and categorizes variables as blocked vs. allowed
    • formatEnvExclusionReport() — formats the report as human-readable console output
    • EnvExclusionReport interface — type for the report structure
  • Updated BaseAgentPlugin:

    • Added envPassthrough field to store passthrough patterns
    • Updated filterEnvByExcludeWithPassthrough() to apply three-layer filtering
    • Added getExclusionReport() method for diagnostics
    • Modified execute() to use default patterns + user excludes + passthrough logic
  • Configuration updates:

    • Added envPassthrough to AgentPluginConfig and StoredConfig schemas
    • Added envPassthrough to type definitions with documentation
    • Updated config loading to apply passthrough shorthand to default agent
  • User-facing improvements:

    • ralph-tui run and ralph-tui prime now display env filter report before starting
    • ralph-tui doctor includes env exclusion report in diagnostics output
    • ralph-tui info includes env exclusion report in system information
    • All commands block on Enter when blocked variables are detected (interactive TTY only)
  • Documentation:

    • Comprehensive update to options.mdx explaining the three-layer filtering system
    • Added examples for common use cases (Max subscription vs. API key auth)
    • Added diagnostics section showing how to verify which variables are blocked
  • Tests:

    • 50+ new test cases covering:
      • Default pattern exclusion behavior
      • envPassthrough allowlist functionality
      • Glob pattern matching in passthrough
      • Interaction between envExclude and envPassthrough
      • getEnvExclusionReport() and formatEnvExclusionReport() functions
      • Agent's getExclusionReport() method

Implementation Details

  • Passthrough patterns use the same glob-matching logic as exclusion patterns
  • The filtering is applied at subprocess spawn time, not at configuration load time
  • Reports are always shown to users (even when no variables match) to confirm the filter is active
  • Interactive blocking (press Enter to continue) only occurs when:
    • Variables are actually blocked
    • stdin is a TTY (interactive terminal)
    • Not in headless mode (for run command)

Summary by CodeRabbit

  • New Features

    • Added envPassthrough to allow specific environment variables to bypass default exclusions
    • Environment-exclusion reports are shown upfront and may pause interactive sessions for acknowledgement
    • Env exclusion details are now included in diagnostics and system info outputs
  • Documentation

    • Updated configuration docs with filtering model, patterns, passthrough usage and examples
  • Tests

    • Added coverage for envPassthrough, envExclude and formatted reporting in unit tests

✏️ Tip: You can customize this high-level summary in your review settings.

Bun auto-loads .env files into process.env, which means API keys stored
in project .env files (e.g., ANTHROPIC_API_KEY) get silently passed to
agent subprocesses, causing unexpected billing. The existing envExclude
feature was opt-in only.

This adds DEFAULT_ENV_EXCLUDE_PATTERNS (*_API_KEY, *_SECRET_KEY, *_SECRET)
that are applied by default when spawning agent processes. Users can
disable defaults with envExcludeDefaults = false if they explicitly need
to pass these variables through.

Closes #202

https://claude.ai/code/session_01Aj9WxkRvQcJG7PaXQXwNwk
…d detection

Instead of a blunt on/off toggle for default exclusions, users can now
specify exactly which blocked vars to allow through via envPassthrough.
This supports exact names and glob patterns.

Also adds getEnvExclusionReport() which scans the environment and
categorizes vars into blocked (won't reach agent) vs allowed (in the
passthrough list). This enables the UI/doctor to show users which keys
from their .env files are being filtered.

Config example:
  envPassthrough = ["ANTHROPIC_API_KEY"]  # allow this specific key

https://claude.ai/code/session_01Aj9WxkRvQcJG7PaXQXwNwk
When sensitive env vars are detected (matching *_API_KEY, *_SECRET_KEY,
*_SECRET patterns), show which are blocked and which are in the
passthrough list. This makes the filtering behavior visible to users.

- doctor: shows in diagnostics output and DoctorResult JSON
- info: included in SystemInfo and formatSystemInfo output
- run: displayed upfront before preflight/engine initialization
- create-prd: displayed before agent preflight check

Also adds formatEnvExclusionReport() utility and passes envPassthrough
config to create-prd agent initialization.

https://claude.ai/code/session_01Aj9WxkRvQcJG7PaXQXwNwk
The env exclusion report was invisible unless the user happened to have
environment variables matching the default patterns. Now
formatEnvExclusionReport always returns output — either listing blocked/
allowed vars or confirming "no vars matched exclusion patterns". Removed
the conditional guards from doctor, info, run, and create-prd commands.

Also adds formatEnvExclusionReport tests, env section tests for info
command output, and updates website docs with envPassthrough, default
patterns, and three-layer filtering documentation.

https://claude.ai/code/session_01Aj9WxkRvQcJG7PaXQXwNwk
The env filter report was being immediately wiped when the TUI renderer
took over the terminal. Now pauses 3 seconds so users can read which
vars are blocked. Only triggers when blocked vars exist and running in
TUI mode — headless mode continues immediately for scripting/automation.

https://claude.ai/code/session_01Aj9WxkRvQcJG7PaXQXwNwk
The 3s setTimeout wasn't working reliably. Now uses readline to prompt
"Press Enter to continue..." which truly blocks the process. Only
triggers when: blocked vars exist AND stdin is a TTY AND not headless.
Piped stdin, CI, and --headless all skip the prompt automatically.

https://claude.ai/code/session_01Aj9WxkRvQcJG7PaXQXwNwk
mergeConfigs was missing envPassthrough, causing it to be silently
dropped when loading project config. Also adds schema validation tests
for envExclude/envPassthrough and config shorthand resolution tests
verifying top-level envPassthrough is applied to the default agent.

https://claude.ai/code/session_01Aj9WxkRvQcJG7PaXQXwNwk
@vercel
Copy link
Copy Markdown

vercel bot commented Jan 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Review Updated (UTC)
ralph-tui Ignored Ignored Preview Jan 23, 2026 3:23pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 23, 2026

Walkthrough

This PR adds envPassthrough to configs, implements passthrough-aware environment exclusion logic and reporting in the base agent plugin, and surfaces formatted env-exclusion reports (with an optional TTY pause) across CLI commands (create-prd, run, doctor, info).

Changes

Cohort / File(s) Summary
Configuration Schema & Types
src/config/schema.ts, src/config/types.ts, src/config/schema.test.ts
Add envPassthrough: string[] to schemas and types; tests validate acceptance/rejection rules and allow combined use with envExclude.
Configuration Merging
src/config/index.ts, src/config/index.test.ts
Propagate top-level envPassthrough into agent configs as a shorthand; tests for precedence and shorthand behaviour.
Base Agent Plugin & Utilities
src/plugins/agents/base.ts, src/plugins/agents/base.test.ts
Add DEFAULT_ENV_EXCLUDE_PATTERNS, EnvExclusionReport, getEnvExclusionReport, formatEnvExclusionReport, passthrough-aware filter (filterEnvByExcludeWithPassthrough), expose getExclusionReport, and wire envPassthrough into plugin init/execute. Tests added/updated.
Agent Types & Registry
src/plugins/agents/types.ts, src/plugins/agents/registry.ts
Add envPassthrough?: string[] to AgentPluginConfig and thread config.envPassthrough into plugin initialization.
CLI: create-prd & run
src/commands/create-prd.tsx, src/commands/run.tsx
Compute and print formatted env-exclusion report after config validation; if blocked vars exist and session is interactive, pause for user Enter. Forward envPassthrough into agent config when building agent.
CLI: doctor
src/commands/doctor.ts
Compute envExclusion in diagnostics, add envExclusion?: EnvExclusionReport to DoctorResult, include report in human output, and forward envPassthrough during agent init.
CLI: info / SystemInfo
src/commands/info.ts, src/commands/info.test.ts
Add envExclusion to SystemInfo; compute per-agent exclusion report and render it in formatted system output; tests updated for empty and populated scenarios.
Documentation
website/content/docs/configuration/options.mdx
Document three-layer filtering model (defaults, envExclude, envPassthrough), usage examples and diagnostics output.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CLI
  participant ProcessEnv as "process.env"
  participant Registry
  participant Agent as "BaseAgentPlugin"

  CLI->>ProcessEnv: read env
  CLI->>CLI: compute getEnvExclusionReport(process.env, stored.envPassthrough, stored.envExclude)
  CLI->>User: print formatEnvExclusionReport(report)
  alt blocked vars && stdin is TTY
    User-->>CLI: press Enter
  end
  CLI->>Registry: registry.getInstance(..., initConfig.envPassthrough)
  Registry->>Agent: initialize with envPassthrough & envExclude
  Agent->>Agent: compute effective env via filterEnvByExcludeWithPassthrough()
  CLI->>CLI: proceed with preflight / command flow
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐇 I sniff the env, I sort with care,

Blocked ones hide, allowed ones share,
Passthrough hops a gentle way,
I print the list — press Enter, yay!
Happy builds and quiet lair.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the primary change: adding envPassthrough as an allowlist mechanism for environment variables that would otherwise be blocked by exclusion patterns.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 23, 2026

Codecov Report

❌ Patch coverage is 62.43094% with 68 lines in your changes missing coverage. Please review.
✅ Project coverage is 45.02%. Comparing base (eff9228) to head (47931cf).
⚠️ Report is 10 commits behind head on main.

Files with missing lines Patch % Lines
src/commands/create-prd.tsx 3.70% 26 Missing ⚠️
src/commands/run.tsx 3.84% 25 Missing ⚠️
src/plugins/agents/base.ts 82.35% 15 Missing ⚠️
src/config/index.ts 77.77% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #207      +/-   ##
==========================================
+ Coverage   44.88%   45.02%   +0.13%     
==========================================
  Files          84       84              
  Lines       24231    24403     +172     
==========================================
+ Hits        10877    10988     +111     
- Misses      13354    13415      +61     
Files with missing lines Coverage Δ
src/commands/doctor.ts 81.96% <100.00%> (+1.61%) ⬆️
src/commands/info.ts 77.21% <100.00%> (+1.21%) ⬆️
src/config/schema.ts 94.78% <100.00%> (+0.09%) ⬆️
src/config/types.ts 100.00% <ø> (ø)
src/plugins/agents/registry.ts 50.40% <100.00%> (+0.20%) ⬆️
src/config/index.ts 53.05% <77.77%> (+0.96%) ⬆️
src/plugins/agents/base.ts 63.27% <82.35%> (+2.44%) ⬆️
src/commands/run.tsx 8.28% <3.84%> (-0.08%) ⬇️
src/commands/create-prd.tsx 20.12% <3.70%> (-1.45%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In `@src/commands/doctor.ts`:
- Around line 210-220: The human-readable output in printHumanResult currently
omits the Environment section when result.envExclusion has no blocked/allowed
entries; update printHumanResult to always print the "Environment:" section and,
when both result.envExclusion.blocked and result.envExclusion.allowed are empty,
print the same "no vars matched" message used by runDiagnostics (or a consistent
"No vars matched" line) instead of skipping the section; locate code in
printHumanResult that checks result.envExclusion and modify the conditional and
console.log calls to mirror runDiagnostics behavior for consistency.
- Around line 90-101: The env exclusion report is being printed twice: once
inside runDiagnostics (using getEnvExclusionReport and formatEnvExclusionReport
followed by log calls) and again in printHumanResult; remove the duplicate by
deleting the logging block in runDiagnostics that builds envExclusion/envLines
and prints them, or wrap that block with a guard so it only runs when the final
human output will not be printed (e.g., skip when quiet is false and
printHumanResult will run). Target the code around runDiagnostics and the calls
to getEnvExclusionReport/formatEnvExclusionReport to eliminate the duplicate
logging.

In `@src/commands/info.ts`:
- Around line 309-314: The env exclusion report is built using only the
top-level config (config.envPassthrough/config.envExclude) so per-agent
overrides are ignored; resolve the target agent's env settings first (e.g.,
determine agentEnvPassthrough and agentEnvExclude from the agent's
config/overrides) and pass those into getEnvExclusionReport(process.env,
agentEnvPassthrough, agentEnvExclude) instead of
config.envPassthrough/config.envExclude so ralph-tui info reflects
agent-specific allowlists.

In `@src/commands/run.tsx`:
- Around line 1547-1571: The env exclusion report is being built from
storedConfig?.envPassthrough and storedConfig?.envExclude which can miss
per-agent overrides; change the call to getEnvExclusionReport to use the
resolved agent configuration (config.agent) values (e.g.,
config.agent.envPassthrough and config.agent.envExclude or the merged agent
config object) so the envReport reflects the actual runtime filtering used by
the agent (symbols: getEnvExclusionReport, envReport, storedConfig,
config.agent, envPassthrough, envExclude, options.headless,
process.stdin.isTTY).

In `@src/plugins/agents/base.ts`:
- Around line 105-115: The comment above DEFAULT_ENV_EXCLUDE_PATTERNS is
outdated—remove the reference to envExcludeDefaults and update it to state that
these patterns are excluded by default to prevent accidental API key leakage
(e.g., from auto-loaded .env files) unless the new envPassthrough option is
enabled; ensure the comment references DEFAULT_ENV_EXCLUDE_PATTERNS and
envPassthrough so readers understand the current behavior.
🧹 Nitpick comments (1)
src/commands/create-prd.tsx (1)

293-299: Duplicate loadStoredConfig call causes redundant I/O.

loadStoredConfig(cwd) is already called inside getAgent() at line 232, and the config is used there. Calling it again here at line 294 duplicates file reads. Consider either returning storedConfig from getAgent() or passing the already-loaded config to avoid the redundant operation.

claude and others added 2 commits January 23, 2026 15:20
- doctor.ts: Remove duplicate env report logging from runDiagnostics
  (now only printed in printHumanResult); always show Environment
  section using formatEnvExclusionReport for consistency
- info.ts: Resolve per-agent envPassthrough/envExclude overrides from
  the [[agents]] config array instead of using only top-level values
- run.tsx: Use config.agent.envPassthrough/envExclude (resolved agent
  config) instead of storedConfig top-level values
- base.ts: Update outdated comment on DEFAULT_ENV_EXCLUDE_PATTERNS to
  reference envPassthrough instead of removed envExcludeDefaults

https://claude.ai/code/session_01Aj9WxkRvQcJG7PaXQXwNwk
@subsy subsy merged commit fa7f3d3 into main Jan 23, 2026
9 checks passed
@subsy subsy deleted the claude/fix-env-variable-leak-hl6ZV branch January 23, 2026 15:35
sakaman pushed a commit to sakaman/ralph-tui that referenced this pull request Feb 15, 2026
…hl6ZV

Add environment variable passthrough allowlist for blocked vars
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants