Scope sshHosts to the machines that should receive them #54
Labels
No labels
blocked
bug
decision
duplicate
enhancement
help wanted
invalid
landed?
question
ready-to-merge
stale
wontfix
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
allod/archetypes#54
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Give a machine only the
sshHostsentries it is meant to reach, instead of the deployment's entire host inventory. Today every machine receives every entry, and the model has no way to say otherwise — which is why one host is already special-cased to work around it.Primary goals:
sshHostsentry can name the machines that receive it, defaulting to all so existing forks are unaffected.identityFileexists only on another machine.Current state and specifics
modules/home-shared.nix:20-24maps the whole ofidentity.sshHostsintoprograms.ssh.matchBlocks, with exactly one host treated differently:That
mkDefaultexists so a fork's per-machine home module can substitute the machine's own forge key. Every other entry is emitted verbatim at normal priority,identityFileincluded — so a machine cannot correct an identity path that does not apply to it, and the one place that needed correcting got a hardcoded exception instead of a mechanism.Two consequences follow. A dev machine receives host blocks for infrastructure it is not meant to touch, including entries the template itself marks as external and operator-facing (
example-backup-vps,example-offsite-console,example-provider-supportin the identity template'ssshHosts). And most of those blocks are inert: they name~/.ssh/host, which by the template's own design is the hypervisor's identity, so on any other machine the alias resolves to a file that is not there. Measured on a deployment, one machine's generated config held fourteen host blocks of which one — the special-cased forge host — could authenticate.The machine name is already in scope at both call sites,
flake.nix:749andflake.nix:1135, so the filter needs no new plumbing.Exposure, not access
This is the same distinction
allod/archetypes#21draws for the secrets directory, and the same conclusion: which host a machine may actually reach is governed by key possession, and that is unaffected and correct. The defect is that the machine is told about hosts it has no business knowing.The honest scale: on a deployment where
allod/archetypes#21is still open, this changes nothing measurable, because the store closure already carries the identity data the config is derived from. A deployment may also place the same facts on a machine through its own document checkouts, which is that deployment's content decision and outside this repo. What the change buys is that the framework stops broadcasting on a channel a deployment cannot opt out of — so the two fixes together make the remaining exposure something an operator chose rather than something the framework imposed. Treat this as least privilege applied structurally, not as a fix for a live leak.The forward-looking half matters more than the current state. Any host added to
sshHostsreaches every machine automatically, whether or not its name is something the fleet should hold.Suggested default
Add an optional field naming the receiving machines, absent meaning all, and filter in the consumer before the
mapAttrs. Applylib.mkDefaulttoidentityFilefor every surviving entry, which makes the current forge-host branch unnecessary and lets any fork correct any host's identity per machine. Existing per-machine overrides setidentityFileat normal priority and continue to win.Preferred over the alternative of having each fork pre-filter its own
sshHostsbefore handing it over: that keeps the consumer simple but pushes the same filtering logic into every fork, and leaves the special case in place.Scope
In scope:
modules/home-shared.nix, the optional field in the identity template'ssshHostswith synthetic entries exercising it, and a check pinning that an out-of-scope host does not reach a machine.Out of scope: the recipient graph; the store-closure carve-out, which is
allod/archetypes#21; and any fork's data. Back-compatible by construction — a fork that names no machines keeps today's behavior.