Declare the host user's credential files from the hypervisor identity, as mkDevVm does #74

Closed
opened 2026-09-10 15:12:45 +01:00 by vnprc-agent · 0 comments

Place the host user's forge token and site hosting rclone config from nexusIdentity fields, null meaning absent, the way mkDevVm already places dev-machine tokens, so a fork gets allod site deploy with a supported credential path and no deployment-private module. Part of allod/strategy#51.

Primary goals:

  • One module, two secrets, driven by identity — mkHypervisor (flake.nix:413-470) imports a modules/host-user-credentials.nix beside ./modules/netrc.nix (:436) that declares age.secrets.user-forgejo-token at /home/<user>/.config/git/forgejo-token and age.secrets.site-hosting-rclone at /home/<user>/.config/rclone/rclone.conf, each owner <user>, group users, mode 0600, symlink, and only when its identity field is non-null.
  • Null is absent, not broken — with both fields null the generated age.secrets contains neither entry and no agenix activation runs for them, which is the template's state and what dev-forge-opt-out asserts for dev machines (flake.nix:1191-1204, :1273-1277).
  • Read with or null — identity.siteHostingConfigFile or null, so this evaluates against a secrets pin that predates allod/secrets#17 and lands in either order.
  • A check that can fail — modelled on dev-forge-opt-out: the null branch asserts an empty projection; a fixture path asserts the exact file, path, owner, group and mode; the string-spelling guard follows whatever contract the dev-VM path-form check settles on (:1281-1286, allod/archetypes#70).

Current state and specifics

The hypervisor's specialArgs already carry identity (flake.nix:423-428), so a module taking { identity, ... } needs no new plumbing. modules/agent-forgejo-token.nix is the dev-machine precedent for a single token file placed in the user's home; modules/github-credentials.nix:50 for a list of them.

Facts the module's header comment should state, read from agenix's installSecret at the pinned revision: it runs mkdir -p on the custom path's parent as root, so on a fresh host ~/.config/rclone and ~/.config/git come into being root-owned, which nothing needs to write into; it installs the path with ln -sfT, so a hand-written regular file there is replaced in place by the symlink; cleanup removes only the previous generation directory, so removing a declaration later leaves the symlink dangling for the operator to delete. rclone's default config path is exactly the second path, which is why allod site deploy, check and config show need no --config, and allod site config update and replace refuse a symlink by design, so a rotation is a secrets change plus a rebuild.

Validation: the check above in both branches; nix eval of the template hypervisor's config.age.secrets shows neither entry; a fleet-diff --expect nexus against a deployment that supplies both fields changes the host and nothing else, save machines that rebuild on any secrets commit (allod/archetypes#21).

Scope

In: the module, its import in mkHypervisor, the check, and the README line under the hypervisor section.

Out: the identity fields themselves (allod/secrets#17, lands first), the deploy command's documentation (allod/nexus#44), and deleting a deployment's own module after its pin advance, which is that deployment's step.

Place the host user's forge token and site hosting rclone config from `nexusIdentity` fields, null meaning absent, the way `mkDevVm` already places dev-machine tokens, so a fork gets `allod site deploy` with a supported credential path and no deployment-private module. Part of allod/strategy#51. Primary goals: - **One module, two secrets, driven by identity** — `mkHypervisor` (`flake.nix:413-470`) imports a `modules/host-user-credentials.nix` beside `./modules/netrc.nix` (`:436`) that declares `age.secrets.user-forgejo-token` at `/home/<user>/.config/git/forgejo-token` and `age.secrets.site-hosting-rclone` at `/home/<user>/.config/rclone/rclone.conf`, each owner `<user>`, group `users`, mode `0600`, symlink, and only when its identity field is non-null. - **Null is absent, not broken** — with both fields null the generated `age.secrets` contains neither entry and no agenix activation runs for them, which is the template's state and what `dev-forge-opt-out` asserts for dev machines (`flake.nix:1191-1204`, `:1273-1277`). - **Read with `or null`** — `identity.siteHostingConfigFile or null`, so this evaluates against a secrets pin that predates allod/secrets#17 and lands in either order. - **A check that can fail** — modelled on `dev-forge-opt-out`: the null branch asserts an empty projection; a fixture path asserts the exact file, path, owner, group and mode; the string-spelling guard follows whatever contract the dev-VM path-form check settles on (`:1281-1286`, allod/archetypes#70). ### Current state and specifics The hypervisor's `specialArgs` already carry `identity` (`flake.nix:423-428`), so a module taking `{ identity, ... }` needs no new plumbing. `modules/agent-forgejo-token.nix` is the dev-machine precedent for a single token file placed in the user's home; `modules/github-credentials.nix:50` for a list of them. Facts the module's header comment should state, read from agenix's `installSecret` at the pinned revision: it runs `mkdir -p` on the custom path's parent as root, so on a fresh host `~/.config/rclone` and `~/.config/git` come into being root-owned, which nothing needs to write into; it installs the path with `ln -sfT`, so a hand-written regular file there is replaced in place by the symlink; cleanup removes only the previous generation directory, so removing a declaration later leaves the symlink dangling for the operator to delete. rclone's default config path is exactly the second path, which is why `allod site deploy`, `check` and `config show` need no `--config`, and `allod site config update` and `replace` refuse a symlink by design, so a rotation is a secrets change plus a rebuild. Validation: the check above in both branches; `nix eval` of the template hypervisor's `config.age.secrets` shows neither entry; a `fleet-diff --expect nexus` against a deployment that supplies both fields changes the host and nothing else, save machines that rebuild on any secrets commit (allod/archetypes#21). ### Scope In: the module, its import in `mkHypervisor`, the check, and the README line under the hypervisor section. Out: the identity fields themselves (allod/secrets#17, lands first), the deploy command's documentation (allod/nexus#44), and deleting a deployment's own module after its pin advance, which is that deployment's step.
vnprc closed this issue 2026-09-10 16:44:43 +01:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
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/archetypes#74
No description provided.