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

Open
opened 2026-10-13 00:31:01 +02:00 by clawbot · 0 comments
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
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/secret#152