Skip to content

Fix: opencode auto-memory-update leaks full transcript via process argv (ps/procfs) - #152

Closed
priyamkarn wants to merge 3 commits into
Autoloops:mainfrom
priyamkarn:fix/opencode-prompt-argv-exposure
Closed

priyamkarn wants to merge 3 commits into
Autoloops:mainfrom
priyamkarn:fix/opencode-prompt-argv-exposure

Conversation

@priyamkarn

Copy link
Copy Markdown
Contributor

Bug

runOpenCodeAgent (libs/agent-runner/opencode.ts) passed the full working-memory-update
prompt -- which embeds the entire session transcript -- as a literal -p <text>
command-line argument to the opencode binary:

const args = ["-p", input.prompt, "-f", "json", "-q"];

Process arguments are visible to other local users via ps aux / /proc/<pid>/cmdline
for as long as the process runs. This isn't a one-off CLI invocation -- it runs
automatically and unattended via the background hook worker on every coding session
(libs/hooks/worker.ts), so the exposure window recurs continuously.

Why opencode specifically

  • codex.ts already writes the prompt to stdin -- safe.
  • openhands.ts already writes it to a task file and passes the path -- safe.
  • opencode.ts was the outlier, passing raw content via argv.

I checked opencode's actual CLI docs before assuming "just switch to stdin" would work:
its prompt argument has no stdin or file-path option, only a literal -p value. So this
needed a different fix than the other two platforms use.

Fix

Write the prompt to a file (opencode-task-prompt.md) inside the same private run
directory worker.ts already creates via mkdtempSync (mode 0700 per POSIX), and pass
only a short, non-sensitive wrapper referencing that file path as the -p value. The
agent reads its real instructions itself via its own file tool -- same effective prompt
content, just relocated out of argv.

Confirmed runOpenCodeAgent has exactly one call path in the codebase (via worker.ts),
so this directory-privacy assumption holds everywhere it's actually used today.

Tests

scripts/check-opencode-prompt-file.js stubs a fake opencode binary that records its
own argv, runs the real built runOpenCodeAgent against it, and asserts: the sensitive
marker never appears in argv, the -p value references the prompt file, and the real
prompt content was actually written there. Wired into npm test.

priyamkarn and others added 3 commits July 13, 2026 06:57
…ss argv

runOpenCodeAgent passed the sensitive prompt (which embeds the full session transcript, including anything not yet caught by redaction) as a literal '-p' command-line argument. Process arguments are visible to other local users via ps/proc for the lifetime of the process -- and this runs automatically, unattended, on every background auto-memory-update, not just when a human runs a CLI command.

codex.ts already avoids this via stdin and openhands.ts via a task file; opencode's CLI has no stdin/file option for its prompt though (confirmed against its docs), only a literal -p value, so the fix writes the prompt to a file inside the caller's private (mode 0700) run directory and passes only a short file-reference wrapper via argv instead.

Adds a regression test that stubs the opencode binary, captures its real argv, and asserts the sensitive content never appears there.
@priyamkarn priyamkarn closed this Aug 2, 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.

1 participant