Skip to content

Fix claude code entrypoint leak#1165

Closed
GouBuliya wants to merge 3 commits intocoleam00:devfrom
GouBuliya:fix-claude-code-entrypoint-leak
Closed

Fix claude code entrypoint leak#1165
GouBuliya wants to merge 3 commits intocoleam00:devfrom
GouBuliya:fix-claude-code-entrypoint-leak

Conversation

@GouBuliya
Copy link
Copy Markdown

@GouBuliya GouBuliya commented Apr 13, 2026

Summary

Describe this PR in 2-5 bullets:

  • Problem: CLAUDE_CODE_ENTRYPOINT was still leaking to Claude subprocesses despite stripCwdEnv() cleanup at entry point, causing nested Claude Code sessions to hang
  • Why it matters: This regression prevented Archon from working correctly when launched from inside a Claude Code session, leading to silent hangs
  • What changed: Modified buildSubprocessEnv() to double-filter environment variables, ensuring no CLAUDE_CODE_* markers (except auth-related ones) leak to the subprocess
  • Additional context: This fix addresses the regression described in issue regression of #1030: CLAUDE_CODE_ENTRYPOINT still leaks to Claude subprocess env in v0.3.6 — nested-Claude-Code hang reproduces #1150 and provides an extra layer of protection even if stripCwdEnv() is bypassed or platform-specific env inheritance adds markers back## Summary

Describe this PR in 2-5 bullets:

  • Problem: CLAUDE_CODE_ENTRYPOINT was still leaking to Claude subprocesses despite stripCwdEnv() cleanup at entry point, causing nested Claude Code sessions to hang
  • Why it matters: This regression prevented Archon from working correctly when launched from inside a Claude Code session, leading to silent hangs
  • What changed: Modified buildSubprocessEnv() to double-filter environment variables, ensuring no CLAUDE_CODE_* markers (except auth-related ones) leak to the subprocess
  • Additional context: This fix addresses the regression described in issue regression of #1030: CLAUDE_CODE_ENTRYPOINT still leaks to Claude subprocess env in v0.3.6 — nested-Claude-Code hang reproduces #1150 and provides an extra layer of protection even if stripCwdEnv() is bypassed or platform-specific env inheritance adds markers back## Summary

Describe this PR in 2-5 bullets:

  • Problem:
  • Why it matters:
  • What changed:
  • What did not change (scope boundary):

UX Journey

Before

(Draw the user-facing flow BEFORE this PR. Show each step the user takes.)

Example:
  User                   Archon                   AI Client
  ────                   ──────                   ─────────
  sends message ──────▶  resolves session
                         loads context
                         streams to AI ──────────▶ processes prompt
                         receives chunks ◀──────── streams response
  sees reply ◀─────────  sends to platform

After

(Draw the user-facing flow AFTER this PR. Highlight what changed with [brackets] or asterisks.)

Architecture Diagram

Before

(Map ALL modules touched or connected to this change. Draw lines between them.)

After

(Same diagram with changes highlighted. Mark new modules with [+], removed with [-],
 modified with [~]. Mark new connections with ===, removed with --x--.)

Connection inventory (list every module-to-module edge, mark changes):

From To Status Notes
unchanged / new / removed / modified

Label Snapshot

  • Risk: risk: low|medium|high
  • Size: size: XS|S|M|L|XL
  • Scope: core|workflows|isolation|git|adapters|server|web|cli|paths|config|docs|dependencies|ci|tests|skills
  • Module: <scope>:<component> (e.g. workflows:executor, adapters:slack, core:orchestrator)

Change Metadata

  • Change type: bug|feature|refactor|docs|security|chore
  • Primary scope: core|workflows|isolation|git|adapters|server|web|cli|paths|multi

Linked Issue

  • Closes #
  • Related #
  • Depends on # (if stacked)
  • Supersedes # (if replacing older PR)

Validation Evidence (required)

Commands and result summary:

bun run type-check
bun run lint
bun run format:check
bun run test
# Or all at once:
bun run validate
  • Evidence provided (test/log/trace/screenshot):
  • If any command is intentionally skipped, explain why:

Security Impact (required)

  • New permissions/capabilities? (Yes/No)
  • New external network calls? (Yes/No)
  • Secrets/tokens handling changed? (Yes/No)
  • File system access scope changed? (Yes/No)
  • If any Yes, describe risk and mitigation:

Compatibility / Migration

  • Backward compatible? (Yes/No)
  • Config/env changes? (Yes/No)
  • Database migration needed? (Yes/No)
  • If yes, exact upgrade steps:

