Parse age_recipients at config load and never echo the entry #187

Merged
clawbot merged 1 commits from issue-153-parse-age-recipients into next 2026-09-22 13:01:01 +02:00
Collaborator

Fixes #153.

Config.Validate now parses every age_recipients entry with age.ParseX25519Recipient, so a bad recipient fails at config load instead of deep in a backup (after the snapshot row exists and the tree has been walked). On failure the error names the position (age_recipients[N]) and never the value: a recipient string can itself be a secret key an operator pasted by mistake, and age's own error quotes its input. An entry whose text begins with AGE-SECRET-KEY- (compared case-insensitively) gets a distinct message saying a secret key was given where a public key belongs.

The remaining parse sites — blobgen.NewWriter, and crypto's NewEncryptor and UpdateRecipients — are reachable by callers that skip config.Load, so they too drop the value and age's wrapped error and name only the position.

test/config.yaml's placeholder second recipient (age1otherpubkey...) is replaced with a valid X25519 key so the two-recipient test config still loads once recipients are actually parsed.

Tests: recipient validation through Validate for the config init placeholder, an ssh-ed25519 recipient, a truncated age1 string, and a valid two-recipient list; plus no-leak tests asserting a secret key passed to Validate, blobgen.NewWriter, and crypto.NewEncryptor never appears in the returned error.

make check is green.

Model: opus-4-8

Fixes https://git.eeqj.de/sneak/vaultik/issues/153. `Config.Validate` now parses every `age_recipients` entry with `age.ParseX25519Recipient`, so a bad recipient fails at config load instead of deep in a backup (after the snapshot row exists and the tree has been walked). On failure the error names the position (`age_recipients[N]`) and never the value: a recipient string can itself be a secret key an operator pasted by mistake, and age's own error quotes its input. An entry whose text begins with `AGE-SECRET-KEY-` (compared case-insensitively) gets a distinct message saying a secret key was given where a public key belongs. The remaining parse sites — `blobgen.NewWriter`, and `crypto`'s `NewEncryptor` and `UpdateRecipients` — are reachable by callers that skip `config.Load`, so they too drop the value and age's wrapped error and name only the position. `test/config.yaml`'s placeholder second recipient (`age1otherpubkey...`) is replaced with a valid X25519 key so the two-recipient test config still loads once recipients are actually parsed. Tests: recipient validation through `Validate` for the `config init` placeholder, an `ssh-ed25519` recipient, a truncated `age1` string, and a valid two-recipient list; plus no-leak tests asserting a secret key passed to `Validate`, `blobgen.NewWriter`, and `crypto.NewEncryptor` never appears in the returned error. `make check` is green. Model: opus-4-8
clawbot added 1 commit 2026-09-22 12:42:20 +02:00
Config.Validate now parses every age_recipients entry with
age.ParseX25519Recipient, so a bad recipient fails at config load instead
of deep in a backup after the snapshot row and tree walk. On failure the
error names the position (age_recipients[N]) and never the value: a
recipient string can itself be a secret key an operator pasted by mistake,
and age's own error quotes its input. An entry starting with
AGE-SECRET-KEY- (compared case-insensitively) gets a specific message.

The remaining parse sites (blobgen.NewWriter, crypto NewEncryptor and
UpdateRecipients), reachable by callers that skip config.Load, likewise
drop the value and age's wrapped error, naming only the position.

test/config.yaml's placeholder second recipient is replaced with a valid
X25519 key so it still loads.

Model: opus-4-8
clawbot added the needs-review label 2026-09-22 12:42:28 +02:00
clawbot self-assigned this 2026-09-22 12:42:28 +02:00
Author
Collaborator

PASS

Model: opus-4-8

PASS Model: opus-4-8
clawbot merged commit 3a58377127 into next 2026-09-22 13:01:01 +02:00
clawbot deleted branch issue-153-parse-age-recipients 2026-09-22 13:01:02 +02:00
Sign in to join this conversation.