fix(mcp): keep the new secret out of argv on secret rotate #119
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/YT-62-secret-rotate-no-argv-secret"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
yt mcp secret rotatetook its only input as--hub-client-secret <value>, so the replacement for a leaked secret went into the shell's history before the process started, and sat in world-readable/proc/<pid>/cmdline(mode 0444) for the duration of the run, where any local user could read it out ofps. Anything that records commands (sudo logs, shell tracing, CI job logs, session recordings) captured it too. The command exists as the security response to a leakedYOUTRACK_MCP_HUB_CLIENT_SECRET, and its only input channel leaked the replacement. YT-61 made the operator's value the sole source, so that was no longer an edge case but the normal path.The flag is gone, replaced by three channels resolved in order:
--hub-client-secret-stdin(docker login --password-stdin's idiom, stripping exactly one trailing newline and nothing else, so a value ending in whitespace survives),$YOUTRACK_MCP_HUB_CLIENT_SECRET_NEW, then an unechoedrpasswordprompt. The prompt is last because it is the only channel an automation cannot drive, so anything passed deliberately outranks it. With no terminal and neither non-interactive channel set, the command exits non-zero naming both, having written nothing.The environment variable is deliberately not the service's own
YOUTRACK_MCP_HUB_CLIENT_SECRET: a shell that has sourcedmcp.envalready exports that one, holding the value being rotated away from, and reading it here would re-apply the leaked secret while reporting a successful rotation./proc/<pid>/environis mode 0400, so unlike argv it is not exposed to other local users.--hub-client-secret-stdinrequires--yes, checked before stdin is read: the secret consumes stdin, so the confirmation's read would hit EOF and abort the rotation, which reads as a hang or a silent no-op rather than a missing flag.The error text no longer teaches the argv form, and names no secret value on any path, including the empty-value refusal, which names only the channel it came from. The empty check now covers all three channels rather than argv alone.
Removing a flag shipped in 0.11.0 is breaking. It shipped hours ago, its only documented use is a security response, and every existing invocation of it already leaked the secret it passed, so removal beats a deprecation window whose warning would print after the value is already in history and in
ps.no_flag_takes_the_secret_as_a_valuepins the removal against the parser rather than a review note, so a value-taking spelling cannot come back unnoticed.#YT-62
secret rotate