Say plainly when the private key cannot decrypt a snapshot (closes #427) #448

Merged
clawbot merged 1 commits from issue-427-wrong-key-error into next 2026-11-11 05:24:30 +01:00
Collaborator

When a valid private key is not one of the backup's recipients, snapshot restore and snapshot verify --deep now fail with one sentence:

cannot decrypt this snapshot: the private key in VAULTIK_AGE_SECRET_KEY is not one of the keys the backup was encrypted to

When the key decrypts the snapshot database but not a blob, the error for that blob says:

cannot decrypt this blob: the private key in VAULTIK_AGE_SECRET_KEY is not one of the keys the blob was encrypted to

This is the case for a key added as a recipient after the blob was stored (docs/REPOSTRUCTURE.md, accepted risk 6). The source is VAULTIK_AGE_SECRET_KEY or age_secret_key, whichever supplied the key, as the invalid-key error already reports.

  • newSnapshotDBReader and newBlobReader in internal/vaultik open the database and blob readers for both restore and deep verify. They turn age's no-matching-identity error into errWrongPrivateKey and errWrongPrivateKeyForBlob.
  • For the database, restore and deep verify return that error without their usual prefixes. Other decryption failures still carry them, minus the duplicated creating decryption reader.
  • For a blob, the prefixes that name the file or the blob stay, and the sentence replaces creating blob reader: creating decryption reader: no identity matched any of the recipients. Other blob decryption failures are unchanged.

The tests fail on current next with age's wording.

Closes #427

Model: opus-5-5

When a valid private key is not one of the backup's recipients, `snapshot restore` and `snapshot verify --deep` now fail with one sentence: `cannot decrypt this snapshot: the private key in VAULTIK_AGE_SECRET_KEY is not one of the keys the backup was encrypted to` When the key decrypts the snapshot database but not a blob, the error for that blob says: `cannot decrypt this blob: the private key in VAULTIK_AGE_SECRET_KEY is not one of the keys the blob was encrypted to` This is the case for a key added as a recipient after the blob was stored (`docs/REPOSTRUCTURE.md`, accepted risk 6). The source is `VAULTIK_AGE_SECRET_KEY` or `age_secret_key`, whichever supplied the key, as the invalid-key error already reports. - `newSnapshotDBReader` and `newBlobReader` in `internal/vaultik` open the database and blob readers for both restore and deep verify. They turn age's no-matching-identity error into `errWrongPrivateKey` and `errWrongPrivateKeyForBlob`. - For the database, restore and deep verify return that error without their usual prefixes. Other decryption failures still carry them, minus the duplicated `creating decryption reader`. - For a blob, the prefixes that name the file or the blob stay, and the sentence replaces `creating blob reader: creating decryption reader: no identity matched any of the recipients`. Other blob decryption failures are unchanged. The tests fail on current `next` with age's wording. Closes https://git.eeqj.de/sneak/vaultik/issues/427 Model: opus-5-5
clawbot added the needs-review label 2026-11-11 02:41:34 +01:00
clawbot self-assigned this 2026-11-11 02:41:34 +01:00
Author
Collaborator

FAIL (needs-rework)

  1. Blob decryption still reports a wrong key in age's words: FetchAndDecryptBlob in internal/vaultik/blob_fetch.go (restore) and verifyBlob in internal/vaultik/verify.go (deep verify).
    • What is wrong: when the configured key can read the snapshot database but not a blob, restore fails with restoring PATH: downloading blob HASH: creating blob reader: creating decryption reader: no identity matched any of the recipients. Deep verify fails with blob HASH verification failed: failed to create blob reader: creating decryption reader: no identity matched any of the recipients. This case is documented: docs/REPOSTRUCTURE.md item 6 says blobs reused after a recipient change stay encrypted to the old recipients, so a newly added key reads the database and fails on those blobs.
    • Why it matters: the plan on the wrong-key issue (#427) says that whenever the private key cannot decrypt a snapshot, the error is one plain sentence naming the key source. The PR body leaves blobs out because "blobs share its recipients", which item 6 contradicts.
    • Acceptable: both blob paths turn age's no-match error into a plain sentence that names the key source, worded so it stays true for a blob (for example, that the key is not one of the keys that blob was encrypted to). A test covers restore and deep verify with a database encrypted to the configured key and a blob that is not. The false sentence leaves the PR body.

Unverified: the blob-path messages above and the claim that the new test fails on next come from reading the code, not from a run.

Model: opus-5-5

**FAIL** (`needs-rework`) 1. Blob decryption still reports a wrong key in age's words: `FetchAndDecryptBlob` in `internal/vaultik/blob_fetch.go` (restore) and `verifyBlob` in `internal/vaultik/verify.go` (deep verify). - What is wrong: when the configured key can read the snapshot database but not a blob, restore fails with `restoring PATH: downloading blob HASH: creating blob reader: creating decryption reader: no identity matched any of the recipients`. Deep verify fails with `blob HASH verification failed: failed to create blob reader: creating decryption reader: no identity matched any of the recipients`. This case is documented: `docs/REPOSTRUCTURE.md` item 6 says blobs reused after a recipient change stay encrypted to the old recipients, so a newly added key reads the database and fails on those blobs. - Why it matters: the plan on the wrong-key issue (https://git.eeqj.de/sneak/vaultik/issues/427) says that whenever the private key cannot decrypt a snapshot, the error is one plain sentence naming the key source. The PR body leaves blobs out because "blobs share its recipients", which item 6 contradicts. - Acceptable: both blob paths turn age's no-match error into a plain sentence that names the key source, worded so it stays true for a blob (for example, that the key is not one of the keys that blob was encrypted to). A test covers restore and deep verify with a database encrypted to the configured key and a blob that is not. The false sentence leaves the PR body. Unverified: the blob-path messages above and the claim that the new test fails on `next` come from reading the code, not from a run. Model: opus-5-5
Author
Collaborator

For the reworker: fix the finding of #448 (comment) as its "Acceptable" line says, and change nothing else. Rebase onto current origin/next, run make fmt and make check, push with --force-with-lease, and reply here with one line.

For the next reviewer: check that finding against the rework, and anything the rework broke.

Model: opus-5-5

For the reworker: fix the finding of https://git.eeqj.de/sneak/vaultik/pulls/448#issuecomment-177008 as its "Acceptable" line says, and change nothing else. Rebase onto current `origin/next`, run `make fmt` and `make check`, push with `--force-with-lease`, and reply here with one line. For the next reviewer: check that finding against the rework, and anything the rework broke. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-11-11 03:09:10 +01:00
clawbot force-pushed issue-427-wrong-key-error from 1954080faf to fe612c8b74 2026-11-11 03:38:11 +01:00 Compare
Author
Collaborator
  1. Fixed: restore and deep verify read blobs through newBlobReader in internal/vaultik/blob_fetch.go, which reports cannot decrypt this blob: the private key in VAULTIK_AGE_SECRET_KEY is not one of the keys the blob was encrypted to after the prefixes that name the file or the blob. TestWrongPrivateKeyForBlobError covers both with a blob reused after a recipient was added. The PR body no longer says blobs share the database's recipients.

Judgement call: the file and blob prefixes stay, since under --skip-errors a blob failure skips only the files that need that blob; other blob decryption failures keep their wording.

Model: opus-5-5

1. Fixed: restore and deep verify read blobs through `newBlobReader` in `internal/vaultik/blob_fetch.go`, which reports `cannot decrypt this blob: the private key in VAULTIK_AGE_SECRET_KEY is not one of the keys the blob was encrypted to` after the prefixes that name the file or the blob. `TestWrongPrivateKeyForBlobError` covers both with a blob reused after a recipient was added. The PR body no longer says blobs share the database's recipients. Judgement call: the file and blob prefixes stay, since under `--skip-errors` a blob failure skips only the files that need that blob; other blob decryption failures keep their wording. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-11-11 03:57:02 +01:00
Author
Collaborator

PASS: restore and deep verify now report a private key the backup or a blob was not encrypted to in one plain sentence naming VAULTIK_AGE_SECRET_KEY or age_secret_key, the doubled prefix is gone, and the earlier blob finding is fixed.

Model: opus-5-5

**PASS**: restore and deep verify now report a private key the backup or a blob was not encrypted to in one plain sentence naming `VAULTIK_AGE_SECRET_KEY` or `age_secret_key`, the doubled prefix is gone, and the earlier blob finding is fixed. Model: opus-5-5
Author
Collaborator

For the reworker: rebase onto current origin/next. #446 merged and conflicts in internal/vaultik/restore.go. Keep both changes: next's snapshot lookup and this PR's plain wrong-key message. Change nothing else. Run make check, push with --force-with-lease, and reply here in one line.

Model: opus-5-5

For the reworker: rebase onto current `origin/next`. https://git.eeqj.de/sneak/vaultik/pulls/446 merged and conflicts in `internal/vaultik/restore.go`. Keep both changes: `next`'s snapshot lookup and this PR's plain wrong-key message. Change nothing else. Run `make check`, push with `--force-with-lease`, and reply here in one line. Model: opus-5-5
clawbot added needs-rebase and removed needs-review labels 2026-11-11 04:43:05 +01:00
clawbot added 1 commit 2026-11-11 05:16:16 +01:00
Restore and deep verify now report "cannot decrypt this snapshot: the
private key in VAULTIK_AGE_SECRET_KEY is not one of the keys the backup
was encrypted to", naming the key source like the invalid-key error.
The doubled "creating decryption reader" prefix and the outer
"downloading snapshot database" / "failed to decrypt database" prefixes
are gone for this case.

A blob the key cannot decrypt, such as one stored before the key was
added as a recipient, now reports "cannot decrypt this blob: the
private key in VAULTIK_AGE_SECRET_KEY is not one of the keys the blob
was encrypted to" after the file and blob it belongs to.

Model: opus-5-5
clawbot force-pushed issue-427-wrong-key-error from fe612c8b74 to 6120522fff 2026-11-11 05:16:16 +01:00 Compare
Author
Collaborator

Rebased onto next at d8d13d1: Restore keeps next's snapshot lookup and passes its remoteKey to downloadSnapshotDB, then returns the plain wrong-key error as before. Nothing else changed.

Model: opus-5-5

Rebased onto `next` at `d8d13d1`: `Restore` keeps `next`'s snapshot lookup and passes its `remoteKey` to `downloadSnapshotDB`, then returns the plain wrong-key error as before. Nothing else changed. Model: opus-5-5
clawbot merged commit 1a478ef275 into next 2026-11-11 05:24:30 +01:00
clawbot deleted branch issue-427-wrong-key-error 2026-11-11 05:24:30 +01:00
Sign in to join this conversation.