The passphrase prompt reads stdin, so secret add --force with a piped value and secret encrypt/decrypt from stdin cannot ask for the passphrase #144

Open
opened 2026-10-13 00:30:28 +02:00 by clawbot · 0 comments
Collaborator

Severity: major. The documented way to give a value, echo value | secret add name, fails as soon as the command needs the long-term key, and the only way out is SB_UNLOCK_PASSPHRASE, which the README warns against.

What happens. readFromTerminal refuses when stdin is not a terminal and otherwise reads the passphrase from stdin. A first add needs only the public key, but --force sets notAfter on the previous version, which needs the long-term key; encrypt and decrypt need the key secret decrypted.

echo v2 | secret add s1 --force
# Error: failed to get long-term key: failed to get unlocker identity: failed to read passphrase: stdin is not a terminal (piped input or script). Please set the SB_UNLOCK_PASSPHRASE environment variable or run interactively
cat doc.txt | secret encrypt mykey        # same error
cat doc.age | secret decrypt mykey        # same error

Where.

if !term.IsTerminal(syscall.Stdin) {
and
input, err := term.ReadPassword(syscall.Stdin)
;
buffers, totalSize, err := readSecretFromReader(cli.cmd.InOrStdin())
(value read from stdin) then
err = v.updatePreviousVersion(previousVersion, &now)
(unlock for --force);
var input io.Reader = os.Stdin
.

Correct behaviour. The README's --force says "Overwrite existing secret" with no condition, and secret encrypt says input is stdin by default. Recommended: prompt on the controlling terminal (/dev/tty), as gpg, ssh and sudo do, and keep the current error only when there is none.

Definition of done

  • echo v | secret add s1 --force at a terminal asks for the passphrase and succeeds.
  • cat file | secret encrypt key and cat file.age | secret decrypt key ask and succeed.
  • A test under a pseudo-terminal with piped stdin fails before the fix.

Model: fable-5-1

Severity: major. The documented way to give a value, `echo value | secret add name`, fails as soon as the command needs the long-term key, and the only way out is `SB_UNLOCK_PASSPHRASE`, which the README warns against. **What happens.** `readFromTerminal` refuses when stdin is not a terminal and otherwise reads the passphrase from stdin. A first `add` needs only the public key, but `--force` sets `notAfter` on the previous version, which needs the long-term key; `encrypt` and `decrypt` need the key secret decrypted. ``` echo v2 | secret add s1 --force # Error: failed to get long-term key: failed to get unlocker identity: failed to read passphrase: stdin is not a terminal (piped input or script). Please set the SB_UNLOCK_PASSPHRASE environment variable or run interactively cat doc.txt | secret encrypt mykey # same error cat doc.age | secret decrypt mykey # same error ``` **Where.** https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/secret/crypto.go#L204 and https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/secret/crypto.go#L222; https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/cli/secrets.go#L376 (value read from stdin) then https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/vault/secrets.go#L232 (unlock for `--force`); https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/cli/crypto.go#L179. **Correct behaviour.** The README's `--force` says "Overwrite existing secret" with no condition, and `secret encrypt` says input is stdin by default. Recommended: prompt on the controlling terminal (`/dev/tty`), as gpg, ssh and sudo do, and keep the current error only when there is none. **Definition of done** - `echo v | secret add s1 --force` at a terminal asks for the passphrase and succeeds. - `cat file | secret encrypt key` and `cat file.age | secret decrypt key` ask and succeed. - A test under a pseudo-terminal with piped stdin fails before the fix. Model: fable-5-1
sneak was assigned by clawbot 2026-10-13 00:30:28 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/secret#144