nixos/polkit: modernize

This commit is contained in:
Martin Weinelt 2026-06-09 22:29:28 +02:00
commit 3a8b38d4ee
No known key found for this signature in database
GPG key ID: 87C1E9888F856759
2 changed files with 59 additions and 33 deletions

View file

@ -6,27 +6,51 @@
}:
let
cfg = config.security.polkit;
inherit (lib)
mkEnableOption
mkOption
mkIf
mkPackageOption
mkRemovedOptionModule
types
;
cfg = config.security.polkit;
in
{
imports = [
(mkRemovedOptionModule [ "security" "polkit" "debug" ] "Use security.polkit.extraArgs instead")
];
options = {
options.security.polkit = {
enable = mkEnableOption "polkit";
security.polkit.enable = lib.mkEnableOption "polkit";
security.polkit.package = lib.mkPackageOption pkgs "polkit" { };
package = mkPackageOption pkgs "polkit" { };
security.polkit.debug = lib.mkEnableOption "debug logs from polkit. This is required in order to see log messages from rule definitions";
extraArgs = mkOption {
type = types.listOf types.str;
default = [
"--no-debug"
"--log-level=notice"
];
description = ''
List of arguments to pass to the polkitd executable.
security.polkit.extraConfig = lib.mkOption {
type = lib.types.lines;
::: {.note}
To see debug logs you need to negate the default `--no-debug` setting.
:::
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
example = ''
/* Log authorization checks. */
polkit.addRule(function(action, subject) {
// Make sure to set { security.polkit.debug = true; } in configuration.nix
// Make sure to negate --no-debug in services.polkit.extraArgs: { security.polkit.extraArgs = [ "--log-level=notice" ]; }
polkit.log("user " + subject.user + " is attempting action " + action.id + " from PID " + subject.pid);
});
@ -41,8 +65,8 @@ in
'';
};
security.polkit.adminIdentities = lib.mkOption {
type = lib.types.listOf lib.types.str;
adminIdentities = mkOption {
type = with types; listOf str;
default = [ "unix-group:wheel" ];
example = [
"unix-user:alice"
@ -58,25 +82,35 @@ in
};
config = lib.mkIf cfg.enable {
config = mkIf cfg.enable {
environment.systemPackages = [
cfg.package.bin
cfg.package.out
];
services.dbus.packages = [ cfg.package.out ];
systemd.packages = [ cfg.package.out ];
systemd.services.polkit.serviceConfig.ExecStart = [
""
"${cfg.package.out}/lib/polkit-1/polkitd ${lib.optionalString (!cfg.debug) "--no-debug"}"
];
systemd.services.polkit.restartTriggers = [ config.system.path ];
systemd.services.polkit.reloadTriggers = [
config.environment.etc."polkit-1/rules.d/10-nixos.rules".source
];
systemd.services.polkit.stopIfChanged = false;
systemd.services.polkit = {
restartTriggers = [ config.system.path ];
reloadTriggers = [
config.environment.etc."polkit-1/rules.d/10-nixos.rules".source
];
stopIfChanged = false;
serviceConfig.ExecStart = [
# nuke default ExecStart
""
# provide our own instead
(toString (
[
"${lib.getLib cfg.package}/lib/polkit-1/polkitd"
]
++ cfg.extraArgs
))
];
};
systemd.sockets."polkit-agent-helper".wantedBy = [ "sockets.target" ];
@ -89,7 +123,7 @@ in
# The upstream unit uses PrivateDevices=yes and ProtectHome=yes,
# which prevents PAM modules from accessing hardware (e.g. FIDO
# tokens via /dev/hidraw*) or reading key files from home directories.
(lib.mkIf config.security.pam.u2f.enable {
(mkIf config.security.pam.u2f.enable {
# Override upstream PrivateDevices=yes to allow access to /dev/hidraw*
PrivateDevices = false;
DeviceAllow = [
@ -100,7 +134,7 @@ in
# ~/.config/Yubico/u2f_keys (the default key file location)
ProtectHome = "read-only";
})
(lib.mkIf config.security.pam.zfs.enable {
(mkIf config.security.pam.zfs.enable {
PrivateDevices = false;
DeviceAllow = [
"/dev/zfs rw"
@ -120,23 +154,15 @@ in
${cfg.extraConfig}
''; # TODO: validation on compilation (at least against typos)
services.dbus.packages = [ cfg.package.out ];
security.pam.services.polkit-1 = { };
security.wrappers.pkexec = {
setuid = true;
owner = "root";
group = "root";
source = "${cfg.package.bin}/bin/pkexec";
source = lib.getExe' cfg.package "pkexec";
};
systemd.tmpfiles.rules = [
# Probably no more needed, clean up
"R /var/lib/polkit-1"
"R /var/lib/PolicyKit"
];
users.users.polkituser = {
description = "PolKit daemon";
uid = config.ids.uids.polkituser;

View file

@ -55,7 +55,7 @@
# Provide a little logging of polkit checks - otherwise it's
# impossible to know what's going on.
security.polkit.debug = true;
security.polkit.extraArgs = [ "--log-level=notice" ];
security.polkit.extraConfig = ''
polkit.addRule(function(action, subject) {
const ns = "org.freedesktop.RealtimeKit1.";