Join our Newsletter — 33% off our NHI Course
Home› Guides› polkit Security Guide: Authorisation Rules and Privileged D-Bus…
Guide Endpoint Security

polkit Security Guide: Authorisation Rules and Privileged D-Bus Actions

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 13 min read
On this page

Most Linux privilege reviews stop at sudoers, but polkit is a second, parallel path to root-level actions that decides who can manage services, mount disks, change networking, install packages or run pkexec, and it is rarely reviewed. polkit (formerly PolicyKit) is the authorisation framework that privileged D-Bus services consult before acting for an unprivileged caller. Its defaults differ by distribution and by whether a user is sitting at the console, which is why flaws such as PwnKit (CVE-2021-4034) and CVE-2021-3560 turned it into a common escalation route. This guide explains how polkit decides, which files and rules matter, how pkexec fits in, how to log and detect misuse, and how to harden servers and desktops. It is for Linux administrators, platform engineers and security reviewers. It goes deeper than the Linux Privilege Escalation Techniques Guide and complements the sudo and sudoers Security Guide.

Key takeaways

  • polkit is a second sudoers. Every action a D-Bus mechanism defines (systemd units, logins, disks, networking, accounts, packages) has its own authorisation, separate from sudo, and should be in scope for privilege reviews.
  • "Active" is an authorisation input. Defaults distinguish allow_active (local console session), allow_inactive and allow_any (for example SSH); anything that makes a remote user look active, as CVE-2025-6018 did, unlocks desktop-grade privileges.
  • Rules are JavaScript that runs first match wins. Files in /etc/polkit-1/rules.d and the other rules directories are processed in lexical order, and an early rule that returns a value can silently override everything after it.
  • pkexec is a setuid root binary. PwnKit showed that its presence alone was enough for local root on most distributions; remove it from servers that do not need it, and patch fast.
  • Prefer auth_admin, avoid _keep with variables. Upstream documentation says auth_self is not restrictive enough on multi-user systems, and *_KEEP results cache authorisation for about five minutes even if the request details change.

How identity and access work in polkit

polkit separates three parties. A mechanism is a privileged service, usually on the system D-Bus, such as systemd, logind, udisks or NetworkManager. A subject is the unprivileged process asking it to do something. The authority is polkitd, which provides the org.freedesktop.PolicyKit1 service and runs as the unprivileged polkitd system user. The mechanism asks the authority whether the subject is authorised for a named action and acts on the answer.

Where the decision comes from

  1. Action declarations: XML .policy files in /usr/share/polkit-1/actions define action IDs (for example org.freedesktop.login1.reboot) and their implicit defaults. List them with pkaction; view one with pkaction -v --action-id=<id>.
  2. Authorisation rules: JavaScript .rules files read from /etc/polkit-1/rules.d, /run/polkit-1/rules.d, /usr/local/share/polkit-1/rules.d and /usr/share/polkit-1/rules.d. Files are ordered by basename across all directories; on a tie, the earlier directory wins. All directories are monitored and reloaded when a file changes.
  3. Distribution layers: SUSE applies its own profiles (easy, standard, restrictive) over upstream defaults, selected with POLKIT_DEFAULT_PRIVS in /etc/sysconfig/security and applied with set_polkit_default_privs, with local overrides in /etc/polkit-default-privs.local. On SUSE, pkaction shows upstream defaults only, so it can mislead a review.

Implicit authorisations

ContextApplies toSecurity note
allow_activeClients in the active session on a local consoleMost generous on desktops; must never be reachable remotely
allow_inactiveClients in inactive local console sessionsUsually stricter than active
allow_anyAny other client, including SSH and service processesThe setting that matters most on servers
ValueMeaningUse
noNot authorisedDefault for sensitive actions on servers
yesAuthorised without authenticationOnly for harmless actions or tightly scoped rules
auth_self / auth_self_keepSession owner must authenticate as themselvesUpstream warns it is not restrictive enough on multi-user systems
auth_admin / auth_admin_keepAn administrative identity must authenticateRecommended baseline for privileged actions

The _keep variants retain the authorisation for a short period, 300 seconds by default (ExpirationSeconds in polkitd.conf). Authentication itself is performed by an authentication agent in the user's session, or by pkttyagent for text sessions, with polkit-agent-helper-1 verifying credentials through PAM. See the Linux PAM Guide.

Admin roles and privileged access

