Bug: Init command writes longterm.age twice, second write overwrites correct encryption #6

Open
opened 2026-02-08 21:02:11 +01:00 by clawbot · 0 comments

Bug

In internal/cli/init.go, after calling vlt.CreatePassphraseUnlocker(passphraseBuffer), the Init() function redundantly re-reads the unlocker's public key, re-encrypts the long-term private key, and overwrites longterm.age:

// CreatePassphraseUnlocker already wrote longterm.age correctly
passphraseUnlocker, err := vlt.CreatePassphraseUnlocker(passphraseBuffer)

// Then Init does it AGAIN:
unlockerPubKeyData, err := afero.ReadFile(cli.fs, filepath.Join(unlockerDir, "pub.age"))
// ... reads pub key, encrypts lt key, writes longterm.age again

CreatePassphraseUnlocker (in internal/vault/unlockers.go) already correctly:

  1. Generates the unlocker keypair
  2. Encrypts the long-term key to the unlocker
  3. Writes longterm.age

The duplicate code in Init overwrites this with a functionally equivalent but separately encrypted blob. This is:

  • Wasteful: double encryption work
  • A maintenance hazard: if CreatePassphraseUnlocker changes its encryption scheme, Init would overwrite with the old approach
  • Confusing: suggests CreatePassphraseUnlocker doesn't handle this step

Fix

Remove the redundant longterm.age encryption and writing from Init().

## Bug In `internal/cli/init.go`, after calling `vlt.CreatePassphraseUnlocker(passphraseBuffer)`, the `Init()` function redundantly re-reads the unlocker's public key, re-encrypts the long-term private key, and overwrites `longterm.age`: ```go // CreatePassphraseUnlocker already wrote longterm.age correctly passphraseUnlocker, err := vlt.CreatePassphraseUnlocker(passphraseBuffer) // Then Init does it AGAIN: unlockerPubKeyData, err := afero.ReadFile(cli.fs, filepath.Join(unlockerDir, "pub.age")) // ... reads pub key, encrypts lt key, writes longterm.age again ``` `CreatePassphraseUnlocker` (in `internal/vault/unlockers.go`) already correctly: 1. Generates the unlocker keypair 2. Encrypts the long-term key to the unlocker 3. Writes `longterm.age` The duplicate code in `Init` overwrites this with a functionally equivalent but separately encrypted blob. This is: - **Wasteful**: double encryption work - **A maintenance hazard**: if `CreatePassphraseUnlocker` changes its encryption scheme, `Init` would overwrite with the old approach - **Confusing**: suggests `CreatePassphraseUnlocker` doesn't handle this step ## Fix Remove the redundant longterm.age encryption and writing from `Init()`.
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: sneak/secret#6
No description provided.