Give every new unlocker a directory of its own (closes #71)
check / check (push) Failing after 1s
check / check (push) Failing after 1s
A passphrase unlocker added to a vault that had one, and a PGP, keychain or Secure Enclave unlocker added on the same day as another of its type, were written into the existing unlocker's directory file by file, so a crash part-way left a current unlocker whose files did not belong together. Unlocker directories, keychain items and Secure Enclave keys are now named with the time to the nanosecond, and secret.WriteDir refuses a directory that exists. Adding a passphrase unlocker writes the new one, points current-unlocker at it, and only then removes the vault's other passphrase unlockers. Model: opus-5-5
This commit was merged in pull request #99.
This commit is contained in:
@@ -25,6 +25,20 @@ Bring the repo into policy compliance in one commit:
|
||||
|
||||
# Completed Steps
|
||||
|
||||
- 2026-10-04: A crash while an unlocker is being replaced no longer leaves a
|
||||
current unlocker that cannot open the vault
|
||||
(https://git.eeqj.de/sneak/secret/issues/71). Every new unlocker gets a
|
||||
directory of its own, named with the time to the nanosecond:
|
||||
`passphrase-<time>`, `<host>-pgp-<time>`, and for a keychain or Secure
|
||||
Enclave unlocker the keychain item or Secure Enclave key, which names the
|
||||
directory, carries the time instead of the day. `secret.WriteDir` fails on a
|
||||
directory that exists instead of writing into it. `unlocker add passphrase`
|
||||
writes the new unlocker, makes it current, and only then removes the vault's
|
||||
other passphrase unlockers; a crash between the last two steps leaves the old
|
||||
one beside the new, and the old passphrase still opens the vault through it
|
||||
until the next `unlocker add passphrase` or an `unlocker remove` removes it.
|
||||
A PGP, keychain or Secure Enclave unlocker added on the same host and day as
|
||||
another of its type is added beside it instead of replacing it.
|
||||
- 2026-10-04: `SB_SECRET_MNEMONIC` and `SB_UNLOCK_PASSPHRASE` are read once
|
||||
per command, in its `RunE`, into locked buffers on the CLI `Instance`, and
|
||||
unset at once, so that no program the command runs, `gpg` included,
|
||||
@@ -79,9 +93,7 @@ Bring the repo into policy compliance in one commit:
|
||||
and encrypt everything before writing anything. All four unlocker
|
||||
types write their files through `secret.WriteDir`: a new unlocker is
|
||||
built in a temporary directory, renamed into place when complete and
|
||||
removed on a failure. One added under the directory name of an
|
||||
existing unlocker is still written into that directory in place
|
||||
(https://git.eeqj.de/sneak/secret/issues/71).
|
||||
removed on a failure.
|
||||
- 2026-10-04: `secret unlocker select` and `secret unlocker remove`
|
||||
skip, with the warning `unlocker list` gives, an unlocker directory
|
||||
whose metadata file cannot be checked for, read or parsed, instead of
|
||||
@@ -177,12 +189,6 @@ Bring the repo into policy compliance in one commit:
|
||||
into place, and removals rename out of the way first, so a version
|
||||
or secret is never half-added and never half-removed. An
|
||||
interrupted command can still leave:
|
||||
- a broken unlocker, when it was replacing one: an unlocker added
|
||||
under the directory name of an existing one is rewritten file by
|
||||
file. That happens to a passphrase unlocker added to a vault that
|
||||
has one, and to a PGP, keychain or Secure Enclave unlocker added
|
||||
on the same host and day as another of its type
|
||||
(https://git.eeqj.de/sneak/secret/issues/71);
|
||||
- from `init` or `vault create` killed after the passphrase prompt
|
||||
but before the unlocker is written, a vault with no unlocker,
|
||||
which `vault create` has already made the current vault;
|
||||
|
||||
Reference in New Issue
Block a user