gabriel / muse public
patch task/tty-gated-mnemonic #1 / 1
AI Agent gabriel · 162 days ago · Apr 17, 2026 · Diff

security: suppress mnemonic display in non-TTY contexts

Mnemonic was printed unconditionally to stderr, leaking into CI logs, piped output, and terminal scroll buffers.

New behaviour mirrors GPG / ssh-keygen: - stderr is a TTY → show full mnemonic box (user is watching, can write it down) - stderr is not a TTY → suppress mnemonic; print word count + hint to re-run interactively in a terminal

Add _stderr_isatty() module hook for test monkeypatching. Add 9 tests in test_auth_mnemonic_display.py covering both paths and the JSON boundary (mnemonic_word_count preserved, plaintext never in stdout). Update test_hd_keygen_unified.py to patch _stderr_isatty when asserting the mnemonic appears in output.

sha256:5e946ca6a85d4bbd868aa9e0e9789b9714596c93ac80a468deb871d834212485 sha
+28 ~3 symbols
sha256:17c0c1d83636bef7a356409324b69e63a9a7692796002f9154b54d71dfca1fd6 snapshot
+28
symbols added
~3
symbols modified
0
dead code introduced
Semantic Changes 31 symbols
~ tests/test_auth_mnemonic_display.py .py 27 symbols added
+ TestMnemonicNeverInStdout class class TestMnemonicNeverInStdout L183–205
+ test_III1_mnemonic_absent_json_plus_non_tty method method test_III1_mnemonic_absent_json_plus_non_tty L184–191
+ test_III2_mnemonic_never_in_json_payload method method test_III2_mnemonic_never_in_json_payload L193–205
+ TestNonTtyMnemonicSuppressed class class TestNonTtyMnemonicSuppressed L89–131
+ test_I1_mnemonic_not_in_output method method test_I1_mnemonic_not_in_output L90–100
+ test_I2_output_contains_word_count method method test_I2_output_contains_word_count L102–108
+ test_I3_output_hints_to_run_interactively method method test_I3_output_hints_to_run_interactively L110–119
+ test_I4_json_has_word_count_not_plaintext method method test_I4_json_has_word_count_not_plaintext L121–131
+ TestTtyMnemonicDisplayed class class TestTtyMnemonicDisplayed L139–175
+ test_II1_full_mnemonic_in_output method method test_II1_full_mnemonic_in_output L140–148
+ test_II2_displayed_mnemonic_is_valid_bip39 method method test_II2_displayed_mnemonic_is_valid_bip39 L150–164
+ test_II3_json_word_count_correct_on_tty method method test_II3_json_word_count_correct_on_tty L166–175
+ _HUB variable variable _HUB L44–44
+ _MNEMONIC variable variable _MNEMONIC L45–48
+ _enable_tty function function _enable_tty L78–81
+ _keygen function function _keygen L74–75
+ fixed_mnemonic function function fixed_mnemonic L68–71
+ CliRunner import import CliRunner L37–37
+ annotations import import annotations L30–30
+ id_module import import id_module L39–39
+ json import import json L32–32
+ kp_module import import kp_module L38–38
+ pathlib import import pathlib L33–33
+ pytest import import pytest L35–35
+ validate_mnemonic import import validate_mnemonic L40–40
+ isolated function function isolated L57–64
+ runner variable variable runner L42–42
~ muse/cli/commands/auth.py .py 1 symbol added, 1 symbol modified
+ _stderr_isatty function function _stderr_isatty L108–109
← Older Oldest on task/tty-gated-mnemonic
All commits
Newer → Latest on task/tty-gated-mnemonic

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:5e946ca6a85d4bbd868aa9e0e9789b9714596c93ac80a468deb871d834212485 --body "your comment"