{ self, ... }: { flake.nixosModules.sshInbound = { config, lib, ... }: let cfg = config.chiasson.ssh.inbound; inventory = self.lib.sshInventory; # Every inbound-enabled user must have a publicKey pasted into the # inventory — silently dropping the key would lock the user out. missingKeys = lib.filter (name: let line = inventory.mkAuthorizedKeyLine name (cfg.userAuthorizedHosts.${name} or "all"); in line == null) (lib.attrNames cfg.userAuthorizedHosts); in { options.chiasson.ssh.inbound = { enable = lib.mkEnableOption "Write user-specific SSH inventory public keys into `authorized_keys`."; userAuthorizedHosts = lib.mkOption { type = lib.types.attrsOf (lib.types.either (lib.types.enum [ "all" ]) (lib.types.listOf lib.types.str)); default = { }; example = { olivier = "all"; server = [ "192.168.2.25" "192.168.2.15" ]; }; description = '' Catalog users whose inventory public key is installed in `authorized_keys`. The value is either `"all"` (no `from=` restriction) or a list of source identifiers appended to sshd's `from=` constraint. List entries should be IPs or CIDRs; hostnames require reverse-DNS to resolve cleanly on the target. ''; }; }; config = lib.mkMerge [ { assertions = [{ assertion = cfg.enable -> missingKeys == [ ]; message = "chiasson.ssh.inbound: users enabled but missing public key in `modules/ssh/inventory.nix`: ${lib.concatStringsSep ", " missingKeys}"; }]; } (lib.mkIf cfg.enable { users.users = lib.mapAttrs (name: selection: { openssh.authorizedKeys.keys = [ (inventory.mkAuthorizedKeyLine name selection) ]; }) cfg.userAuthorizedHosts; }) ]; }; }