Skip to content

Commit 79542bc

Browse files
committed
mcp(docs[audit]): Clarify env redaction
why: Describe both accepted respawn environment representations and their distinct audit summaries. what: - Explain per-key redaction for mapping input - Explain scalar redaction for JSON object strings
1 parent 126c171 commit 79542bc

3 files changed

Lines changed: 12 additions & 11 deletions

File tree

docs/topics/safety.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ Mitigations:
111111

112112
- `pane_id` is required (no fallback to "first pane in session/window"). Agents that pass only `session_name` get an {exc}`~libtmux_mcp._utils.ExpectedToolError` instead of an unintended kill — resolve via {tool}`list-panes` first.
113113
- Any `shell` argument is briefly visible in the OS process table and tmux's `pane_current_command` metadata before the spawned shell takes over; the audit log redacts `shell` payloads (see below), but do not pass credentials directly even with redaction.
114-
- The optional `environment` argument (`dict[str, str]`) maps to one tmux `-e KEY=VALUE` flag per item. The audit log redacts each *value* via a `{len, sha256_prefix}` digest while keeping the *keys* visible — env var names like `DATABASE_URL` are usually operator-debug-useful, but their values are the secret. The same OS-process-table caveat as `shell` applies: `respawn-pane -e DB_PASSWORD=...` may briefly appear in `ps` output before the spawned process inherits the env.
114+
- The optional `environment` argument accepts either a mapping of string keys and values or a JSON object string, then maps each item to one tmux `-e KEY=VALUE` flag. For a mapping, the audit log keeps each *key* visible and replaces each *value* with a `{len, sha256_prefix}` digest. A JSON string is redacted as one scalar digest, so its keys are not retained in the audit record. The same OS-process-table caveat as `shell` applies: `respawn-pane -e DB_PASSWORD=...` may briefly appear in `ps` output before the spawned process inherits the env.
115115
- The same self-pane guard that protects the destructive kill commands also refuses to respawn the pane running the MCP server.
116116

117117
### Raw pane input

src/libtmux_mcp/middleware.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -440,11 +440,10 @@ async def on_call_tool(
440440
#: secrets, or arbitrary large strings.
441441
#: Matched by exact name, case-sensitive, to mirror the tool signatures.
442442
#:
443-
#: ``environment`` is dict-shaped (``dict[str, str]``); the redaction logic
444-
#: in :func:`_summarize_args` recognises this and digests each *value* while
445-
#: leaving the *keys* (env var names like ``DATABASE_URL``) visible — env
446-
#: var names are operator-debug-useful, but their values are the secret.
447-
#: All other entries are scalar strings; mixing the two is intentional.
443+
#: ``environment`` accepts a mapping or a JSON object string. The redaction
444+
#: logic in :func:`_summarize_args` digests each mapping *value* while leaving
445+
#: its *keys* (env var names like ``DATABASE_URL``) visible. A JSON string is
446+
#: instead redacted as one scalar digest, so its keys are not retained.
448447
#:
449448
#: Note on ``shell`` and ``environment`` redaction: this redacts the MCP
450449
#: audit log only. ``respawn_pane(shell="env SECRET=... bash")`` and

src/libtmux_mcp/tools/pane_tools/lifecycle.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,13 @@ def respawn_pane(
124124
Environment variables to set for the relaunched process. Each
125125
item becomes one ``-e KEY=VALUE`` flag (tmux's
126126
``cmd-respawn-pane.c`` supports the flag repeatedly). Values
127-
are redacted in the audit log on a per-key basis — keys like
128-
``DATABASE_URL`` remain visible but their values are replaced
129-
by ``{len, sha256_prefix}`` digests. Note that the values may
130-
still appear briefly in the OS process table while tmux spawns
131-
the new process; do not pass long-lived secrets here when a
127+
supplied in a mapping are redacted in the audit log on a
128+
per-key basis — keys like ``DATABASE_URL`` remain visible but
129+
their values are replaced by ``{len, sha256_prefix}`` digests.
130+
A JSON object string is redacted as one scalar digest, so its
131+
keys are not retained in the audit record. Values may still
132+
appear briefly in the OS process table while tmux spawns the
133+
new process; do not pass long-lived secrets here when a
132134
host-resident agent or other tenant could observe ``ps``.
133135
socket_name : str, optional
134136
tmux socket name.

0 commit comments

Comments
 (0)