Skip to content

Secret scanning at prompt submission: redact tokens before they reach the model/context (opt-out, on by default) #44717

Closed as not planned

Description

@deviceargent

Description

Users routinely paste live credentials into the chat, usually following CLI docs verbatim:

export KAGGLE_API_TOKEN=KGAT_d22b...        # straight from Kaggle's setup page
OPENROUTER_API_KEY=sk-or-v1-...             # straight from OpenRouter

Once Enter is pressed, the secret:

  1. Leaves the machine to the LLM provider inside the prompt,
  2. Persists in local session storage / history,
  3. Can leak further through share exports, log files, compaction summaries, and any later replay of that context.

There is currently no mitigation layer between "user pressed enter" and "the secret is now everywhere". For an agent CLI whose users live in terminals, this is arguably the most common real-world credential footgun.

What plugins can and cannot cover today

I built a working plugin (guardian-secretos) that scans tool.execute.before payloads for known token shapes (Kaggle KGAT_, OpenRouter sk-or-v1-, GitHub ghp_/github_pat_, AWS AKIA, Slack xox*-, JWTs, PEM blocks), archives matches DPAPI-encrypted on Windows, and prepends a visible warning to bash commands that contain them.

But the plugin layer structurally cannot protect the highest-risk path: a secret typed directly into the prompt has already been sent to the model before any hook sees it, and it stays in plaintext in session storage forever.

Proposal

First-class secret handling at prompt submission, on by default (opt-out):

  1. Detect high-signal token patterns in user input at submit time (gitleaks / GitHub secret-scanning regex sets are good baselines).
  2. Redact + stash: replace each match with a stable placeholder ({secret:kaggle-1}) and archive the value OS-side — DPAPI on Windows, Keychain on macOS, libsecret on Linux.
  3. Warn visibly: one dismissible TUI line ("2 possible secrets archived locally and replaced with placeholders"). A strict mode could refuse send until confirmed.
  4. Persistence hygiene: placeholders instead of plaintext automatically protect session DBs, share exports and logs.
  5. Optionally expose a way for tools/agents to resolve {secret:id} at execution time (env injection), so stashed values stay usable without re-entering plaintext context.

Why on by default

The users most at risk are exactly the ones who will never find an opt-in setting. A visible, low-friction warning keeps the happy path unchanged while turning the failure mode from "rotate everything, audit every share" into "rotate one token".

Happy to contribute the pattern set or port the plugin logic if this lands as a core feature.

Environment

Activity

  1. github-actions commented on Aug 24, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of or closely related to existing issues. Please check:

    • Agent exposes API keys in terminal output without warning user #36647: "Agent exposes API keys in terminal output without warning user" — same concern about credential exposure, though that issue focuses on redacting secrets in tool output while this one focuses on redacting secrets at prompt submission time. The two are complementary and might be best addressed together.

    If these are intentionally separate requests targeting different layers of the same problem, feel free to clarify how they differ so maintainers can track them independently.

  2. tkoop commented on Sep 26, 2026

    @tkoop

    This is a good idea. We should do this. I would up-vote this if I could.

  3. thdxr commented on Oct 11, 2026

    @thdxr
    Member

    Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.

    — from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions