diff --git a/system/modules/default.nix b/system/modules/default.nix index ef298e64..899808b0 100644 --- a/system/modules/default.nix +++ b/system/modules/default.nix @@ -8,7 +8,8 @@ ... }: { imports = [ - ./systemd-networkd ./containers + ./polkit + ./systemd-networkd ]; } diff --git a/system/modules/polkit/default.nix b/system/modules/polkit/default.nix new file mode 100644 index 00000000..b06e3619 --- /dev/null +++ b/system/modules/polkit/default.nix @@ -0,0 +1,42 @@ +{ + config, + nixosConfig, + lib, + mylib, + pkgs, + ... +}: +with lib; +with mylib.modules; let + cfg = config.modules.polkit; +in { + options.modules.polkit = import ./options.nix {inherit lib mylib;}; + + config = mkIf cfg.enable { + security.polkit.enable = true; + + # TODO: Don't hardcode subject.user == "christoph" + security.polkit.extraConfig = let + # Stuff that is non-negotiable + always-predicates = [ + # TODO: Those should be set by the VPN/networkd module + "wg0-de-115.service" + "wg0-lu-16.service" + ]; + + mkServicePredicate = service: "action.lookup(\"unit\") == \"${service}\""; + predicates = lib.pipe (cfg.allowed-system-services ++ always-predicates) [ + (builtins.map mkServicePredicate) + (builtins.concatStringsSep " ||\n") + ]; + in '' + polkit.addRule(function(action, subject) { + if (action.id == "org.freedesktop.systemd1.manage-units" && subject.user == "christoph" && ( + ${predicates} + )) { + return polkit.Result.YES; + } + }); + ''; + }; +} diff --git a/system/modules/polkit/options.nix b/system/modules/polkit/options.nix new file mode 100644 index 00000000..2bcf16f2 --- /dev/null +++ b/system/modules/polkit/options.nix @@ -0,0 +1,21 @@ +{ + lib, + mylib, + ... +}: +with lib; +with mylib.modules; { + enable = mkEnableOpt "Polkit"; + + allowed-system-services = mkOption { + type = types.listOf types.str; + description = "System Services that should be manageable by a User without Root Password"; + example = '' + [ + "jellyfin" + "stablediffusion" + ] + ''; + default = []; + }; +}