allod secret declare hardcodes the hostKey recipient binding #271

Closed
opened 2026-10-06 15:52:52 +01:00 by vnprc-agent · 1 comment
Contributor

allod secret declare writes a secrets.nix recipient line that only evaluates in a checkout defining hostKey; it should take the host recipient name from the checkout it edits instead of hardcoding it.

Primary goals:

  • Generated line evaluates in any fork — the recipient expression declare appends uses whatever binding the target secrets.nix already uses for the hypervisor's keys, so a fork that names it differently gets a line nix flake check accepts.
  • Refuse rather than guess — when secrets.nix has no recognisable host-recipient binding, declare refuses with the file and the names it looked for, instead of writing a line that fails evaluation at create time.

Current state and specifics

cmd/allod/secret_declare.go declareSecretsRecipients writes the literal [ hostKey ] (b.WriteString("[ hostKey ]")) followed by ++ vmKeys "<vm>" per guest target. The public template's secrets.nix binds hostKey = identity.hostPublicKey;, so the line evaluates there. A fork that derives the hypervisor recipient set differently — for example a list holding the active and a staged host key under another name, with no hostKey binding at all — gets a line that fails evaluation with undefined variable 'hostKey'. declare itself succeeds and prints the three paths, so the failure surfaces only when the operator runs allod secret create on the host, which runs the repository's checks after writing the ciphertext and then restores the files.

The other two pieces declare writes are already derived from the checkout (machines.<name>.type from the inventory flake, lib.credentialEncodings from the secrets flake), so the recipient binding is the one hardcoded name left.

Scope

In: declareSecretsRecipients reads the recipient binding name from the target secrets.nix (the name bound to the hypervisor keys, which the existing lines in that file already use), and refuses when none is found. Out: changing the public template's binding name; any change to create, rekey or rotate.

`allod secret declare` writes a `secrets.nix` recipient line that only evaluates in a checkout defining `hostKey`; it should take the host recipient name from the checkout it edits instead of hardcoding it. Primary goals: - **Generated line evaluates in any fork** — the recipient expression `declare` appends uses whatever binding the target `secrets.nix` already uses for the hypervisor's keys, so a fork that names it differently gets a line `nix flake check` accepts. - **Refuse rather than guess** — when `secrets.nix` has no recognisable host-recipient binding, `declare` refuses with the file and the names it looked for, instead of writing a line that fails evaluation at `create` time. ### Current state and specifics `cmd/allod/secret_declare.go` `declareSecretsRecipients` writes the literal `[ hostKey ]` (`b.WriteString("[ hostKey ]")`) followed by `++ vmKeys "<vm>"` per guest target. The public template's `secrets.nix` binds `hostKey = identity.hostPublicKey;`, so the line evaluates there. A fork that derives the hypervisor recipient set differently — for example a list holding the active and a staged host key under another name, with no `hostKey` binding at all — gets a line that fails evaluation with `undefined variable 'hostKey'`. `declare` itself succeeds and prints the three paths, so the failure surfaces only when the operator runs `allod secret create` on the host, which runs the repository's checks after writing the ciphertext and then restores the files. The other two pieces `declare` writes are already derived from the checkout (`machines.<name>.type` from the inventory flake, `lib.credentialEncodings` from the secrets flake), so the recipient binding is the one hardcoded name left. ### Scope In: `declareSecretsRecipients` reads the recipient binding name from the target `secrets.nix` (the name bound to the hypervisor keys, which the existing lines in that file already use), and refuses when none is found. Out: changing the public template's binding name; any change to `create`, `rekey` or `rotate`.
Member

Closed in favour of allod/secrets#46, by the owner's decision. Reading the fork's binding name out of secrets.nix (allod/tools#275, closed unmerged) fixes the symptom and keeps the cause: declare hand-writes a recipient line into a data file whose naming a fork owns. allod/secrets#46 derives those recipients from the rotation registry inside the secrets repo, after which declare writes no secrets.nix line at all; the tools half is filed as its own issue when that lands, and each deployment fork adopts the derivation in its own repo first.

Closed in favour of allod/secrets#46, by the owner's decision. Reading the fork's binding name out of secrets.nix (allod/tools#275, closed unmerged) fixes the symptom and keeps the cause: declare hand-writes a recipient line into a data file whose naming a fork owns. allod/secrets#46 derives those recipients from the rotation registry inside the secrets repo, after which declare writes no secrets.nix line at all; the tools half is filed as its own issue when that lands, and each deployment fork adopts the derivation in its own repo first.
Sign in to join this conversation.
No milestone
No project
No assignees
2 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
allod/tools#271
No description provided.