From d3b3b646d383b164647fe3c7d25ddd3a489544e7 Mon Sep 17 00:00:00 2001 From: Cameron Smith Date: Mon, 31 Aug 2026 23:33:17 -0400 Subject: [PATCH] fix(magnetite): confine the builder account's key to the nix protocol The nix-remote-build key that stibnite holds authorized an unrestricted shell on magnetite's builder account, which is a nix trusted user on a host whose sshd accepts connections from the public internet. Wrap that key with restrict and a forced nix-daemon --stdio command, so it can start only the protocol its single consumer speaks: the ssh-ng buildMachines entry in modules/system/magnetite-builder.nix, which authenticates with the matching private half at config.clan.core.vars.generators.nix-remote-build.files.key.path. The forced command interpolates config.nix.package rather than a bare program name so it resolves to the nix deployed on magnetite, and the account keeps its default bash shell because sshd runs the forced command through it. Drop crs58's personal keys from the same account. They authorize the wheel account fleet-wide through modules/system/admins.nix, where wheel also has passwordless sudo, so sudo -u builder still reaches the account for debugging and no access is lost. The builder entry in nix.settings.trusted-users is deliberately unchanged; removing it depends on per-machine store signing, which is tracked separately. Verified by evaluation, which renders the key list as a single entry carrying restrict, the store path of the deployed nix, and no personal keys. Ran the treefmt, structure-nixos-configurations and deployment-safety checks. No deployment was performed, so the live remote build path is untested. --- modules/machines/nixos/magnetite/default.nix | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/machines/nixos/magnetite/default.nix b/modules/machines/nixos/magnetite/default.nix index 76cbc0b23..f0740f288 100644 --- a/modules/machines/nixos/magnetite/default.nix +++ b/modules/machines/nixos/magnetite/default.nix @@ -396,8 +396,17 @@ in users.users.builder = { isNormalUser = true; description = "Remote nix build user"; - openssh.authorizedKeys.keys = inputs.self.users.crs58.meta.sshKeys ++ [ - inputs.self.darwinConfigurations.stibnite.config.clan.core.vars.generators.nix-remote-build.files."key.pub".value + # nix-daemon --stdio is exactly what an ssh-ng caller would otherwise + # invoke (`remote-program` defaults to nix-daemon), so forcing it serves + # the build protocol and discards anything else the client asks for. + # sshd runs the forced command through the account's login shell, so the + # shell must stay executable; a nologin shell would break the protocol + # rather than harden it. Mirrors the stibnite direction of this pair. + openssh.authorizedKeys.keys = [ + ''restrict,command="${config.nix.package}/bin/nix-daemon --stdio" ${ + lib.removeSuffix "\n" + inputs.self.darwinConfigurations.stibnite.config.clan.core.vars.generators.nix-remote-build.files."key.pub".value + }'' ]; };