Human Verification (required)

What was personally validated beyond CI:

  • Verified scenarios:
  • Edge cases checked:
  • What was not verified:

Side Effects / Blast Radius (required)

  • Affected subsystems/workflows:
  • Potential unintended effects:
  • Guardrails/monitoring for early detection:

Rollback Plan (required)

  • Fast rollback command/path:
  • Feature flags or config toggles (if any):
  • Observable failure symptoms:

Risks and Mitigations

List real risks in this PR (or write None).

  • Risk:
    • Mitigation:

Summary by CodeRabbit

  • Documentation

    • Added Windows Symbolic Link Prerequisite section detailing symlink creation requirements and necessary privileges.
  • Bug Fixes

    • Enhanced sensitive key removal recommendations to dynamically include all detected keys from environment files.
    • Improved environment variable filtering for subprocess execution to prevent unintended variable leakage.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3a4e017907

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +143 to +145
const grepCommand = keysArray
.map(key => `grep -v '^${key}='`)
.join(' | ') + ' .env > .env.tmp && mv .env.tmp .env';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Put .env input on first grep stage

When more than one sensitive key is detected, this formatter emits a command like grep -v '^KEY1=' | grep -v '^KEY2=' .env > .env.tmp ...; in that form, the first grep has no file/stdin source and waits on terminal input, so the recommended remediation hangs instead of editing .env. This only appears in multi-key findings (for example .env containing both OPENAI_API_KEY and GEMINI_API_KEY), which is a common case for this gate.

Useful? React with 👍 / 👎.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 13, 2026

📝 Walkthrough

Walkthrough

This PR adds Windows symlink setup documentation, enhances environment leak detection by dynamically aggregating sensitive keys into shell remediation commands, and filters Claude-related environment variables to prevent unintended propagation during subprocess execution.

Changes

Cohort / File(s) Summary
Documentation
README.md
Added "Windows Symbolic Link Prerequisite" section informing Windows users about symlink creation under ~/.archon/workspaces/ and required privileges (Developer Mode or administrator).
Environment Leak Detection
packages/core/src/utils/env-leak-scanner.ts
Enhanced formatLeakError() to aggregate all unique sensitive keys from findings and generate a composite shell remediation command with multiple grep -v filters, replacing the fixed example command.
Provider Environment Filtering
packages/providers/src/claude/provider.ts
Modified buildSubprocessEnv() to explicitly remove all CLAUDE_CODE_* variables except allowlisted ones (CLAUDE_CODE_OAUTH_TOKEN, CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX) and delete CLAUDECODE marker.