"Administrator" in polkit is whatever addAdminRule() returns: an array of identities such as unix-group:wheel, unix-netgroup:<netgroup> or unix-user:<user>. Distributions ship a default admin rule; Red Hat family systems commonly use the wheel group and Debian family systems the sudo group. Membership of that group therefore grants two things: sudo rights and the ability to satisfy every auth_admin prompt.

  • Review the admin group as privileged: include wheel or sudo membership, and every addAdminRule in rules files, in privileged access reviews. See the Unix and Linux Privileged Access Guide.
  • pkexec: runs a program as another user, root by default. The default action org.freedesktop.policykit.exec requires administrator authentication, and pkexec sets a minimal environment and PKEXEC_UID. It does not validate arguments, so any custom action (via the org.freedesktop.policykit.exec.path annotation) that lets users run a program without fresh admin authentication must treat input as untrusted, like any setuid program.
  • Remove pkexec where unused: servers rarely need it. Qualys' PwnKit advisory notes the vulnerable code dated from May 2009, that exploitation did not need polkitd to be running, and gave removing the setuid bit (chmod 0755 /usr/bin/pkexec) as a stopgap until patching.
  • Delegate narrowly: if an operations group needs to restart one service, write a rule for that action and unit, rather than adding them to wheel.

Writing safe delegation rules

Rules receive an action (with id and lookup() for mechanism variables) and a subject (with user, groups, isInGroup(), local, active, system_unit and no_new_privileges). A rule that grants one group the right to manage one systemd unit, and nothing else, looks like this:

// /etc/polkit-1/rules.d/50-ops-restart-app.rules
polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        action.lookup("unit") == "app.service" &&
        subject.isInGroup("app-ops")) {
        return polkit.Result.AUTH_ADMIN;
    }
});
  • Match exact IDs: prefix matches such as indexOf("org.freedesktop.udisks2.") == 0 grant every current and future action in the namespace.
  • Do not trust display strings: pkexec's command_line variable is documented as not secure for checks; use program.
  • Avoid _KEEP when the rule depends on variables: a cached YES applies to the same action and subject even if the variables differ.
  • Use spawn() sparingly: helpers run as the polkitd user, block other checks while running and are killed after 10 seconds; rules running longer than 15 seconds are killed.
  • Name files deliberately: a rule that must run first goes in /etc/polkit-1/rules.d with a low prefix such as 00-; use two-digit prefixes throughout so ordering is visible.

Integrations, API tokens and service accounts

polkit is not only for humans at a desktop. Service accounts, agents and automation call D-Bus mechanisms too, and these non-human callers fall under allow_any.

  • Bind automation to its unit: the system_unit subject attribute identifies the systemd system unit of the caller, and no_new_privileges confirms the unit has NoNewPrivileges= set. Upstream's example allows user administration only for processes in admin.service that cannot gain new privileges. System units need root to create, unlike user units, so this binding is meaningful.
  • Prefer unit identity over user name: a rule keyed on a service account's user name applies to any process running as that user, including an interactive shell an attacker obtains with its credentials. See the Linux Service Accounts and Keytab Management Guide.
  • Configuration management: Ansible, Puppet or similar tools that deploy rules files hold the power to rewrite authorisation. Protect their credentials and review rule changes like sudoers changes.
  • Query delegation: by default only root can ask whether a different user's process is authorised; the org.freedesktop.policykit.owner annotation lets a named system user do so, for daemons that run as non-root.
  • Meta actions: the org.freedesktop.policykit.imply annotation authorises a list of other actions together. Review implied action lists when granting an umbrella action.

Logging and detection

polkitd logs to the system journal, and polkit.log() in rules writes with LOG_AUTHPRIV, which usually lands in /var/log/secure or the auth log. Collect both centrally. See the Linux Logging and auditd for Defenders Guide.

SignalSourceWhy it mattersATT&CK
Execution of /usr/bin/pkexec, especially with an empty or unusual argument list or from a web or service accountauditd execve watch on pkexec; EDR process eventsPwnKit-style exploitation and abuseT1068, T1548.001
Writes to rules or action directoriesauditd file watches on /etc/polkit-1/, /usr/share/polkit-1/, /run/polkit-1/; file integrity monitoringNew rule granting YES is a quiet persistence pathT1548
Temporary authorisations granted to unexpected userspolkitd journal entriesShows who satisfied auth prompts and for which actionT1548
Service management actions from non-admin userssystemd and logind journal, polkit authorisation logsDelegated units used outside intentT1543.002
Changes to wheel or sudo group membershipauditd on /etc/group; directory logsExpands who counts as adminT1098
Remote sessions marked activeloginctl session data, logind journalallow_active privileges reachable over SSH (CVE-2025-6018 pattern)T1068

Metrics

  • pkexec presence: share of servers where pkexec is removed or not setuid. Target 100% of servers without a documented need.
  • Patch latency: days from a polkit, udisks or related advisory to full deployment. CVE-2021-4034 is in the CISA Known Exploited Vulnerabilities catalogue with known ransomware use, so treat polkit fixes as urgent.
  • Custom rule inventory: number of rules files outside vendor packages, each with an owner and review date.
  • Unauthenticated grants: count of rules or overrides returning YES for privileged action namespaces. Target zero on servers.
  • Admin identity count: users who satisfy auth_admin per host class, reviewed with sudoers.

Hardening baseline

Servers and desktops differ

