Parse the age identity key once and accept every identity in it #196

Merged
clawbot merged 1 commits from issue-165-parse-age-key-once into next 2026-09-22 15:45:28 +02:00
Collaborator

Closes #165.

Restore and snapshot verify --deep parsed the age secret key in several places with different rules, kept only the first identity of a multi-identity file, and the docs/help/error showed the key typed literally into the shell.

A new internal/vaultik helper (restoreIdentities) parses Config.AgeSecretKey once with age.ParseIdentities and hands every identity to age.Decrypt (via blobgen.NewReader, now variadic). It is the first step of both commands, so a missing or unparseable key fails before anything is downloaded. Its error names the source (VAULTIK_AGE_SECRET_KEY or age_secret_key) and never echoes the key value.

config.extractAgeSecretKey and its silent fallback are removed; the key is stored raw (source recorded for the error message) and parsed only where decryption happens, so backup, list and prune are unaffected.

README, restore help, and the missing-key error now read the key from a file — VAULTIK_AGE_SECRET_KEY="$(cat vaultik_backup_private_key.txt)" — and state the variable may hold the whole key file.

Tests: a two-identity file where only the second recipient matches decrypts; a trailing-newline value parses and decrypts; a malformed key errors before any store access with an error that does not contain the input; the restore command exposes no key flag and its help shows no literal key.

Reviewer note: I did not add a TODO.md Completed Steps entry — the recent merged issue PRs (#151, #156, #169, #170, #159) did not touch TODO.md, so I followed that established practice to avoid conflicts with concurrent workers.

Model: opus-4-8

Closes https://git.eeqj.de/sneak/vaultik/issues/165. Restore and `snapshot verify --deep` parsed the age secret key in several places with different rules, kept only the first identity of a multi-identity file, and the docs/help/error showed the key typed literally into the shell. A new `internal/vaultik` helper (`restoreIdentities`) parses `Config.AgeSecretKey` once with `age.ParseIdentities` and hands every identity to `age.Decrypt` (via `blobgen.NewReader`, now variadic). It is the first step of both commands, so a missing or unparseable key fails before anything is downloaded. Its error names the source (`VAULTIK_AGE_SECRET_KEY` or `age_secret_key`) and never echoes the key value. `config.extractAgeSecretKey` and its silent fallback are removed; the key is stored raw (source recorded for the error message) and parsed only where decryption happens, so backup, list and prune are unaffected. README, restore help, and the missing-key error now read the key from a file — `VAULTIK_AGE_SECRET_KEY="$(cat vaultik_backup_private_key.txt)"` — and state the variable may hold the whole key file. Tests: a two-identity file where only the second recipient matches decrypts; a trailing-newline value parses and decrypts; a malformed key errors before any store access with an error that does not contain the input; the restore command exposes no key flag and its help shows no literal key. Reviewer note: I did not add a `TODO.md` Completed Steps entry — the recent merged issue PRs (#151, #156, #169, #170, #159) did not touch `TODO.md`, so I followed that established practice to avoid conflicts with concurrent workers. Model: opus-4-8
clawbot added 1 commit 2026-09-22 15:24:26 +02:00
Restore and verify --deep now parse the configured age secret key a
single time through a new internal helper that uses age.ParseIdentities
and hands every identity to age.Decrypt. A key file with several
identities (a whole age-keygen file) is fully accepted, so a blob
encrypted to any of its recipients decrypts, not just the first.

The helper is the first step of both commands, so a missing or
unparseable key now fails before anything is downloaded. Its error names
the configuration source (VAULTIK_AGE_SECRET_KEY or age_secret_key) and
never echoes the key value. config.extractAgeSecretKey and its silent
fallback are removed; the key is stored raw and parsed only where
decryption happens, so backup, list and prune are unaffected.

README, the restore help, and the missing-key error now show the key
read from a file with $(cat ...) rather than typed literally, keeping it
out of shell history, and say the variable may hold the whole key file.

Model: opus-4-8
clawbot added the needs-review label 2026-09-22 15:24:35 +02:00
clawbot self-assigned this 2026-09-22 15:24:35 +02:00
Author
Collaborator

PASS

Model: opus-4-8

PASS Model: opus-4-8
clawbot merged commit d88ed64489 into next 2026-09-22 15:45:28 +02:00
clawbot deleted branch issue-165-parse-age-key-once 2026-09-22 15:45:28 +02:00
Sign in to join this conversation.