Skip to content

feat(harness): hard-block the embedded agent from reading .env; drop WebFetch - #57

Merged
itelo merged 1 commit into
mainfrom
itelo/eng-2925-wizard-hard-block-the-embedded-agent-from-reading-env
Aug 24, 2026
Merged

feat(harness): hard-block the embedded agent from reading .env; drop WebFetch#57
itelo merged 1 commit into
mainfrom
itelo/eng-2925-wizard-hard-block-the-embedded-agent-from-reading-env

Conversation

@itelo

@itelo itelo commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes the gap where the wizard's embedded integration agent was only instructed not to read secrets (a system-prompt line), with no enforcement. A developer's .env routinely holds secrets beyond the Seam key — DB URLs, Stripe keys, etc. — that must never enter the model context.

Implements ENG-2925.

Changes

  • PreToolUse deny hook (src/lib/steps/harness/anthropic.ts): blocks any tool call whose input targets .env / .env.* (except .env.example). A deny overrides the broad Read allow and fires for every tool, so Read/Grep/Edit/Write are all covered.
  • Removed WebFetch from ALLOWED_TOOLS (the "review WebFetch" ask): arbitrary web egress isn't needed — references come from the seam-docs MCP, and the pi harness already omits it — and it was the obvious exfiltration channel. Reintroduce behind an allowlist if a real need appears.
  • Shared helper src/lib/steps/harness/secret-paths.ts (isSecretFilePath / toolInputTouchesSecret) with unit tests.

Already safe (unchanged, for context)

  • The Anthropic key never leaves Seam's serverbuildAgentEnv drops ANTHROPIC_API_KEY and injects only the short-lived scoped wizard token.
  • The Seam key stays out of git.env gitignored + value-less .env.example.
  • No Bash / no subagents in either harness.

Scope / follow-ups (in ENG-2925)

  • pi harness (eval-only) guard is deferred: pi only runs under SEAM_WIZARD_HARNESS=pi (eval), the eval workspace carries no real secret, and pi's ToolDef.execute shape isn't documented enough to guard without guessing.
  • Residual: a broad Grep across the repo could still surface secret lines from other files; a PostToolUse redaction pass is the natural next step. The direct-.env-access vector is closed here.

Testing

  • npm run lint clean
  • npm run typecheck clean
  • npm test — 155 passed (+5 new: secret-paths.test.ts)

Security & Compliance

  • Security hardening (defense-in-depth); no secrets in the diff.

🤖 Generated with Claude Code

The embedded integration agent was only *instructed* not to read secrets — no
enforcement. A developer's .env routinely holds secrets beyond the Seam key
(DB URLs, Stripe keys, …) that must never enter the model context.

- Add a PreToolUse deny hook (anthropic harness) that blocks any tool whose
  input targets .env / .env.* (except .env.example). A deny overrides the broad
  Read allow and fires for every tool, so Read/Grep/Edit/Write are all covered.
- Remove WebFetch from ALLOWED_TOOLS: arbitrary web egress isn't needed (docs
  come from the seam-docs MCP; the pi harness already omits it) and it was the
  obvious exfiltration channel.
- Shared, unit-tested helpers isSecretFilePath / toolInputTouchesSecret.

pi harness (eval-only) tracked as a follow-up in ENG-2925.
@itelo
itelo requested a review from razor-x as a code owner August 24, 2026 18:59
@itelo
itelo merged commit 72db368 into main Aug 24, 2026
11 checks passed
@itelo
itelo deleted the itelo/eng-2925-wizard-hard-block-the-embedded-agent-from-reading-env branch August 24, 2026 19:10
itelo added a commit that referenced this pull request Aug 24, 2026
Follow-up to ENG-2925 (#57), completing ENG-2926.

- pi harness: wrap the built-in Read/Edit/Write/Ls/Find/Grep tools so a call
  whose input targets a secret file (.env, …) is refused before it runs —
  parity with the anthropic PreToolUse deny. Reuses toolInputTouchesSecret;
  pi's path fields (path/glob/dir/directory) are now covered too.
- anthropic harness: add a PostToolUse hook that strips .env-sourced lines from
  Grep output via updatedToolOutput. The PreToolUse deny only fires when a tool
  *names* a secret path, so a repo-wide grep (path ".") could still surface
  .env lines; this closes that residual.
- secret-paths.ts: add redactSecretGrepLines + the pi path-field keys, with tests.
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.

1 participant