Commands that prompt for a mnemonic or passphrase hold the state directory lock while waiting, so other changing commands wait silently #152

Closed
opened 2026-10-13 00:31:01 +02:00 by clawbot · 1 comment
Collaborator

Severity: minor
secret init, secret vault create, secret unlocker add, and secret add --force, generate secret --force and import --force on an existing secret take the state directory lock before they ask for the mnemonic or passphrase, so while one of them waits at a prompt every other command that changes anything waits silently, with no message and no limit; a prompt left open in one terminal stops secret add in another until it is answered. The removal commands deliberately ask before taking the lock "so that no other command waits while the user answers" (confirm.go); these do the opposite. Reads are not affected.

Reproduction (one terminal, no SB_UNLOCK_PASSPHRASE):

SB_SECRET_MNEMONIC="$M" secret vault create work
Enter passphrase for unlocker:       # leave it waiting

Another shell:

echo -n v | SB_UNLOCK_PASSPHRASE=pw timeout 5 secret add x; echo $?
# prints nothing, exit 124 after 5 s; succeeds at once after the prompt is answered or killed

Where:

release, err := vault.LockStateDir(cli.fs, cli.stateDir)
(lock) before L103 and L130 (prompts);
release, err := vault.LockStateDir(cli.fs, cli.stateDir)
before L268 and L289;
release, err := vault.LockStateDir(cli.fs, cli.stateDir)
before L470 and the unlock inside CreatePassphraseUnlocker/CreatePGPUnlocker;
release, err := vault.LockStateDir(cli.fs, cli.stateDir)
before the unlock prompt in updatePreviousVersion (
ltIdentity, err := v.GetOrDeriveLongTermKey()
).

Correct behaviour is a product decision the README does not settle. Recommended: read the mnemonic and passphrase, and unlock the vault, before taking the lock (as the removal commands and secret add reading stdin already do), and have a command that must wait for the lock say so after a moment.

Definition of done

  • No command holds the lock while waiting at a prompt, or a command waiting for the lock prints that it is waiting and why.
  • A regression test, on the in-memory filesystem, holds the lock and shows the prompt is reached (or the wait is reported) while it is held; it fails before the fix.

Model: fable-5-1

Severity: minor `secret init`, `secret vault create`, `secret unlocker add`, and `secret add --force`, `generate secret --force` and `import --force` on an existing secret take the state directory lock before they ask for the mnemonic or passphrase, so while one of them waits at a prompt every other command that changes anything waits silently, with no message and no limit; a prompt left open in one terminal stops `secret add` in another until it is answered. The removal commands deliberately ask before taking the lock "so that no other command waits while the user answers" (`confirm.go`); these do the opposite. Reads are not affected. Reproduction (one terminal, no `SB_UNLOCK_PASSPHRASE`): ``` SB_SECRET_MNEMONIC="$M" secret vault create work Enter passphrase for unlocker: # leave it waiting ``` Another shell: ``` echo -n v | SB_UNLOCK_PASSPHRASE=pw timeout 5 secret add x; echo $? # prints nothing, exit 124 after 5 s; succeeds at once after the prompt is answered or killed ``` Where: https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/cli/init.go#L73 (lock) before L103 and L130 (prompts); https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/cli/vault.go#L262 before L268 and L289; https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/cli/unlockers.go#L414 before L470 and the unlock inside `CreatePassphraseUnlocker`/`CreatePGPUnlocker`; https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/cli/secrets.go#L405 before the unlock prompt in `updatePreviousVersion` (https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/vault/secrets.go#L645). Correct behaviour is a product decision the README does not settle. Recommended: read the mnemonic and passphrase, and unlock the vault, before taking the lock (as the removal commands and `secret add` reading stdin already do), and have a command that must wait for the lock say so after a moment. **Definition of done** - No command holds the lock while waiting at a prompt, or a command waiting for the lock prints that it is waiting and why. - A regression test, on the in-memory filesystem, holds the lock and shows the prompt is reached (or the wait is reported) while it is held; it fails before the fix. Model: fable-5-1
sneak was assigned by clawbot 2026-10-13 00:31:01 +02:00
Author
Collaborator

Reassigned to clawbot: sneak ruled that nothing is a release candidate while a known bug is open (sneak/project-management#32).

Plan: the issue's recommendation: these commands read the mnemonic and passphrase, and unlock the vault, before taking the state directory lock, as the removal commands already do; what must hold under the lock is checked again under it. No waiting message is added: with no prompt under the lock, no command holds it for long. Built after #136, #151 and #154, which change the same code.

Model: opus-5-5

Reassigned to clawbot: sneak ruled that nothing is a release candidate while a known bug is open (https://git.eeqj.de/sneak/project-management/issues/32). Plan: the issue's recommendation: these commands read the mnemonic and passphrase, and unlock the vault, before taking the state directory lock, as the removal commands already do; what must hold under the lock is checked again under it. No waiting message is added: with no prompt under the lock, no command holds it for long. Built after https://git.eeqj.de/sneak/secret/issues/136, https://git.eeqj.de/sneak/secret/issues/151 and https://git.eeqj.de/sneak/secret/issues/154, which change the same code. Model: opus-5-5
sneak was unassigned by clawbot 2026-10-14 19:42:56 +02:00
clawbot self-assigned this 2026-10-14 19:42:56 +02:00
clawbot added this to the 1.0.0 milestone 2026-10-14 19:42:56 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/secret#152