Skip to content

feat(run): mask fetched values by default; --no-mask turns it off - #171

Merged
groupsky merged 6 commits into
mainfrom
feat/170-mask-default
Nov 11, 2026
Merged

groupsky merged 6 commits into
mainfrom
feat/170-mask-default

Conversation

@groupsky

@groupsky groupsky commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Refs #170

nodkey run masks fetched values by default. --no-mask turns it off for one run.

Rule for terminals

When both stdout and stderr of nodkey run are terminals, the default
keeps the old execve path: the command owns the terminal, so editors,
ssh, prompts and colour work, and its output is not masked. In every other
case (a pipe or a file on stdout or stderr, which is how an agent reads
output) the command runs as a child and both streams are masked.
--mask forces the mask also on a terminal. --no-mask always uses execve.

Why this rule and not "always mask": the issue allows it, and a person in
a terminal gets a working ssh, editor or prompt without a new flag. The
security review noted the risk: an agent that runs its commands in a
pseudo-terminal of its own gets the values unmasked. THREAT-MODEL.md T15
says this, and --mask masks also on a terminal. A config setting or a
line in the phone message about masking can come later, as its own issue.

Not changed from the review: the ioctl check is now in internal/client
and in cmd/nodkey (for nodkey version). They take different inputs; a
shared package for 5 lines is not worth it now.

Why not a pseudo-terminal: it needs much more code (raw mode, window size,
job control, SIGWINCH) and new risk, for the case where a person, not an
agent, reads the output. The leaner rule covers the agent case.

Progress

  • nodkey run without flags masks values in stdout and stderr (canary tests)
  • nodkey run --no-mask behaves as before PR feat(run): --mask hides fetched values in the command's output #169 (execve, no child); test
  • Terminal rule tested (TestRunMaskRule, TestIsTerminal) and documented (DESIGN.md section 5)
  • Exit code and signals reach the caller as before (tests)
  • DESIGN.md, THREAT-MODEL.md (T15), docs/setup.md updated; PR title names the new default and --no-mask (changelog)
  • Security review and code review, findings fixed

@groupsky
groupsky marked this pull request as ready for review November 11, 2026 11:50
@groupsky
groupsky merged commit 6e42f97 into main Nov 11, 2026
7 checks passed
@groupsky
groupsky deleted the feat/170-mask-default branch November 11, 2026 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant