nix/common/security.nix
2026-06-09 16:01:48 +10:00

83 lines
2.9 KiB
Nix

{
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";
};
};
}