{ lib, pkgs, inputs, mainUser, getFlakePkg, ... }: { imports = [ inputs.run0-shim.nixosModules.default ]; environment.shellAliases = { #make run0 use aliases run0 = "run0 --background='' "; s = "run0"; }; services.dbus.implementation = "broker"; security = { sudo.enable = false; polkit = { enable = true; extraConfig = '' polkit.addRule(function(action, subject) { if (action.id == "org.freedesktop.policykit.exec" || action.id.indexOf("org.freedesktop.systemd1.") == 0) { return polkit.Result.AUTH_ADMIN_KEEP; } }); ''; }; }; environment.systemPackages = [ (getFlakePkg inputs.run0-shim) ]; security.soteria.enable = true; systemd.user.services.polkit-soteria = { after = [ "dbus.socket" ]; requires = [ "dbus.socket" ]; serviceConfig = { Environment = [ "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%U/bus" ]; # RestartSec = 3; }; unitConfig = { StartLimitIntervalSec = 30; StartLimitBurst = 5; }; }; # polkitd drops every registered authentication agent when it restarts, and # soteria 0.3.1 never re-registers — it lingers as a live process with a dead # registration, after which run0/sudo silently falls back to a tty pkttyagent # prompt instead of the GUI dialog. `nixos-rebuild switch` was restarting # polkitd on every config change, knocking soteria out of the agent slot many # times a day. Two-part fix: # (B) reload polkit instead of restarting it for config-only changes — # a polkitd SIGHUP re-reads rules without tearing down live agent # registrations, so editing the rule above no longer de-registers soteria. # (A) for the cases that still force a genuine restart (manual restart, # reboot), bounce soteria afterwards so it re-registers. # Caveat of (B): a polkit *package* bump changes the unit but won't restart it, # so the new polkitd binary only takes effect after a reboot or manual # `systemctl restart polkit`. Acceptable here; rule edits are the hot path. # Proper upstream fix: soteria should watch org.freedesktop.PolicyKit1 for # NameOwnerChanged and re-register itself (issue to be filed). systemd.services.polkit = { restartIfChanged = false; reloadIfChanged = true; }; systemd.services.polkit-soteria-reregister = { description = "Re-register soteria with polkitd after polkit (re)starts"; after = [ "polkit.service" ]; partOf = [ "polkit.service" ]; wantedBy = [ "polkit.service" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; # `-` ignores failure: the user manager may not be up yet (e.g. at boot), # and try-restart is a no-op when soteria isn't currently running. ExecStart = "-${pkgs.systemd}/bin/systemctl --user --machine ${mainUser}@.host try-restart polkit-soteria.service"; }; }; }