AreaServer baselineDesktop baseline
pkexecRemove the package or the setuid bit unless requiredKeep patched; default auth_admin
allow_any for privileged actionsno or auth_adminauth_admin
allow_activeLargely irrelevant if no local console users; confirm SSH sessions are never activeConvenient defaults acceptable for the single local user; avoid on shared machines
Disk, network and package mechanisms (udisks, NetworkManager, PackageKit)Remove the services if unusedRestrict to the local active user
SUSE profilerestrictivestandard (easy only for single-user machines where the user is the administrator)
Custom rulesDelegation bound to system units and specific actionsFew or none

Rollout

  1. Inventory: run pkaction to list actions, list all .rules files in the four rules directories with their package ownership, and record admin rule identities and pkexec setuid status per host.
  2. Patch: confirm polkit, udisks and libblockdev packages include fixes for CVE-2021-4034, CVE-2021-3560 and CVE-2025-6019, and on SUSE 15 the PAM fix for CVE-2025-6018. Set user_readenv=0 for pam_env, the default from Linux-PAM 1.4.0.
  3. Reduce: remove pkexec setuid and unused mechanisms on a pilot ring of servers; watch for broken automation for two weeks.
  4. Tighten: add a low-numbered rule that logs (with polkit.log()) and returns AUTH_ADMIN for sensitive namespaces on servers, test with pkcheck and real workflows, then switch to NO where nothing breaks.
  5. Monitor: deploy auditd watches on rules directories and pkexec, and forward polkitd and authpriv logs to the SIEM.
  6. Roll back: rules are files; removing or renaming the new .rules file takes effect immediately because polkitd watches the directories. Restore pkexec permissions from the package (rpm --setperms or reinstalling) if a dependency appears. On SUSE, restore defaults by selecting the profile, clearing .local overrides and rerunning set_polkit_default_privs.

Framework mapping

ControlNIST SP 800-53 Rev. 5NIST CSF 2.0CIS Controls v8.1ISO/IEC 27001:2022
Restrictive defaults, narrow delegationAC-6, AC-6(1)PR.AA-055, 6A.8.2
Remove pkexec and unused mechanismsCM-7, CM-7(5)PR.PS-014A.8.9
Patch polkit and related servicesSI-2PR.PS-027A.8.8
Protect rules filesCM-5, SI-7PR.PS-014A.8.9
Log privileged actionsAU-2, AC-6(9)DE.CM-098A.8.15

In MITRE ATT&CK v20, polkit abuse maps mainly to T1548 Abuse Elevation Control Mechanism, T1548.001 Setuid and Setgid for pkexec, and T1068 Exploitation for Privilege Escalation for flaws such as CVE-2021-4034 and CVE-2021-3560.

Common misconfigurations

  • Unpatched pkexec on servers: PwnKit gave any local user root on default installs of major distributions; web shells and compromised service accounts are local users. Red Hat rated it CVSS 7.8 and published a SystemTap workaround for systems that could not update at once.
  • Trusting identity lookups blindly: CVE-2021-3560 came from polkit treating a failed D-Bus UID lookup as UID 0, affecting polkit 0.113 and later until the June 2021 fix. Old base images still carry it.
  • Remote users treated as local: on openSUSE Leap 15 and SUSE Linux Enterprise 15, CVE-2025-6018 let an SSH user be treated as allow_active through ~/.pam_environment, opening desktop privileges such as udisks operations used in CVE-2025-6019.
  • Catch-all rules: a rule returning YES for any action when the user is in an admin-like group, often added to "stop the password prompts", turns group membership into silent root.
  • Editing vendor policy files: changes to /usr/share/polkit-1/actions are overwritten by updates and hide intent; SUSE explicitly advises writing your own policy and rules instead.
  • Reviewing sudoers only: privileged access reviews that ignore polkit admin rules and custom rules miss a full second path to root-level actions.

Practitioner checklist

  • polkit, udisks, libblockdev and PAM packages are patched for CVE-2021-4034, CVE-2021-3560, CVE-2025-6018 and CVE-2025-6019 where applicable.
  • pkexec is removed or not setuid on servers that do not need it.
  • Every custom .rules file is in configuration management, owned, reviewed and named with a two-digit prefix.
  • No rule returns YES for systemd, login, udisks, NetworkManager, accounts or PackageKit namespaces on servers without an exact action and unit match.
  • Admin identities from addAdminRule and the wheel or sudo group are included in privileged access reviews.
  • Delegation to automation uses system_unit and no_new_privileges rather than user names.
  • SSH sessions are confirmed never to be marked active; pam_env has user_readenv=0.
  • auditd watches cover pkexec execution and writes to polkit rules and action directories, with logs in the SIEM.
  • SUSE hosts use the restrictive profile on servers and keep overrides in /etc/polkit-default-privs.local.

Standards and references

Related NHI Mgmt Group resources: Linux Privilege Escalation Techniques Guide · sudo and sudoers Security Guide · Linux Server Hardening Guide · Linux Capabilities Guide · SELinux Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org