Possibly related issues

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Windows users now see the way,
Symlinks need Admin's hand to play,
Secrets scrubbed with grep's sharp blade,
No more leaks in subprocess made,
Archon's safety—hooray, hooray! 🎉

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description includes the required summary section with problem, why it matters, and what changed, but most other required template sections (UX Journey, Architecture Diagram, Change Metadata, Linked Issue, Validation Evidence, Security Impact, Compatibility, Human Verification, Side Effects, and Rollback Plan) are missing or incomplete. Complete the missing template sections: add UX Journey diagrams, Architecture Diagram with connection inventory, Change Metadata labels, Linked Issue reference (#1150), Validation Evidence with test results, Security Impact assessment, Compatibility/Migration details, Human Verification scenarios, Side Effects analysis, and Rollback Plan.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly describes the main change: fixing a leak of Claude Code entrypoint environment variables to subprocesses, which is the core purpose of this PR.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@GouBuliya
Copy link
Copy Markdown
Author

@coleam00 @coleam00 我已经修复了 CLAUDE_CODE_ENTRYPOINT 泄漏到 Claude 子进程环境的问题,这个修复解决了嵌套 Claude Code 会话中 Archon 挂起的问题。@coleam00 我已经修复了 CLAUDE_CODE_ENTRYPOINT 泄漏到 Claude 子进程环境的问题,这个修复解决了嵌套 Claude Code 会话中 Archon 挂起的问题。

Copy link
Copy Markdown

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/utils/env-leak-scanner.ts`:
- Around line 135-146: The generated grep pipeline is invalid for multiple keys
and may include unsafe patterns; update the code that builds grepCommand (using
keysArray/allKeys/report.findings) to first filter keys to only valid env
variable names (e.g. /^[A-Za-z_][A-Za-z0-9_]*$/), skip if none remain, escape
regex metacharacters for each key (add a small escapeRegex helper), and then
build a safe pipeline that starts with "cat .env" and pipes through each grep -v
like: "cat .env | grep -v '^ESCAPED_KEY=' | grep -v '^OTHER_KEY=' > .env.tmp &&
mv .env.tmp .env" so each grep operates on the stream and the command is valid
for multiple keys.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 25c4fd09-78cd-418b-a229-03df79c376cc

📥 Commits

Reviewing files that changed from the base of the PR and between 6a6740a and 3a4e017.

📒 Files selected for processing (3)
  • README.md
  • packages/core/src/utils/env-leak-scanner.ts
  • packages/providers/src/claude/provider.ts

Comment on lines +135 to +146
// Collect all unique keys from findings
const allKeys = new Set<string>();
report.findings.forEach(finding => {
finding.keys.forEach(key => allKeys.add(key));
});
const keysArray = Array.from(allKeys);

// Generate grep command that excludes all detected keys
const grepCommand = keysArray
.map(key => `grep -v '^${key}='`)
.join(' | ') + ' .env > .env.tmp && mv .env.tmp .env';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix generated remediation command for multiple keys.

Line 143-145 builds an invalid pipeline for >1 key (only the last grep gets .env). It also includes non-env placeholders (e.g. unreadable markers), which can generate broken regex patterns.

💡 Proposed fix
-  // Collect all unique keys from findings
-  const allKeys = new Set<string>();
-  report.findings.forEach(finding => {
-    finding.keys.forEach(key => allKeys.add(key));
-  });
-  const keysArray = Array.from(allKeys);
-
-  // Generate grep command that excludes all detected keys
-  const grepCommand = keysArray
-    .map(key => `grep -v '^${key}='`)
-    .join(' | ') + ' .env > .env.tmp && mv .env.tmp .env';
+  // Collect unique concrete env var keys only (skip diagnostic placeholders)
+  const keysArray = Array.from(new Set(report.findings.flatMap(f => f.keys))).filter(key =>
+    /^[A-Z_][A-Z0-9_]*$/.test(key)
+  );
+
+  const escapedKeys = keysArray.map(key => key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
+  const grepCommand =
+    escapedKeys.length > 0
+      ? `grep -v -E '^(${escapedKeys.join('|')})=' .env > .env.tmp && mv .env.tmp .env`
+      : '# No concrete key names could be derived; remove keys manually from .env';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Collect all unique keys from findings
const allKeys = new Set<string>();
report.findings.forEach(finding => {
finding.keys.forEach(key => allKeys.add(key));
});
const keysArray = Array.from(allKeys);
// Generate grep command that excludes all detected keys
const grepCommand = keysArray
.map(key => `grep -v '^${key}='`)
.join(' | ') + ' .env > .env.tmp && mv .env.tmp .env';
// Collect unique concrete env var keys only (skip diagnostic placeholders)
const keysArray = Array.from(new Set(report.findings.flatMap(f => f.keys))).filter(key =>
/^[A-Z_][A-Z0-9_]*$/.test(key)
);
const escapedKeys = keysArray.map(key => key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
const grepCommand =
escapedKeys.length > 0
? `grep -v -E '^(${escapedKeys.join('|')})=' .env > .env.tmp && mv .env.tmp .env`
: '# No concrete key names could be derived; remove keys manually from .env';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/utils/env-leak-scanner.ts` around lines 135 - 146, The
generated grep pipeline is invalid for multiple keys and may include unsafe
patterns; update the code that builds grepCommand (using
keysArray/allKeys/report.findings) to first filter keys to only valid env
variable names (e.g. /^[A-Za-z_][A-Za-z0-9_]*$/), skip if none remain, escape
regex metacharacters for each key (add a small escapeRegex helper), and then
build a safe pipeline that starts with "cat .env" and pipes through each grep -v
like: "cat .env | grep -v '^ESCAPED_KEY=' | grep -v '^OTHER_KEY=' > .env.tmp &&
mv .env.tmp .env" so each grep operates on the stream and the command is valid
for multiple keys.

@Wirasm
Copy link
Copy Markdown
Collaborator

Wirasm commented Apr 13, 2026

Closing — #1150 (the underlying issue) is now fixed structurally in #1169 (merged into dev) via executableArgs: ['--no-env-file'] on the Claude Code subprocess. This prevents Bun from auto-loading .env from the CWD entirely, which was the actual root cause — the markers were being re-injected by the child Bun runtime, not leaking from the parent. E2E verified: Claude workflows run clean from within a Claude Code session. Thanks for the defense-in-depth approach — the double-filter idea confirmed the leak was in the child process.

@Wirasm Wirasm closed this Apr 13, 2026
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.

3 participants