From 10cc6cceed085433d8ce06c64e4819b3709fee95 Mon Sep 17 00:00:00 2001 From: Emma Thorpe Date: Mon, 29 Jun 2026 12:27:52 +0100 Subject: [PATCH] refactor(flake): add user registry and multi-user host support Separate user identity (data) from the reusable modules, and let a host declare any number of users instead of exactly one. - users/registry.nix: per-user identity (name, email, groups, authorized and signing keys) as the single source of identity; no user data is hardcoded in the modules. - mkHost takes a `users` set keyed by username; per-user identity is injected into each home config via the `identity` module arg (extraSpecialArgs is per-host, so it cannot carry per-user data). - modules/users.nix builds accounts from the registry; modules/ssh.nix no longer defines authorized keys (the registry owns them); home/git.nix and home/desktop.nix read `identity`; users/emmathorpe/work.nix drops its now-redundant git identity override. - Restructure the tree: users/, home/, modules/, hosts/, lib/ replace the former lyrathorpe/ and system/ layout. - Add standalone homeConfigurations (the portable subset: shell, git, editor, claude) and an exported homeModules output for use on machines not managed by this flake, or as an input to other flakes. Behaviour-preserving for existing hosts: lyrathorpe-mbp and emmathorpe-edaas evaluate to identical derivations; lyrathorpe-t400, lyrathorpe-macpro31 and lyrathorpe-rpi5 differ only by de-duplicating a repeated authorized_keys entry. Fixes the SSH authorized-key leak (one user's key was applied to every account), the hardcoded default git identity, and the hardcoded EDaaS linger setting. --- .gitignore | 2 +- flake.nix | 220 ++++++++++++------ {lyrathorpe/home => home}/KEYBINDINGS.md | 0 {lyrathorpe/home => home}/README.md | 0 {lyrathorpe/home => home}/claude.nix | 0 {lyrathorpe/home => home}/claude/CLAUDE.md | 0 .../home => home}/claude/memory/MEMORY.md | 0 .../claude/memory/dev_clusters_disposable.md | 0 .../claude/memory/docs_keep_updated.md | 0 .../claude/memory/feedback_sandbox_prompts.md | 0 .../claude/memory/git_check_state.md | 0 .../claude/memory/git_commit_signing.md | 0 .../claude/memory/git_conventions.md | 0 .../claude/memory/git_network_ops.md | 0 .../claude/memory/jira_tooling.md | 0 .../claude/memory/persona_soviet_engineer.md | 0 .../home => home}/claude/memory/user_name.md | 0 .../memory/workflow_review_and_comments.md | 0 .../claude/output-styles/soviet-engineer.md | 0 {lyrathorpe/home => home}/default.nix | 0 {lyrathorpe/home => home}/desktop.nix | 9 +- {lyrathorpe/home => home}/editor.nix | 0 {lyrathorpe/home => home}/git.nix | 28 ++- {lyrathorpe/home => home}/shell.nix | 2 +- {lyrathorpe/home => home}/sway.nix | 4 +- .../Darwin/configuration.nix | 2 +- .../machine => hosts}/EDaaS/configuration.nix | 11 +- .../MBP-Asahi/configuration.nix | 0 .../MBP-Asahi/hardware-configuration.nix | 0 {system/machine => hosts}/MacPro31/README.md | 0 .../MacPro31/configuration.nix | 2 +- .../MacPro31/hardware-configuration.nix | 0 {system/machine => hosts}/RPi5/README.md | 0 .../machine => hosts}/RPi5/configuration.nix | 2 +- {system/machine => hosts}/RPi5/docker.nix | 0 .../RPi5/hardware-configuration.nix | 0 .../machine => hosts}/RPi5/reverse-proxy.nix | 0 {system/machine => hosts}/T400/README.md | 0 {system/machine => hosts}/T400/boot-bios.nix | 0 .../T400/boot-coreboot-grub.nix | 0 .../T400/boot-coreboot-uefi.nix | 0 .../machine => hosts}/T400/configuration.nix | 0 .../T400/hardware-configuration.nix | 0 {lyrathorpe => lib}/catppuccin-mocha.nix | 2 +- lyrathorpe/user.nix | 31 --- {system/modules => modules}/common-nixos.nix | 0 {system/modules => modules}/desktop.nix | 2 +- {system/modules => modules}/features.nix | 4 +- .../firmware/all_firmware.tar.gz | Bin .../firmware/kernelcache.release.mac14j | Bin {system/modules => modules}/laptop.nix | 2 +- modules/ssh.nix | 14 ++ lyrathorpe/swaywm.nix => modules/sway.nix | 4 +- modules/users.nix | 44 ++++ {system/modules => modules}/workstation.nix | 0 system/modules/ssh.nix | 19 -- .../emmathorpe}/renovate-review.nix | 0 .../home => users/emmathorpe}/work.nix | 17 +- users/registry.nix | 40 ++++ 59 files changed, 286 insertions(+), 175 deletions(-) rename {lyrathorpe/home => home}/KEYBINDINGS.md (100%) rename {lyrathorpe/home => home}/README.md (100%) rename {lyrathorpe/home => home}/claude.nix (100%) rename {lyrathorpe/home => home}/claude/CLAUDE.md (100%) rename {lyrathorpe/home => home}/claude/memory/MEMORY.md (100%) rename {lyrathorpe/home => home}/claude/memory/dev_clusters_disposable.md (100%) rename {lyrathorpe/home => home}/claude/memory/docs_keep_updated.md (100%) rename {lyrathorpe/home => home}/claude/memory/feedback_sandbox_prompts.md (100%) rename {lyrathorpe/home => home}/claude/memory/git_check_state.md (100%) rename {lyrathorpe/home => home}/claude/memory/git_commit_signing.md (100%) rename {lyrathorpe/home => home}/claude/memory/git_conventions.md (100%) rename {lyrathorpe/home => home}/claude/memory/git_network_ops.md (100%) rename {lyrathorpe/home => home}/claude/memory/jira_tooling.md (100%) rename {lyrathorpe/home => home}/claude/memory/persona_soviet_engineer.md (100%) rename {lyrathorpe/home => home}/claude/memory/user_name.md (100%) rename {lyrathorpe/home => home}/claude/memory/workflow_review_and_comments.md (100%) rename {lyrathorpe/home => home}/claude/output-styles/soviet-engineer.md (100%) rename {lyrathorpe/home => home}/default.nix (100%) rename {lyrathorpe/home => home}/desktop.nix (94%) rename {lyrathorpe/home => home}/editor.nix (100%) rename {lyrathorpe/home => home}/git.nix (77%) rename {lyrathorpe/home => home}/shell.nix (99%) rename {lyrathorpe/home => home}/sway.nix (99%) rename {system/machine => hosts}/Darwin/configuration.nix (98%) rename {system/machine => hosts}/EDaaS/configuration.nix (88%) rename {system/machine => hosts}/MBP-Asahi/configuration.nix (100%) rename {system/machine => hosts}/MBP-Asahi/hardware-configuration.nix (100%) rename {system/machine => hosts}/MacPro31/README.md (100%) rename {system/machine => hosts}/MacPro31/configuration.nix (96%) rename {system/machine => hosts}/MacPro31/hardware-configuration.nix (100%) rename {system/machine => hosts}/RPi5/README.md (100%) rename {system/machine => hosts}/RPi5/configuration.nix (98%) rename {system/machine => hosts}/RPi5/docker.nix (100%) rename {system/machine => hosts}/RPi5/hardware-configuration.nix (100%) rename {system/machine => hosts}/RPi5/reverse-proxy.nix (100%) rename {system/machine => hosts}/T400/README.md (100%) rename {system/machine => hosts}/T400/boot-bios.nix (100%) rename {system/machine => hosts}/T400/boot-coreboot-grub.nix (100%) rename {system/machine => hosts}/T400/boot-coreboot-uefi.nix (100%) rename {system/machine => hosts}/T400/configuration.nix (100%) rename {system/machine => hosts}/T400/hardware-configuration.nix (100%) rename {lyrathorpe => lib}/catppuccin-mocha.nix (87%) delete mode 100644 lyrathorpe/user.nix rename {system/modules => modules}/common-nixos.nix (100%) rename {system/modules => modules}/desktop.nix (91%) rename {system/modules => modules}/features.nix (75%) rename {system/modules => modules}/firmware/all_firmware.tar.gz (100%) rename {system/modules => modules}/firmware/kernelcache.release.mac14j (100%) rename {system/modules => modules}/laptop.nix (94%) create mode 100644 modules/ssh.nix rename lyrathorpe/swaywm.nix => modules/sway.nix (97%) create mode 100644 modules/users.nix rename {system/modules => modules}/workstation.nix (100%) delete mode 100644 system/modules/ssh.nix rename {lyrathorpe/home => users/emmathorpe}/renovate-review.nix (100%) rename {lyrathorpe/home => users/emmathorpe}/work.nix (80%) create mode 100644 users/registry.nix diff --git a/.gitignore b/.gitignore index 73c4e0f..596783b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -system/modules/firmware/* +modules/firmware/* # vim swap files *.swp diff --git a/flake.nix b/flake.nix index 3f8f634..24f299b 100644 --- a/flake.nix +++ b/flake.nix @@ -23,7 +23,7 @@ # Provides mkFlake: the systems/perSystem scaffolding used below. flake-parts.url = "github:hercules-ci/flake-parts"; flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; - # Declarative Firefox add-ons (e.g. the Catppuccin theme); see lyrathorpe/user.nix. + # Declarative Firefox add-ons (e.g. the Catppuccin theme); see modules/users.nix. firefox-addons = { url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons"; inputs.nixpkgs.follows = "nixpkgs"; @@ -46,7 +46,7 @@ url = "github:cachix/git-hooks.nix"; inputs.nixpkgs.follows = "nixpkgs"; }; - # Declarative Neovim (the editor; see lyrathorpe/home/editor.nix). Release + # Declarative Neovim (the editor; see home/editor.nix). Release # branch matched to the pinned nixpkgs (26.05); follows our nixpkgs to keep a # single nixpkgs in the closure. editor.nix sets programs.nixvim.nixpkgs.source # to this same input so the home module doesn't warn about the pin. @@ -97,6 +97,12 @@ "lens-desktop" ]; + # Identity registry: who each user is (name, email, keys, groups), keyed + # by username. Threaded into the system layer as the `userRegistry` + # specialArg and into each user's home config as the `identity` module + # arg. See users/registry.nix, modules/users.nix, home/git.nix. + userRegistry = import ./users/registry.nix; + # nixpkgs + nix-daemon settings shared by NixOS and Darwin hosts. commonModule = { nixpkgs.overlays = overlays; @@ -112,9 +118,9 @@ # Shared scaffolding for every NixOS host: common user, settings, home-manager. baseModules = [ - ./lyrathorpe/user.nix - ./system/modules/common-nixos.nix - ./system/modules/features.nix + ./modules/users.nix + ./modules/common-nixos.nix + ./modules/features.nix commonModule home-manager.nixosModules.home-manager { @@ -126,18 +132,19 @@ } ]; - # mkHost :: { system, username, fullName, modules, homeModules } -> nixosSystem + # mkHost :: { system, modules, users, portable } -> nixosSystem # Builds one machine by appending its host-specific modules to the shared - # baseModules. The user identity (username/fullName) is threaded through - # specialArgs so user.nix and the home modules stay host-agnostic, and the - # home-manager profile is keyed by the host's username. + # baseModules. `users` is an attrset keyed by username; each value carries + # that user's home-module list and optional per-host-user system bits + # (e.g. linger). Per-user identity is injected into each home config via + # the `identity` module arg (extraSpecialArgs is per-host, so it cannot + # carry per-user data); the system layer reads the global `userRegistry` + # restricted to this host's `hostUsers` set. mkHost = { system, - username, - fullName, modules, - homeModules, + users, # Host form factor. Laptops inherit the default; a desktop host sets # `portable = false` to drop mobile components (battery block, # brightness keys) from the home-manager Sway config. @@ -148,8 +155,7 @@ specialArgs = { inherit inputs - username - fullName + userRegistry portable ; }; @@ -157,16 +163,15 @@ baseModules ++ modules ++ [ + { _module.args.hostUsers = users; } { - home-manager.extraSpecialArgs = { - inherit - inputs - username - fullName - portable - ; - }; - home-manager.users.${username}.imports = homeModules; + home-manager.extraSpecialArgs = { inherit inputs portable; }; + home-manager.users = lib.mapAttrs (name: spec: { + imports = spec.homeModules; + _module.args.identity = userRegistry.${name} // { + username = name; + }; + }) users; } ]; }; @@ -185,19 +190,20 @@ } ]; - # mkDarwinHost :: { system, username, fullName, modules, homeModules } -> darwinSystem + # mkDarwinHost :: { system, username, modules, homeModules } -> darwinSystem # Darwin counterpart of mkHost. macOS already owns the login user, so we # only attach the platform and home-manager; no NixOS user module here. + # Stays single-user (macOS owns the account); identity is still sourced + # from the registry so the shared home modules behave as on NixOS. mkDarwinHost = { system, username, - fullName, modules, homeModules, }: nix-darwin.lib.darwinSystem { - specialArgs = { inherit inputs username fullName; }; + specialArgs = { inherit inputs username; }; modules = darwinBaseModules ++ modules @@ -206,40 +212,44 @@ nixpkgs.hostPlatform = system; # macOS owns the account; point home-manager at its home dir. users.users.${username}.home = "/Users/${username}"; - home-manager.extraSpecialArgs = { inherit inputs username fullName; }; - home-manager.users.${username}.imports = homeModules; + home-manager.extraSpecialArgs = { inherit inputs; }; + home-manager.users.${username} = { + imports = homeModules; + _module.args.identity = userRegistry.${username} // { + inherit username; + }; + }; } ]; }; # Host table — declarative registry of every machine. To add a host: - # give it a name, its `system`, the owning user, and the module lists. - # mapAttrs below turns each entry into a nixosConfiguration of the same name. + # give it a name, its `system`, its `users` set (each user's home-module + # list, plus optional per-host-user bits like linger), and the system + # `modules`. mapAttrs below turns each entry into a nixosConfiguration of + # the same name. Per-user home configs compose ./home (the shared bundle) + # with any per-user modules (e.g. ./users/emmathorpe/work.nix). hosts = { lyrathorpe-mbp = { system = "aarch64-linux"; - username = "lyrathorpe"; - fullName = "Lyra Thorpe"; modules = [ - ./system/machine/MBP-Asahi/configuration.nix - ./system/modules/laptop.nix + ./hosts/MBP-Asahi/configuration.nix + ./modules/laptop.nix nixos-apple-silicon.nixosModules.default - ./lyrathorpe/swaywm.nix + ./modules/sway.nix ]; - homeModules = [ - ./lyrathorpe/home - ./lyrathorpe/home/desktop.nix + users.lyrathorpe.homeModules = [ + ./home + ./home/desktop.nix ]; }; lyrathorpe-t400 = { system = "x86_64-linux"; - username = "lyrathorpe"; - fullName = "Lyra Thorpe"; modules = [ - ./system/machine/T400/configuration.nix - ./system/modules/laptop.nix - ./system/modules/ssh.nix + ./hosts/T400/configuration.nix + ./modules/laptop.nix + ./modules/ssh.nix # No t400-specific profile exists; compose the generic ThinkPad + # laptop/SSD/Intel building blocks (tp_smapi/acpi_call for battery # thresholds, SSD + microcode defaults). @@ -247,78 +257,76 @@ inputs.nixos-hardware.nixosModules.common-pc-laptop inputs.nixos-hardware.nixosModules.common-pc-laptop-ssd inputs.nixos-hardware.nixosModules.common-cpu-intel - ./lyrathorpe/swaywm.nix + ./modules/sway.nix ]; - homeModules = [ - ./lyrathorpe/home - ./lyrathorpe/home/desktop.nix + users.lyrathorpe.homeModules = [ + ./home + ./home/desktop.nix ]; }; lyrathorpe-macpro31 = { system = "x86_64-linux"; - username = "lyrathorpe"; - fullName = "Lyra Thorpe"; portable = false; modules = [ - ./system/machine/MacPro31/configuration.nix - ./system/modules/desktop.nix - ./system/modules/ssh.nix + ./hosts/MacPro31/configuration.nix + ./modules/desktop.nix + ./modules/ssh.nix inputs.nixos-hardware.nixosModules.common-pc-ssd inputs.nixos-hardware.nixosModules.common-cpu-intel - ./lyrathorpe/swaywm.nix + ./modules/sway.nix ]; - homeModules = [ - ./lyrathorpe/home - ./lyrathorpe/home/desktop.nix + users.lyrathorpe.homeModules = [ + ./home + ./home/desktop.nix ]; }; emmathorpe-edaas = { system = "x86_64-linux"; - username = "emmathorpe"; - fullName = "Emma Thorpe"; modules = [ - ./system/machine/EDaaS/configuration.nix + ./hosts/EDaaS/configuration.nix nixos-wsl.nixosModules.default - ./lyrathorpe/swaywm.nix - ]; - homeModules = [ - ./lyrathorpe/home - ./lyrathorpe/home/work.nix + ./modules/sway.nix ]; + users.emmathorpe = { + homeModules = [ + ./home + ./users/emmathorpe/work.nix + ]; + # Keep the systemd --user instance alive without a login session so + # the renovate-review home timer fires on schedule. + linger = true; + }; }; lyrathorpe-rpi5 = { system = "aarch64-linux"; - username = "lyrathorpe"; - fullName = "Lyra Thorpe"; portable = false; - # Headless server: Docker host + nginx reverse proxy. No swaywm.nix + # Headless server: Docker host + nginx reverse proxy. No sway.nix # (no desktop); the raspberry-pi-5 profile supplies kernel/firmware, # ssh.nix adds key-only sshd. modules = [ - ./system/machine/RPi5/configuration.nix + ./hosts/RPi5/configuration.nix inputs.nixos-hardware.nixosModules.raspberry-pi-5 - ./system/modules/ssh.nix + ./modules/ssh.nix ]; - homeModules = [ ./lyrathorpe/home ]; + users.lyrathorpe.homeModules = [ ./home ]; }; }; # Darwin host table — macOS machines built via mkDarwinHost. The shared - # ./lyrathorpe/home modules (shell, git, editor) are reused; the Linux-only + # ./home bundle (shell, git, editor) is reused directly; the Linux-only # desktop/sway modules are intentionally left out. darwinHosts = { lyrathorpe-mac = { system = "aarch64-darwin"; username = "lyrathorpe"; - fullName = "Lyra Thorpe"; modules = [ - ./system/machine/Darwin/configuration.nix + ./hosts/Darwin/configuration.nix ]; homeModules = [ - ./lyrathorpe/home + ./home ]; }; }; @@ -409,6 +417,70 @@ # Realise the host tables: each entry becomes a {nixos,darwin}Configuration. flake.nixosConfigurations = lib.mapAttrs (_name: mkHost) hosts; flake.darwinConfigurations = lib.mapAttrs (_name: mkDarwinHost) darwinHosts; + + # Reusable home modules, exported so this config can be consumed off these + # hosts -- by a standalone home-manager on a non-NixOS machine, or as an + # input to someone else's flake. `default` is the portable bundle + # (shell + git + editor + claude). Consumers must supply the module args + # these expect: `inputs` always; `identity` (see users/registry.nix) for + # git/desktop; `portable` for sway. `desktop`/`sway` additionally require + # a NixOS host that provides the Sway/Firefox binary -- they are not + # standalone-portable. + flake.homeModules = { + default = ./home; + shell = ./home/shell.nix; + git = ./home/git.nix; + editor = ./home/editor.nix; + claude = ./home/claude.nix; + desktop = ./home/desktop.nix; + sway = ./home/sway.nix; + }; + + # Standalone home-manager configurations: the portable bundle built for a + # machine NOT managed by this flake (`home-manager switch --flake + # .#"@"`). Only the portable subset is exposed; the desktop + # suite stays NixOS-only. homeConfigurations are not per-system, so the + # system is encoded in the attribute name, and home.username/homeDirectory + # are set explicitly (the NixOS module sets them automatically; standalone + # does not). + flake.homeConfigurations = + let + mkHome = + { + system, + name, + }: + home-manager.lib.homeManagerConfiguration { + pkgs = import nixpkgs { + inherit system overlays; + config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) unfreePackages; + }; + extraSpecialArgs = { + inherit inputs; + portable = true; + identity = userRegistry.${name} // { + username = name; + }; + }; + modules = [ + ./home + { + home.username = name; + home.homeDirectory = "/home/${name}"; + } + ]; + }; + in + { + "lyrathorpe@x86_64-linux" = mkHome { + system = "x86_64-linux"; + name = "lyrathorpe"; + }; + "lyrathorpe@aarch64-linux" = mkHome { + system = "aarch64-linux"; + name = "lyrathorpe"; + }; + }; } ); } diff --git a/lyrathorpe/home/KEYBINDINGS.md b/home/KEYBINDINGS.md similarity index 100% rename from lyrathorpe/home/KEYBINDINGS.md rename to home/KEYBINDINGS.md diff --git a/lyrathorpe/home/README.md b/home/README.md similarity index 100% rename from lyrathorpe/home/README.md rename to home/README.md diff --git a/lyrathorpe/home/claude.nix b/home/claude.nix similarity index 100% rename from lyrathorpe/home/claude.nix rename to home/claude.nix diff --git a/lyrathorpe/home/claude/CLAUDE.md b/home/claude/CLAUDE.md similarity index 100% rename from lyrathorpe/home/claude/CLAUDE.md rename to home/claude/CLAUDE.md diff --git a/lyrathorpe/home/claude/memory/MEMORY.md b/home/claude/memory/MEMORY.md similarity index 100% rename from lyrathorpe/home/claude/memory/MEMORY.md rename to home/claude/memory/MEMORY.md diff --git a/lyrathorpe/home/claude/memory/dev_clusters_disposable.md b/home/claude/memory/dev_clusters_disposable.md similarity index 100% rename from lyrathorpe/home/claude/memory/dev_clusters_disposable.md rename to home/claude/memory/dev_clusters_disposable.md diff --git a/lyrathorpe/home/claude/memory/docs_keep_updated.md b/home/claude/memory/docs_keep_updated.md similarity index 100% rename from lyrathorpe/home/claude/memory/docs_keep_updated.md rename to home/claude/memory/docs_keep_updated.md diff --git a/lyrathorpe/home/claude/memory/feedback_sandbox_prompts.md b/home/claude/memory/feedback_sandbox_prompts.md similarity index 100% rename from lyrathorpe/home/claude/memory/feedback_sandbox_prompts.md rename to home/claude/memory/feedback_sandbox_prompts.md diff --git a/lyrathorpe/home/claude/memory/git_check_state.md b/home/claude/memory/git_check_state.md similarity index 100% rename from lyrathorpe/home/claude/memory/git_check_state.md rename to home/claude/memory/git_check_state.md diff --git a/lyrathorpe/home/claude/memory/git_commit_signing.md b/home/claude/memory/git_commit_signing.md similarity index 100% rename from lyrathorpe/home/claude/memory/git_commit_signing.md rename to home/claude/memory/git_commit_signing.md diff --git a/lyrathorpe/home/claude/memory/git_conventions.md b/home/claude/memory/git_conventions.md similarity index 100% rename from lyrathorpe/home/claude/memory/git_conventions.md rename to home/claude/memory/git_conventions.md diff --git a/lyrathorpe/home/claude/memory/git_network_ops.md b/home/claude/memory/git_network_ops.md similarity index 100% rename from lyrathorpe/home/claude/memory/git_network_ops.md rename to home/claude/memory/git_network_ops.md diff --git a/lyrathorpe/home/claude/memory/jira_tooling.md b/home/claude/memory/jira_tooling.md similarity index 100% rename from lyrathorpe/home/claude/memory/jira_tooling.md rename to home/claude/memory/jira_tooling.md diff --git a/lyrathorpe/home/claude/memory/persona_soviet_engineer.md b/home/claude/memory/persona_soviet_engineer.md similarity index 100% rename from lyrathorpe/home/claude/memory/persona_soviet_engineer.md rename to home/claude/memory/persona_soviet_engineer.md diff --git a/lyrathorpe/home/claude/memory/user_name.md b/home/claude/memory/user_name.md similarity index 100% rename from lyrathorpe/home/claude/memory/user_name.md rename to home/claude/memory/user_name.md diff --git a/lyrathorpe/home/claude/memory/workflow_review_and_comments.md b/home/claude/memory/workflow_review_and_comments.md similarity index 100% rename from lyrathorpe/home/claude/memory/workflow_review_and_comments.md rename to home/claude/memory/workflow_review_and_comments.md diff --git a/lyrathorpe/home/claude/output-styles/soviet-engineer.md b/home/claude/output-styles/soviet-engineer.md similarity index 100% rename from lyrathorpe/home/claude/output-styles/soviet-engineer.md rename to home/claude/output-styles/soviet-engineer.md diff --git a/lyrathorpe/home/default.nix b/home/default.nix similarity index 100% rename from lyrathorpe/home/default.nix rename to home/default.nix diff --git a/lyrathorpe/home/desktop.nix b/home/desktop.nix similarity index 94% rename from lyrathorpe/home/desktop.nix rename to home/desktop.nix index c278b5f..3780577 100644 --- a/lyrathorpe/home/desktop.nix +++ b/home/desktop.nix @@ -1,12 +1,13 @@ # Graphical desktop layer: GUI apps, Wayland session env, and cursor theme. # Imported only on hosts that run Sway (MBP, T400, Mac Pro); never pulled onto # the headless WSL host. Login (and the Sway session launch) is handled by the -# greetd/ReGreet greeter -- see ../swaywm.nix -- so there is no tty1 autostart. +# greetd/ReGreet greeter -- see ../modules/sway.nix -- so there is no tty1 +# autostart. { pkgs, config, inputs, - username, + identity, ... }: { @@ -89,7 +90,7 @@ }; # Firefox is themed at the browser level (it does not follow the GTK theme). - # The system installs the binary (programs.firefox in ../user.nix); here + # The system installs the binary (programs.firefox in ../modules/users.nix); here # home-manager owns only the profile, hence package = null. Apply the # Catppuccin Mocha theme add-on (only the mauve accent is packaged upstream; # the rest of the desktop uses blue) and make content + UI dark. @@ -101,7 +102,7 @@ # stateVersion<26.05 default-change warning (the new XDG path depends on # Firefox's own profile support). configPath = ".mozilla/firefox"; - profiles.${username} = { + profiles.${identity.username} = { id = 0; isDefault = true; extensions = { diff --git a/lyrathorpe/home/editor.nix b/home/editor.nix similarity index 100% rename from lyrathorpe/home/editor.nix rename to home/editor.nix diff --git a/lyrathorpe/home/git.nix b/home/git.nix similarity index 77% rename from lyrathorpe/home/git.nix rename to home/git.nix index 9300ecf..4e90b5a 100644 --- a/lyrathorpe/home/git.nix +++ b/home/git.nix @@ -1,13 +1,14 @@ -# Version control: git + delta pager + commitizen + lazygit. The work host -# layers commit signing and an email override on top (see work.nix). +# Version control: git + delta pager + commitizen + lazygit. The committer +# identity (name, email, signing key) comes from the per-user `identity` arg, +# derived from the registry (users/registry.nix) by mkHost. { pkgs, lib, - fullName, + identity, ... }: let - ctp = import ../catppuccin-mocha.nix; + ctp = import ../lib/catppuccin-mocha.nix; in { home.packages = [ @@ -18,10 +19,10 @@ in enable = true; package = pkgs.gitFull; settings = { - user.name = fullName; - # Personal identity. mkDefault so the work module overrides it on the work - # host (and to merge cleanly with that plain definition there). - user.email = lib.mkDefault "iam@emmathe.dev"; + user.name = identity.fullName; + # Identity from the registry. mkDefault so a host-specific module can still + # override it without conflicting. + user.email = lib.mkDefault identity.email; push.autoSetupRemote = true; init.defaultBranch = "main"; @@ -77,14 +78,11 @@ in cc = "!cz commit"; }; - # SSH commit signing. This personal key is the default; the work module - # (work.nix) overrides it with the work key on the EDaaS host, the same way - # user.email is overridden -- so mkDefault here lets that plain definition - # win instead of conflicting. gpgsign is mkDefault too, so a host without - # the key in its ssh-agent can override it to false rather than fail every - # commit. + # SSH commit signing, key from the registry. mkDefault on the key and on + # gpgsign so a host without that key in its ssh-agent can override gpgsign + # to false rather than fail every commit. gpg.format = "ssh"; - user.signingkey = lib.mkDefault "key::ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDxHvdMTOzpFWUFMtCP7C/4tIOUO3GIO2QPvaifSnWH lyrathorpe@Lyra-MBA"; + user.signingkey = lib.mkDefault identity.signingKey; commit.gpgsign = lib.mkDefault true; tag.gpgsign = lib.mkDefault true; }; diff --git a/lyrathorpe/home/shell.nix b/home/shell.nix similarity index 99% rename from lyrathorpe/home/shell.nix rename to home/shell.nix index b47f80c..ec6e421 100644 --- a/lyrathorpe/home/shell.nix +++ b/home/shell.nix @@ -8,7 +8,7 @@ }: let # Shared Catppuccin Mocha palette: raw 6-hex strings, no leading "#". - ctp = import ../catppuccin-mocha.nix; + ctp = import ../lib/catppuccin-mocha.nix; in { imports = [ diff --git a/lyrathorpe/home/sway.nix b/home/sway.nix similarity index 99% rename from lyrathorpe/home/sway.nix rename to home/sway.nix index f250716..b52f67a 100644 --- a/lyrathorpe/home/sway.nix +++ b/home/sway.nix @@ -2,7 +2,7 @@ # Imported via ./desktop.nix, so only graphical hosts get it. # # The compositor binary, PAM and the polkit *daemon* come from the system-level -# programs.sway (see ../swaywm.nix); package = null below reuses it instead of +# programs.sway (see ../modules/sway.nix); package = null below reuses it instead of # pulling a second Sway. The polkit authentication *agent* (the thing that draws # the GUI auth dialog) is a user service started here. home-manager owns the user # config (~/.config/sway) and wires the systemd user session (sway-session.target), @@ -20,7 +20,7 @@ let # Catppuccin Mocha (shared with the ReGreet greeter). Raw hex; prefix "#" # where a consumer needs it -- Sway/i3status/dunst want "#", foot/swaylock do # not. - ctp = import ../catppuccin-mocha.nix; + ctp = import ../lib/catppuccin-mocha.nix; # Focused-window screenshot -> swappy editor (the dotfiles' grimshot.sh logic). # Full store paths so it needs nothing on PATH. diff --git a/system/machine/Darwin/configuration.nix b/hosts/Darwin/configuration.nix similarity index 98% rename from system/machine/Darwin/configuration.nix rename to hosts/Darwin/configuration.nix index 6cf40c3..630e784 100644 --- a/system/machine/Darwin/configuration.nix +++ b/hosts/Darwin/configuration.nix @@ -1,5 +1,5 @@ # Default nix-darwin host. Minimal macOS baseline; the user environment -# (shell, git, editor) is carried by the shared ./lyrathorpe/home modules, +# (shell, git, editor) is carried by the shared ./home modules, # the same ones used by the Linux hosts. nixpkgs.hostPlatform is set by # mkDarwinHost in flake.nix. { pkgs, username, ... }: diff --git a/system/machine/EDaaS/configuration.nix b/hosts/EDaaS/configuration.nix similarity index 88% rename from system/machine/EDaaS/configuration.nix rename to hosts/EDaaS/configuration.nix index 35adc8f..89da4eb 100644 --- a/system/machine/EDaaS/configuration.nix +++ b/hosts/EDaaS/configuration.nix @@ -62,12 +62,11 @@ features.swayDesktop.enable = false; - # Keep this user's systemd --user instance running without an open login - # session, so the home-manager user timer (renovate-review.nix) fires on - # schedule even when no terminal is attached. On WSL the timer still only runs - # while the distro itself is up; Persistent=true catches up a missed run at - # next start. - users.users.emmathorpe.linger = true; + # NOTE: this user's systemd --user lingering -- so the home-manager renovate + # timer fires without an open login session -- is enabled from the host table + # in flake.nix (users.emmathorpe.linger = true) and applied by + # modules/users.nix. + # programs.nix-ld is enabled for all NixOS hosts in common-nixos.nix. # This value determines the NixOS release from which the default # settings for stateful data, like file locations and database versions diff --git a/system/machine/MBP-Asahi/configuration.nix b/hosts/MBP-Asahi/configuration.nix similarity index 100% rename from system/machine/MBP-Asahi/configuration.nix rename to hosts/MBP-Asahi/configuration.nix diff --git a/system/machine/MBP-Asahi/hardware-configuration.nix b/hosts/MBP-Asahi/hardware-configuration.nix similarity index 100% rename from system/machine/MBP-Asahi/hardware-configuration.nix rename to hosts/MBP-Asahi/hardware-configuration.nix diff --git a/system/machine/MacPro31/README.md b/hosts/MacPro31/README.md similarity index 100% rename from system/machine/MacPro31/README.md rename to hosts/MacPro31/README.md diff --git a/system/machine/MacPro31/configuration.nix b/hosts/MacPro31/configuration.nix similarity index 96% rename from system/machine/MacPro31/configuration.nix rename to hosts/MacPro31/configuration.nix index 66b0834..77b1a16 100644 --- a/system/machine/MacPro31/configuration.nix +++ b/hosts/MacPro31/configuration.nix @@ -42,7 +42,7 @@ # - ATI Radeon HD 2600 XT -> "radeon" (older) or "amdgpu" KMS # - NVIDIA GeForce 8800 GT -> "nouveau" KMS # These come up automatically via the in-tree drivers + KMS, and the graphics - # stack itself is enabled by swaywm.nix. If a card needs to be forced, add it + # stack itself is enabled by modules/sway.nix. If a card needs to be forced, add it # here, e.g. `services.xserver.videoDrivers = [ "radeon" ];` (or "nouveau"), # and/or `boot.initrd.kernelModules = [ "radeon" ];` in # hardware-configuration.nix for early KMS. diff --git a/system/machine/MacPro31/hardware-configuration.nix b/hosts/MacPro31/hardware-configuration.nix similarity index 100% rename from system/machine/MacPro31/hardware-configuration.nix rename to hosts/MacPro31/hardware-configuration.nix diff --git a/system/machine/RPi5/README.md b/hosts/RPi5/README.md similarity index 100% rename from system/machine/RPi5/README.md rename to hosts/RPi5/README.md diff --git a/system/machine/RPi5/configuration.nix b/hosts/RPi5/configuration.nix similarity index 98% rename from system/machine/RPi5/configuration.nix rename to hosts/RPi5/configuration.nix index 0ab4c72..632c6da 100644 --- a/system/machine/RPi5/configuration.nix +++ b/hosts/RPi5/configuration.nix @@ -15,7 +15,7 @@ # (which selects by the local hostname) resolves without an explicit -H flag. networking.hostName = "lyrathorpe-rpi5"; - # Headless server: the Sway desktop is intentionally not set up. swaywm.nix is + # Headless server: the Sway desktop is intentionally not set up. modules/sway.nix is # not imported and features.swayDesktop.enable defaults to false (declared in # system/modules/features.nix), so this host keeps plain TTY/SSH login. diff --git a/system/machine/RPi5/docker.nix b/hosts/RPi5/docker.nix similarity index 100% rename from system/machine/RPi5/docker.nix rename to hosts/RPi5/docker.nix diff --git a/system/machine/RPi5/hardware-configuration.nix b/hosts/RPi5/hardware-configuration.nix similarity index 100% rename from system/machine/RPi5/hardware-configuration.nix rename to hosts/RPi5/hardware-configuration.nix diff --git a/system/machine/RPi5/reverse-proxy.nix b/hosts/RPi5/reverse-proxy.nix similarity index 100% rename from system/machine/RPi5/reverse-proxy.nix rename to hosts/RPi5/reverse-proxy.nix diff --git a/system/machine/T400/README.md b/hosts/T400/README.md similarity index 100% rename from system/machine/T400/README.md rename to hosts/T400/README.md diff --git a/system/machine/T400/boot-bios.nix b/hosts/T400/boot-bios.nix similarity index 100% rename from system/machine/T400/boot-bios.nix rename to hosts/T400/boot-bios.nix diff --git a/system/machine/T400/boot-coreboot-grub.nix b/hosts/T400/boot-coreboot-grub.nix similarity index 100% rename from system/machine/T400/boot-coreboot-grub.nix rename to hosts/T400/boot-coreboot-grub.nix diff --git a/system/machine/T400/boot-coreboot-uefi.nix b/hosts/T400/boot-coreboot-uefi.nix similarity index 100% rename from system/machine/T400/boot-coreboot-uefi.nix rename to hosts/T400/boot-coreboot-uefi.nix diff --git a/system/machine/T400/configuration.nix b/hosts/T400/configuration.nix similarity index 100% rename from system/machine/T400/configuration.nix rename to hosts/T400/configuration.nix diff --git a/system/machine/T400/hardware-configuration.nix b/hosts/T400/hardware-configuration.nix similarity index 100% rename from system/machine/T400/hardware-configuration.nix rename to hosts/T400/hardware-configuration.nix diff --git a/lyrathorpe/catppuccin-mocha.nix b/lib/catppuccin-mocha.nix similarity index 87% rename from lyrathorpe/catppuccin-mocha.nix rename to lib/catppuccin-mocha.nix index d621b95..0b51f7c 100644 --- a/lyrathorpe/catppuccin-mocha.nix +++ b/lib/catppuccin-mocha.nix @@ -1,6 +1,6 @@ # Catppuccin Mocha palette. Raw 6-digit hex (no leading "#"); consumers add a # "#" where their format needs it. Shared by the Sway desktop theming -# (home/sway.nix) and the ReGreet greeter (swaywm.nix) so the two stay in sync. +# (home/sway.nix) and the ReGreet greeter (modules/sway.nix) so the two stay in sync. { base = "1e1e2e"; mantle = "181825"; diff --git a/lyrathorpe/user.nix b/lyrathorpe/user.nix deleted file mode 100644 index 4482115..0000000 --- a/lyrathorpe/user.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ - config, - pkgs, - lib, - username, - fullName, - ... -}: - -{ - programs.zsh.enable = true; - users.users.${username} = { - isNormalUser = true; - home = "/home/${username}"; - description = fullName; - extraGroups = [ - "wheel" - "docker" - ]; - openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDxHvdMTOzpFWUFMtCP7C/4tIOUO3GIO2QPvaifSnWH lyrathorpe@Lyra-MBA" - ]; - shell = pkgs.zsh; - }; - programs.firefox = lib.mkIf (config.features.swayDesktop.enable == true) { - enable = true; - }; - programs.thunderbird = lib.mkIf (config.features.swayDesktop.enable == true) { - enable = true; - }; -} diff --git a/system/modules/common-nixos.nix b/modules/common-nixos.nix similarity index 100% rename from system/modules/common-nixos.nix rename to modules/common-nixos.nix diff --git a/system/modules/desktop.nix b/modules/desktop.nix similarity index 91% rename from system/modules/desktop.nix rename to modules/desktop.nix index f103ca7..072da84 100644 --- a/system/modules/desktop.nix +++ b/modules/desktop.nix @@ -2,7 +2,7 @@ # shared ./workstation.nix base and swaps the mobile Wi-Fi backend for wired # NetworkManager. A desktop host also sets `portable = false` in its host-table # entry (flake.nix), which drops the battery block and brightness keybindings -# from the Sway bar -- see lyrathorpe/home/sway.nix. +# from the Sway bar -- see home/sway.nix. { ... }: { imports = [ ./workstation.nix ]; diff --git a/system/modules/features.nix b/modules/features.nix similarity index 75% rename from system/modules/features.nix rename to modules/features.nix index 486c4b8..0d0de92 100644 --- a/system/modules/features.nix +++ b/modules/features.nix @@ -2,9 +2,9 @@ # baseModules in flake.nix). Declaring the flags here -- rather than inside the # module that implements them -- means a host can read or set a flag without # importing the (often large) implementation module. In particular, -# features.swayDesktop.enable is read by lyrathorpe/user.nix on every host, but a +# features.swayDesktop.enable is read by modules/users.nix on every host, but a # headless host (e.g. the Pi) must be able to leave it at its default without -# pulling in lyrathorpe/swaywm.nix. The implementation lives in swaywm.nix, +# pulling in modules/sway.nix. The implementation lives in modules/sway.nix, # gated on this flag. { lib, ... }: { diff --git a/system/modules/firmware/all_firmware.tar.gz b/modules/firmware/all_firmware.tar.gz similarity index 100% rename from system/modules/firmware/all_firmware.tar.gz rename to modules/firmware/all_firmware.tar.gz diff --git a/system/modules/firmware/kernelcache.release.mac14j b/modules/firmware/kernelcache.release.mac14j similarity index 100% rename from system/modules/firmware/kernelcache.release.mac14j rename to modules/firmware/kernelcache.release.mac14j diff --git a/system/modules/laptop.nix b/modules/laptop.nix similarity index 94% rename from system/modules/laptop.nix rename to modules/laptop.nix index 127dd95..7dfd6c9 100644 --- a/system/modules/laptop.nix +++ b/modules/laptop.nix @@ -2,7 +2,7 @@ # flake.nix. Shared graphical-workstation settings live in ./workstation.nix; # the only laptop-specific bit is the Wi-Fi backend. Mobile home-manager # components (battery block, brightness keys) are gated by the `portable` flag -# threaded through mkHost -- see lyrathorpe/home/sway.nix. +# threaded through mkHost -- see home/sway.nix. { ... }: { imports = [ ./workstation.nix ]; diff --git a/modules/ssh.nix b/modules/ssh.nix new file mode 100644 index 0000000..0c68157 --- /dev/null +++ b/modules/ssh.nix @@ -0,0 +1,14 @@ +# Key-only SSH hardening, imported by the hosts that run sshd (T400, Mac Pro, +# RPi5). The host config still does `services.openssh.enable = true` and opens +# port 22 next to where it documents the listening service; this module only +# tightens the policy so a host opting into sshd cannot accidentally ship +# password/root login. Authorized keys are owned per-user by the identity +# registry (users/registry.nix, applied via modules/users.nix), not here. +{ ... }: +{ + services.openssh.settings = { + PasswordAuthentication = false; # keys only + KbdInteractiveAuthentication = false; # no keyboard-interactive fallback + PermitRootLogin = "no"; + }; +} diff --git a/lyrathorpe/swaywm.nix b/modules/sway.nix similarity index 97% rename from lyrathorpe/swaywm.nix rename to modules/sway.nix index 22d27c5..8b01ac1 100644 --- a/lyrathorpe/swaywm.nix +++ b/modules/sway.nix @@ -7,8 +7,8 @@ let cfg = config.features.swayDesktop; - # Catppuccin Mocha (shared with the Sway desktop, see lyrathorpe/home/sway.nix). - ctp = import ./catppuccin-mocha.nix; + # Catppuccin Mocha (shared with the Sway desktop, see home/sway.nix). + ctp = import ../lib/catppuccin-mocha.nix; in { # The features.swayDesktop.enable option is declared in diff --git a/modules/users.nix b/modules/users.nix new file mode 100644 index 0000000..03a7749 --- /dev/null +++ b/modules/users.nix @@ -0,0 +1,44 @@ +# System-level user accounts, built from the identity registry +# (users/registry.nix). `hostUsers` is the host's user set, threaded by mkHost +# from the flake host table; `userRegistry` is the global identity table passed +# as a specialArg. Every account's identity -- description, groups, authorized +# keys -- comes from its registry entry, so no user data is hardcoded here and a +# host may declare any number of users. +{ + config, + pkgs, + lib, + hostUsers, + userRegistry, + ... +}: + +{ + programs.zsh.enable = true; + + users.users = lib.mapAttrs ( + name: spec: + let + id = userRegistry.${name}; + in + { + isNormalUser = true; + home = "/home/${name}"; + description = id.fullName; + inherit (id) extraGroups; + openssh.authorizedKeys.keys = id.sshAuthorizedKeys; + shell = pkgs.zsh; + } + # Keep this user's systemd --user instance running without an open login + # session (e.g. for home-manager user timers). Only emitted when the host + # table opts in, so hosts that don't set it leave linger entirely unmanaged. + // lib.optionalAttrs (spec ? linger) { inherit (spec) linger; } + ) hostUsers; + + programs.firefox = lib.mkIf (config.features.swayDesktop.enable == true) { + enable = true; + }; + programs.thunderbird = lib.mkIf (config.features.swayDesktop.enable == true) { + enable = true; + }; +} diff --git a/system/modules/workstation.nix b/modules/workstation.nix similarity index 100% rename from system/modules/workstation.nix rename to modules/workstation.nix diff --git a/system/modules/ssh.nix b/system/modules/ssh.nix deleted file mode 100644 index ee2423a..0000000 --- a/system/modules/ssh.nix +++ /dev/null @@ -1,19 +0,0 @@ -# Key-only SSH hardening, imported by the hosts that run sshd (T400, Mac Pro). -# The host config still does `services.openssh.enable = true` and opens port 22 -# next to where it documents the listening service; this module only tightens -# the policy and installs the authorized key, so a host opting into sshd cannot -# accidentally ship password/root login. -{ username, ... }: -{ - services.openssh.settings = { - PasswordAuthentication = false; # keys only - KbdInteractiveAuthentication = false; # no keyboard-interactive fallback - PermitRootLogin = "no"; - }; - - # The key permitted to log in as the primary user. Add more entries here as - # new client machines are provisioned. - users.users.${username}.openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDxHvdMTOzpFWUFMtCP7C/4tIOUO3GIO2QPvaifSnWH lyrathorpe@Lyra-MBA" - ]; -} diff --git a/lyrathorpe/home/renovate-review.nix b/users/emmathorpe/renovate-review.nix similarity index 100% rename from lyrathorpe/home/renovate-review.nix rename to users/emmathorpe/renovate-review.nix diff --git a/lyrathorpe/home/work.nix b/users/emmathorpe/work.nix similarity index 80% rename from lyrathorpe/home/work.nix rename to users/emmathorpe/work.nix index 6191c5a..6a6a9d4 100644 --- a/lyrathorpe/home/work.nix +++ b/users/emmathorpe/work.nix @@ -1,5 +1,7 @@ -# Home-manager module for the work (EDaaS/WSL) profile: corporate git signing, -# work toolchain packages and tmux tweaks. Imported only by the work host. +# Home-manager module for the work (EDaaS/WSL) profile: corporate work toolchain +# packages and tmux tweaks. Imported only by the work host. The corporate git +# identity (email + signing key) is the emmathorpe entry in the identity +# registry (users/registry.nix), applied by the shared home/git.nix. { pkgs, lib, ... }: { @@ -12,15 +14,6 @@ # programs.ssh (shell.nix) take it over. The ssh-agent below still runs. programs.ssh.enable = lib.mkForce false; - programs.git = { - settings = { - commit.gpgsign = true; - tag.gpgsign = true; - gpg.format = "ssh"; - user.signingkey = "key::ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJMVgeRKnfX1G8coU3nAobI485aeUpGTMqH7+zbKI8o emma.thorpe@cloud.com"; - user.email = "emma.thorpe@citrix.com"; - }; - }; home.packages = [ pkgs.kubectl pkgs.argo-rollouts @@ -66,7 +59,7 @@ }; # LSP servers only relevant to work: C# (omnisharp) and Helm charts (helm_ls). - # The shared editor (lyrathorpe/home/editor.nix) carries the universal ones; + # The shared editor (home/editor.nix) carries the universal ones; # these are gated to this host so the heavy omnisharp closure stays off the # personal machines. Tree-sitter grammars (highlighting) remain global there. programs.nixvim.plugins.lsp.servers = { diff --git a/users/registry.nix b/users/registry.nix new file mode 100644 index 0000000..56c02b5 --- /dev/null +++ b/users/registry.nix @@ -0,0 +1,40 @@ +# User identity registry -- pure data, no machinery. Keyed by username. +# +# Each entry describes WHO a user is (display name, email, authorized/signing +# keys, supplementary groups). The reusable modules read this indirectly: +# - system: modules/users.nix builds users.users.* from `userRegistry` +# (specialArg) restricted to the host's `hostUsers` set. +# - home: home/git.nix and home/desktop.nix read the per-user `identity` +# module arg, which mkHost derives from the matching registry entry. +# +# The login name is injected by mkHost as `identity.username`, so it is not +# repeated inside each entry here. +{ + lyrathorpe = { + fullName = "Lyra Thorpe"; + email = "iam@emmathe.dev"; + extraGroups = [ + "wheel" + "docker" + ]; + sshAuthorizedKeys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDxHvdMTOzpFWUFMtCP7C/4tIOUO3GIO2QPvaifSnWH lyrathorpe@Lyra-MBA" + ]; + signingKey = "key::ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDxHvdMTOzpFWUFMtCP7C/4tIOUO3GIO2QPvaifSnWH lyrathorpe@Lyra-MBA"; + }; + + emmathorpe = { + fullName = "Emma Thorpe"; + email = "emma.thorpe@citrix.com"; + extraGroups = [ + "wheel" + "docker" + ]; + # No personal authorized key on file yet. The previous shared user module + # applied Lyra's key to every account, including this one -- a defect. Leave + # this empty until a real key is provisioned; SSH login is moot on the WSL + # host (entered via wsl.exe, not sshd). + sshAuthorizedKeys = [ ]; + signingKey = "key::ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJMVgeRKnfX1G8coU3nAobI485aeUpGTMqH7+zbKI8o emma.thorpe@cloud.com"; + }; +}