Check that inventory guests, host keys and identities name one set of machines #48

Merged
vnprc merged 2 commits from agent/inventory-machine-sets into master 2026-10-21 23:07:19 +01:00
Member

Nothing changes on any running machine: this adds one check to the secrets gate and edits no data, lib output or deployed file. The check refuses a secrets tree whose machines disagree with the inventory: a guest with no entry in machine-host-keys.json, an entry for a machine the inventory does not declare or for the primary hypervisor, a guest with no identity in identity.nix, an identity for no guest, an identity filed under another machine type's attrset, or one name in two attrsets. Each refusal names the file to edit. Before this, the gate passed with a guest deleted from the host-key file and with an entry for a machine that does not exist, measured on this branch's parent; after it, both are refused by name. Proof is the gate on this branch (11 steps, 10 checks built) plus six sabotaged copies of the template's own data, each refused with the expected message, and two mutations of the check that its fixtures catch. If it is wrong, revert the one commit; nothing deployed depends on it. If a fork's legal layout trips it, the message says which name and which file, and the fork's fix is a data edit, not a framework change.

Closes allod/secrets#43

What the issue got right and what it did not

The gap the issue describes is real in this repository and was measured: deleting bitcoin-node from machine-host-keys.json together with its ciphertext left all 10 existing steps green, and so did adding an entry for a machine named ghost. Two claims in the issue are narrower than written. allod/archetypes already asserts identity keys equal machine keys at composition, so the identity half is caught today, only late and in the wrong repository; and mkVmFacts in archetypes throws on a guest with no host-key entry, but only when something forces vmFacts, which the deploy gate does not, so that failure surfaces at provision-vm on the hypervisor. This check moves both refusals to the repository that owns the files and names them.

Risk

R1. A check with no effect on any derivation a machine builds; flake.nix, lib outputs and every data file are untouched. Worst credible failure after validation: a fork with a legal machine layout the fixtures did not anticipate is refused and its gate goes red until a data edit, which the message names. Rollback is a revert of one commit.

Validation

  • allod check on the branch: All 11 steps passed (checks: 10 built).
  • Six sabotaged copies of the template's data, each run against the new check alone, each refused with its own message: guest with no host-key entry; orphan host-key entry; primary hypervisor in machine-host-keys.json; guest with no identity; identity under the wrong attrset; identity for no machine.
  • Two mutations of the check (the host-key rule and the wrong-set rule each disabled) fail on their fixture assertions, so the fixtures are load-bearing.
  • Fixtures name no real machine (testing.md); the fleet can change without touching them.
  • Not run: the private fork's gate, which this repository cannot see; the check reaches it only when the fork takes this file.
Nothing changes on any running machine: this adds one check to the secrets gate and edits no data, lib output or deployed file. The check refuses a secrets tree whose machines disagree with the inventory: a guest with no entry in `machine-host-keys.json`, an entry for a machine the inventory does not declare or for the primary hypervisor, a guest with no identity in `identity.nix`, an identity for no guest, an identity filed under another machine type's attrset, or one name in two attrsets. Each refusal names the file to edit. Before this, the gate passed with a guest deleted from the host-key file and with an entry for a machine that does not exist, measured on this branch's parent; after it, both are refused by name. Proof is the gate on this branch (11 steps, 10 checks built) plus six sabotaged copies of the template's own data, each refused with the expected message, and two mutations of the check that its fixtures catch. If it is wrong, revert the one commit; nothing deployed depends on it. If a fork's legal layout trips it, the message says which name and which file, and the fork's fix is a data edit, not a framework change. Closes allod/secrets#43 ## What the issue got right and what it did not The gap the issue describes is real in this repository and was measured: deleting `bitcoin-node` from `machine-host-keys.json` together with its ciphertext left all 10 existing steps green, and so did adding an entry for a machine named `ghost`. Two claims in the issue are narrower than written. `allod/archetypes` already asserts identity keys equal machine keys at composition, so the identity half is caught today, only late and in the wrong repository; and `mkVmFacts` in archetypes throws on a guest with no host-key entry, but only when something forces `vmFacts`, which the deploy gate does not, so that failure surfaces at `provision-vm` on the hypervisor. This check moves both refusals to the repository that owns the files and names them. ## Risk R1. A check with no effect on any derivation a machine builds; `flake.nix`, `lib` outputs and every data file are untouched. Worst credible failure after validation: a fork with a legal machine layout the fixtures did not anticipate is refused and its gate goes red until a data edit, which the message names. Rollback is a revert of one commit. ## Validation - `allod check` on the branch: `All 11 steps passed (checks: 10 built)`. - Six sabotaged copies of the template's data, each run against the new check alone, each refused with its own message: guest with no host-key entry; orphan host-key entry; primary hypervisor in `machine-host-keys.json`; guest with no identity; identity under the wrong attrset; identity for no machine. - Two mutations of the check (the host-key rule and the wrong-set rule each disabled) fail on their fixture assertions, so the fixtures are load-bearing. - Fixtures name no real machine (`testing.md`); the fleet can change without touching them. - Not run: the private fork's gate, which this repository cannot see; the check reaches it only when the fork takes this file.
A new check, machine-coverage, reads the consumed inventory's machines
beside machine-host-keys.json and identity.nix and refuses a guest with
no host-key entry, an entry naming no machine or the primary hypervisor,
a guest with no identity, an identity naming no guest, an identity under
another type's attrset, and one name in two attrsets. Each message names
the file to edit. Measured before the change: the gate passed with
bitcoin-node deleted from machine-host-keys.json together with its
ciphertext, and with an entry for a machine the inventory never
declares. Every refusal has a sabotage fixture; no real machine is named.

Refs allod/secrets#43
vnprc approved these changes 2026-10-21 23:07:14 +01:00
vnprc merged commit 7d2d7671be into master 2026-10-21 23:07:19 +01:00
vnprc deleted branch agent/inventory-machine-sets 2026-10-21 23:07:19 +01:00
Sign in to join this conversation.
No reviewers
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/secrets!48
No description provided.