@@ -79,6 +79,19 @@ in {
7979 for supported values.
8080 '';
8181 };
82+
83+ allowSystemControl = mkOption {
84+ type = types.bool;
85+ default = false;
86+ description = ''
87+ Whether to allow Moonraker to perform system-level operations.
88+
89+ Moonraker exposes APIs to perform system-level operations, such as
90+ reboot, shutdown, and management of systemd units. See the
91+ <link xlink:href="https://moonraker.readthedocs.io/en/latest/web_api/#machine-commands">documentation</link>
92+ for details on what clients are able to do.
93+ '';
94+ };
8295 };
8396 };
8497
@@ -86,6 +99,13 @@ in {
8699 warnings = optional (cfg.settings ? update_manager)
87100 ''Enabling update_manager is not supported on NixOS and will lead to non-removable warnings in some clients.'';
88101
102+ assertions = [
103+ {
104+ assertion = cfg.allowSystemControl -> config.security.polkit.enable;
105+ message = "services.moonraker.allowSystemControl requires polkit to be enabled (security.polkit.enable).";
106+ }
107+ ];
108+
89109 users.users = optionalAttrs (cfg.user == "moonraker") {
90110 moonraker = {
91111 group = cfg.group;
@@ -137,5 +157,22 @@ in {
137157 User = cfg.user;
138158 };
139159 };
160+
161+ security.polkit.extraConfig = lib.optionalString cfg.allowSystemControl ''
162+ // nixos/moonraker: Allow Moonraker to perform system-level operations
163+ //
164+ // This was enabled via services.moonraker.allowSystemControl.
165+ polkit.addRule(function(action, subject) {
166+ if ((action.id == "org.freedesktop.systemd1.manage-units" ||
167+ action.id == "org.freedesktop.login1.power-off" ||
168+ action.id == "org.freedesktop.login1.power-off-multiple-sessions" ||
169+ action.id == "org.freedesktop.login1.reboot" ||
170+ action.id == "org.freedesktop.login1.reboot-multiple-sessions" ||
171+ action.id.startsWith("org.freedesktop.packagekit.")) &&
172+ subject.user == "${cfg.user}") {
173+ return polkit.Result.YES;
174+ }
175+ });
176+ '';
140177 };
141178}