How to Audit and Configure Polkit Authorization Rules in Ubuntu Using pkaction and pkcheck

In modern Linux distributions like Ubuntu, unprivileged desktop users and background services frequently require elevated rights to perform specific administrative tasks—such as restarting a systemd daemon, managing network connections via NetworkManager, or mounting an external storage volume—without acquiring full, unrestricted root access via sudo. The Polkit (formerly PolicyKit) framework provides this fine-grained privilege mediation. Rather than granting blanket root permissions, Polkit evaluates discrete action IDs against declarative authorization rules. Using the pkaction and pkcheck command-line tools, administrators can audit registered system actions, test process privileges, and deploy custom JavaScript authorization rules.

Understanding the Polkit Authorization Model

Polkit separates privilege definition from privilege authorization. The framework operates on three primary concepts:

  • Actions: Unique reverse-domain identifiers defined by installed packages in XML policy files (stored in /usr/share/polkit-1/actions/). For example, org.freedesktop.systemd1.manage-units controls systemd unit operations.
  • Default Authorizations: Defined within action XML files, specifying access levels for any (remote sessions), inactive (unfocused console sessions), and active (local logged-in graphical sessions). Values include no, yes, auth_self, and auth_admin.
  • Rules: JavaScript files located in /etc/polkit-1/rules.d/ (local administrator overrides) and /usr/share/polkit-1/rules.d/ (vendor packages). These rules dynamically intercept authorization requests and apply custom logic based on user, group, or process attributes.

The pkaction utility inspects registered action definitions, while pkcheck queries the Polkit daemon (polkitd) to test whether a given process is authorized for an action.

Auditing Available System Actions with pkaction

To list all Polkit actions currently registered on your Ubuntu system, open a terminal and execute:

pkaction

The output streams hundreds of registered action names spanning systemd, udisks2, NetworkManager, packagekit, and desktop environment components. You can filter for specific subsystems using grep:

pkaction | grep "org.freedesktop.systemd1"

To inspect the detailed definition, description, and default access controls for a specific action, use the --action-id parameter along with --verbose:

pkaction --action-id org.freedesktop.systemd1.manage-units --verbose

The output details the exact security configuration:

org.freedesktop.systemd1.manage-units:
  description:       Manage system services or other units
  message:           Authentication is required to manage system services or other units.
  default_any:       auth_admin
  default_inactive:  auth_admin
  default_active:    auth_admin_keep

Here, auth_admin_keep indicates that a local active user must authenticate with administrative credentials once, after which Polkit caches the authorization for a grace period.

Testing Authorization Checks with pkcheck

System daemons invoke Polkit authorization checks when unprivileged clients send D-Bus requests. You can simulate and test these authorization checks from the command line using pkcheck.

To test whether your current shell process (represented by $$) is authorized to reboot the system without triggering an authentication dialogue, execute:

pkcheck --action-id org.freedesktop.login1.reboot --process $$

If the process is fully authorized, the command exits silently with return code 0. If authorization is denied or requires interactive credentials, pkcheck exits with an error code (such as exit code 1 or 2) and prints an error message. To allow interactive password prompts during testing, append the --allow-user-interaction flag:

pkcheck --action-id org.freedesktop.systemd1.manage-units --process $$ --allow-user-interaction

Creating Custom Polkit Rules in Ubuntu

Ubuntu utilizes JavaScript-based Polkit rule syntax. Custom rules placed in /etc/polkit-1/rules.d/ take precedence over system rules and execute in alphanumeric order.

For example, if you want members of a local developer group named developers to restart a specific web server service (nginx.service) without being prompted for a root password, create a custom rule file:

sudo nano /etc/polkit-1/rules.d/50-developer-service-control.rules

Add the following JavaScript definition:

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        subject.isInGroup("developers")) {
        var verb = action.lookup("verb");
        var unit = action.lookup("unit");
        if ((verb == "restart" || verb == "status") && unit == "nginx.service") {
            return polkit.Result.YES;
        }
    }
});

Save the file. Polkit’s inotify monitors automatically detect changes in /etc/polkit-1/rules.d/, applying the new authorization rule immediately without requiring a daemon restart.

Debugging Polkit Rule Execution via System Logs

If a custom rule does not behave as expected, insert diagnostic logging directly into your JavaScript rule using polkit.log():

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units") {
        polkit.log("Evaluating user: " + subject.user + " for unit: " + action.lookup("unit"));
    }
});

Then monitor the Polkit log output in real time using journalctl:

sudo journalctl -u polkit.service -f

Every time an action is evaluated, your diagnostic statement will appear in the system journal, confirming whether variables and group checks matched correctly.

Mastering pkaction and pkcheck enables system administrators to implement least-privilege security architectures across Ubuntu workstations and enterprise servers with surgical accuracy.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.