Give every new unlocker a directory of its own (closes #71)
check / check (push) Failing after 2s
check / check (push) Failing after 2s
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 is contained in:
@@ -25,6 +25,22 @@ 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: `secret unlocker add pgp` works on Linux
|
||||
(https://git.eeqj.de/sneak/secret/issues/88). `CreatePGPUnlocker` gets
|
||||
the vault's long-term key as adding a passphrase unlocker does, with the
|
||||
@@ -59,9 +75,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
|
||||
@@ -157,12 +171,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