Polkit
Polkit is used for controlling system-wide privileges. It provides an organized way for non-privileged processes to communicate with privileged ones. In contrast to sudo, it does not grant root permission to an entire process, but rather allows a finer level of control of centralized system policy.
Enable polkit
Polkit is disabled by default. If you wish to enable it, you can set security.polkit.enable
to true. (However, if you are running any one of the desktop environments, you are likely to have polkit enabled as a dependency.)
Writing rules
The Polkit rule language is described at https://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html#polkit-rules. It is really just JavaScript with an API.
On NixOS, Polkit uses Duktape as its JavaScript runtime. Keep that in mind when you try to write newfangled code.
The rules you write, together with any rule generated by security.polkit
, is stored at /etc/polkit-1/rules.d/10-nixos.rules
for the current running generation.
Reboot/poweroff for unprivileged users
With the following rule, we can grant the permissions reboot
and poweroff
a machine to users in the
users
group.
This is useful on a multi-user machine. It may also be of particular importance when using XRDP or other similar Remote Desktop solutions.
/etc/nixos/configuration.nix
security.polkit.extraConfig = ''
polkit.addRule(function (action, subject) {
if (
subject.isInGroup("users") &&
[
"org.freedesktop.login1.reboot",
"org.freedesktop.login1.reboot-multiple-sessions",
"org.freedesktop.login1.power-off",
"org.freedesktop.login1.power-off-multiple-sessions",
].indexOf(action.id) !== -1
) {
return polkit.Result.YES;
}
});
'';
No password for wheel
The following rule is the analogue of NOPASSWD:ALL in sudo, in that wheel users do not need to authenticate again when performing any action.
/etc/nixos/configuration.nix
security.polkit.extraConfig = ''
polkit.addRule(function(action, subject) {
if (subject.isInGroup("wheel"))
return polkit.Result.YES;
});
'';
(This does not take into account the security.polkit.adminIdentities
setting.)
Authentication agents
If Polkit seems not to work properly, you could check that you have an authentication agent installed and running (especially if you use a more niche desktop environment like e.g. i3wm).
For example, polkit_gnome
is a GNOME-based authentication agent, but it will usually only autostart when used with GNOME, KDE, or Unity (examine its autostart file in etc/xdg/autostart/polkit-gnome-authentication-agent-1.desktop
for details); otherwise you will need to start it yourself, e.g. by copying that autostart file to ~/.config/autostart/
and removing the parts that restrict it to GNOME/KDE/Unity.
Alternatively, you can start it on login by creating a systemd user service:
systemd = {
user.services.polkit-gnome-authentication-agent-1 = {
description = "polkit-gnome-authentication-agent-1";
wantedBy = [ "graphical-session.target" ];
wants = [ "graphical-session.target" ];
after = [ "graphical-session.target" ];
serviceConfig = {
Type = "simple";
ExecStart = "${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1";
Restart = "on-failure";
RestartSec = 1;
TimeoutStopSec = 10;
};
};
};
Another option is lxqt.lxqt-policykit
, which can be launched on login through the command lxqt-policykit-agent
on e.g. Hyprland.
Start the authentication agent in dwm
If you use dwm patched with dwm-autostart-20210120-cb3f58a.diff, you can add a command into ~/.dwm/autostart.sh
to start a polkit agent. Here take mate.mate-polkit
for example:
#!/bin/sh
# General stuff
...
/nix/store/$(ls -la /nix/store | grep 'mate-polkit' | grep '4096' | awk '{print $9}' | sed -n '$p')/libexec/polkit-mate-authentication-agent-1 &
...
Use this method, you won't need to change the codes even mate.mate-polkit
gets an update.
#!/bin/sh
...
/nix/store/$(ls -la /nix/store | grep polkit-kde-agent | grep '^d' | awk '{print $9}')/libexec/polkit-kde-authentication-agent-1 &
...
The same but for polkit-kde-agent