Skip to content

fix(opencode): redact output.metadata, not just output.output - #9

Merged
arr-wf merged 4 commits into
mainfrom
fix/opencode-metadata-leak
Aug 27, 2026
Merged

fix(opencode): redact output.metadata, not just output.output#9
arr-wf merged 4 commits into
mainfrom
fix/opencode-metadata-leak

Conversation

@arr-wf

@arr-wf arr-wf commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • OpenCode's tool.execute.after hook exposes output as three independently-mutable fields: title, output, metadata. ctxcop's bridge only ever redacted output.output — the field the model reads next turn.
  • OpenCode separately populates output.metadata with a raw copy of the tool's result and persists it to the session store (and includes it in --format json / opencode export), independent of output.output. A secret fully redacted in what the model sees could still sit in plaintext in session metadata.
  • Confirmed live: ran real OpenCode sessions (a Linux container, then interactively on macOS via the actual TUI) with synthetic fake secrets (AWS, GitHub PAT, OpenAI, Anthropic key shapes). output.output came back correctly redacted while output.metadata.output still carried three of the four raw values, byte-for-byte, in the exported session JSON.

Fix

  • internal/harness/opencode/tool_execute_after.go: now also walks and redacts metadata via redact.RedactTreeToolOutput — the same tree-walker claudecode/cursor/pi already use for their tree-shaped payloads. OpenCode's adapter was the outlier because its hook contract splits output into a flat string plus a separate metadata field instead of one tree.
  • internal/harness/opencode/extension/ctxcop.ts: forwards output.metadata to the Go binary and reapplies the redacted result via replaceInPlace, consistent with how tool.execute.before already preserves object identity for args.
  • CHANGELOG.md: Security entry under Unreleased.

Also bundled: Webflow OSS branding

Added the Webflow logo + a short "Webflow Open Source" blurb to the README, matching webflow/codeflow's pattern (same logo asset). Unrelated to the security fix — bundled at Andrew's request since we were touching the repo anyway.

Test plan

  • go test ./internal/harness/opencode/... — added TestToolExecuteAfterRedactsMetadataEvenWhenOutputClean, all existing tests pass unchanged.
  • Reproduced the leak and the fix live against the real opencode binary (v1.18.23) with the real plugin loader (Bun), both in a Linux container and interactively in a macOS terminal — confirmed via byte-level inspection of the session's exported JSON, not just what's rendered in the TUI.

🤖 Generated with Claude Code

arr-wf and others added 4 commits August 27, 2026 15:09
OpenCode's tool.execute.after hook exposes metadata as a separate
mutable field alongside output. OpenCode populates metadata with a
raw copy of the tool result and persists it to the session store
(and includes it in --format json / opencode export) independently
of output.output — so a secret fully redacted in the field the model
sees could still survive in plaintext in session metadata. Confirmed
live against real bash tool output in an OpenCode session.

Redact metadata via the same RedactTreeToolOutput walker the
claudecode/cursor/pi adapters already use for their tree-shaped
payloads.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Logo + a short blurb, per Utkarsh's request in the open-sourcing
Slack thread. Logo asset matches webflow/codeflow's, the other public
Webflow repo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@arr-wf
arr-wf requested a review from mohammadualam August 27, 2026 22:19
@arr-wf
arr-wf merged commit 95f5de7 into main Aug 27, 2026
14 checks passed
@arr-wf arr-wf mentioned this pull request Aug 27, 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.

2 participants