docs(bash): reframe stdin/env — the scrub is the security control, not a trust boundary
Address review: the "trusted-plugin surface" framing overstated the security story. A model driving the `bash` tool already has equivalent power to set env vars and feed stdin through ordinary shell syntax (`FOO=bar cmd`, heredocs), so the `env`/`stdin` seam fields grant it no new capability — and they cannot exfiltrate the harness's ambient credentials, because the credential SCRUB in dsh-bash-local (which strips *KEY*/*SECRET*/*TOKEN* from process.env before the child sees it) is the actual control, and it works regardless of these fields (tool-call args are static JSON, never shell-evaluated). So drop the "dangerous / trusted-plugin boundary" language across the RFC, the three bash-package READMEs, the bash/src/types.ts JSDoc, and docs/bash.md (both the type-equiv blocks — kept 1:1 with source — and the prose). The reality that remains: the `bash` tool doesn't EXPOSE env/stdin as parameters because they'd be redundant with shell syntax; the fields exist for in-process plugins (the hooks bridges) to pass a JSON payload + CLAUDE_* vars cleanly. The guard test is kept but reframed: it catches a future `...args` spread that would silently forward model input into the post-scrub env merge, NOT a trust wall. No code or behavior change.
This commit is contained in:
@@ -47,19 +47,20 @@ export interface BashExecRequest {
|
||||
signal?: AbortSignal | undefined
|
||||
/**
|
||||
* Bytes to write to the command's stdin, then close it. Absent leaves stdin
|
||||
* closed/empty (the default for model-driven tool calls). A TRUSTED-PLUGIN
|
||||
* surface: the model-facing bash tool does NOT thread model-supplied input
|
||||
* here — it is set by in-process plugins (e.g. the hooks bridges, which write
|
||||
* a hook command's JSON payload to its stdin).
|
||||
* closed/empty (the default for model-driven tool calls). Set by in-process
|
||||
* plugins (e.g. the hooks bridges, which write a hook command's JSON payload
|
||||
* to its stdin); the model-facing bash tool does not expose it as a parameter
|
||||
* (a model that needs stdin uses shell syntax like a heredoc or a pipe).
|
||||
*/
|
||||
stdin?: string | undefined
|
||||
/**
|
||||
* Extra environment entries for the command, merged AFTER the
|
||||
* implementation's credential scrub (so an explicit entry here is honored even
|
||||
* when its name matches the scrub pattern — the caller takes responsibility).
|
||||
* Like {@link stdin}, a TRUSTED-PLUGIN surface: the model-facing bash tool
|
||||
* never forwards model-supplied env; in-process plugins (the hooks bridges)
|
||||
* set hook env vars (`CLAUDE_PROJECT_DIR`, `CLAUDE_PLUGIN_ROOT`, …) here.
|
||||
* when its name matches the scrub pattern — the caller named a value it holds,
|
||||
* not the harness's ambient secret). Set by in-process plugins (the hooks
|
||||
* bridges set `CLAUDE_PROJECT_DIR`, `CLAUDE_PLUGIN_ROOT`, …); the model-facing
|
||||
* bash tool does not expose it as a parameter (a model that needs an env var
|
||||
* uses shell syntax like `FOO=bar cmd`).
|
||||
*/
|
||||
env?: Record<string, string> | undefined
|
||||
/**
|
||||
@@ -92,8 +93,7 @@ export interface BashExecSpec {
|
||||
* verbatim from {@link BashExecRequest.stdin}. OPTIONAL on the resolved spec
|
||||
* (unlike `owner`): it has no config default, so a missing one means "no
|
||||
* stdin" — the safe, ordinary case — not a silent footgun, so it stays a
|
||||
* plain optional rather than required-but-nullable. A TRUSTED-PLUGIN surface
|
||||
* (see the request field).
|
||||
* plain optional rather than required-but-nullable (see the request field).
|
||||
*/
|
||||
stdin?: string | undefined
|
||||
/**
|
||||
@@ -101,7 +101,7 @@ export interface BashExecSpec {
|
||||
* {@link BashExecRequest.env} and merged by the implementation AFTER its
|
||||
* credential scrub (an explicit entry wins even when its name matches the
|
||||
* scrub pattern). OPTIONAL on the spec for the same reason as `stdin` — no
|
||||
* config default, absent means "no extra env". A TRUSTED-PLUGIN surface.
|
||||
* config default, absent means "no extra env".
|
||||
*/
|
||||
env?: Record<string, string> | undefined
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user