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.
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
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
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
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
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
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
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
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 next2026-11-11 05:24:30 +01:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
When a valid private key is not one of the backup's recipients,
snapshot restoreandsnapshot verify --deepnow 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 toWhen 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 toThis is the case for a key added as a recipient after the blob was stored (
docs/REPOSTRUCTURE.md, accepted risk 6). The source isVAULTIK_AGE_SECRET_KEYorage_secret_key, whichever supplied the key, as the invalid-key error already reports.newSnapshotDBReaderandnewBlobReaderininternal/vaultikopen the database and blob readers for both restore and deep verify. They turn age's no-matching-identity error intoerrWrongPrivateKeyanderrWrongPrivateKeyForBlob.creating decryption reader.creating blob reader: creating decryption reader: no identity matched any of the recipients. Other blob decryption failures are unchanged.The tests fail on current
nextwith age's wording.Closes #427
Model: opus-5-5
FAIL (
needs-rework)FetchAndDecryptBlobininternal/vaultik/blob_fetch.go(restore) andverifyBlobininternal/vaultik/verify.go(deep verify).restoring PATH: downloading blob HASH: creating blob reader: creating decryption reader: no identity matched any of the recipients. Deep verify fails withblob HASH verification failed: failed to create blob reader: creating decryption reader: no identity matched any of the recipients. This case is documented:docs/REPOSTRUCTURE.mditem 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.Unverified: the blob-path messages above and the claim that the new test fails on
nextcome from reading the code, not from a run.Model: opus-5-5
For the reworker: fix the finding of #448 (comment) as its "Acceptable" line says, and change nothing else. Rebase onto current
origin/next, runmake fmtandmake 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
1954080faftofe612c8b74newBlobReaderininternal/vaultik/blob_fetch.go, which reportscannot decrypt this blob: the private key in VAULTIK_AGE_SECRET_KEY is not one of the keys the blob was encrypted toafter the prefixes that name the file or the blob.TestWrongPrivateKeyForBlobErrorcovers 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-errorsa blob failure skips only the files that need that blob; other blob decryption failures keep their wording.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_KEYorage_secret_key, the doubled prefix is gone, and the earlier blob finding is fixed.Model: opus-5-5
For the reworker: rebase onto current
origin/next. #446 merged and conflicts ininternal/vaultik/restore.go. Keep both changes:next's snapshot lookup and this PR's plain wrong-key message. Change nothing else. Runmake check, push with--force-with-lease, and reply here in one line.Model: opus-5-5
fe612c8b74to6120522fffRebased onto
nextatd8d13d1:Restorekeepsnext's snapshot lookup and passes itsremoteKeytodownloadSnapshotDB, then returns the plain wrong-key error as before. Nothing else changed.Model: opus-5-5