No way to hand the daemon a secret without it passing through the model transcript #22

Open
opened 2026-08-28 17:09:53 +09:00 by floot · 1 comment
Owner

In session mt82q1ns-l8nrge the operator pasted a Google service-account JSON
— including the full private_key — into chat so a calendar integration could
be tried. The agent then embedded it verbatim as a string literal inside an
mcp__endo__exec body.

The key is now in plaintext in the session JSONL at least twice: once as the
user message, once as tool input. It is also in whatever context windows that
session used.

There is no capability-shaped alternative. Every route to "give the daemon a
credential" currently runs through the agent as text.

Wanted: a secret-ingestion path where the operator submits the value to the
daemon directly (a form field, a drop target, a paste box in the UI) and the
agent receives only a capability referring to it — never the bytes. The agent
should be able to say "send me a credential for X" and get back a handle it can
pass to provideGitRemote, provideHttpClient and friends.

In session `mt82q1ns-l8nrge` the operator pasted a Google service-account JSON — including the full `private_key` — into chat so a calendar integration could be tried. The agent then embedded it verbatim as a string literal inside an `mcp__endo__exec` body. The key is now in plaintext in the session JSONL at least twice: once as the user message, once as tool input. It is also in whatever context windows that session used. There is no capability-shaped alternative. Every route to "give the daemon a credential" currently runs through the agent as text. **Wanted:** a secret-ingestion path where the operator submits the value to the daemon directly (a form field, a drop target, a paste box in the UI) and the agent receives only a capability referring to it — never the bytes. The agent should be able to say "send me a credential for X" and get back a handle it can pass to `provideGitRemote`, `provideHttpClient` and friends.
Author
Owner

Implemented on feature/secret-ingestion (a48bea2b3).

  • New requestSecret / writeSecret tools on every Floot session (API and Claude CLI). The operator gets a paste box in the Floot UI; the model receives only { petName, kind, audience, byteLength }.
  • EndoHost.writeSecret(mount, path, credential) writes material to a mount without revealing it.
  • Form fields marked secret plus asCredential / audience / secretKind mint a credential cap on submit instead of storing the string. Existing Lal-style secret: true fields are unchanged.
  • Prompts now tell the agent never to ask for secrets in chat or put them in exec.

Not deployed yet. After review we pin this revision and the paste box will be live.

Implemented on `feature/secret-ingestion` (`a48bea2b3`). - New `requestSecret` / `writeSecret` tools on every Floot session (API and Claude CLI). The operator gets a paste box in the Floot UI; the model receives only `{ petName, kind, audience, byteLength }`. - `EndoHost.writeSecret(mount, path, credential)` writes material to a mount without revealing it. - Form fields marked `secret` plus `asCredential` / `audience` / `secretKind` mint a credential cap on submit instead of storing the string. Existing Lal-style `secret: true` fields are unchanged. - Prompts now tell the agent never to ask for secrets in chat or put them in exec. Not deployed yet. After review we pin this revision and the paste box will be live.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
floot/endo#22
No description provided.