Principe général
Polkit est un framework d’autorisation : une spécification + une bibliothèque (libpolkit) + un démon (polkitd).
Il opère sur les systèmes Unix/Linux dont le principe est de fournir une « API d’Autorisation ».
Il contrôle le franchissement de la frontière (la séparation des privilèges imposée par le noyau (UID, permissions)) entre processus non privilégiés et privilégiés.

Polkit est destiné à être utilisé par les programmes dits privilégiés (« Mechanism »), en offrant des services aux programmes non-privilégiés (« Subject »).
Mechanism (libpolkit-gobject-1)
Ce rôle « Mechanism » traite toutes les demandes des « Subject » comme non fiable.
A chaque demande, il doit déterminer si la demande du « Subject » est autorisée ou s’il doit refuser de traiter le sujet. Pour cela, il peut (via l’API polkit) décharger cette tâche à l’autorité Polkit (polkitd).
L’autorité Polkit (polkitd – org.freedesktop.PolicyKit1)
Cette autorité polkit fonctionne en tant que démon système (polkitd). Ce démon a peut de privilège, et s’exécute avec l’utilisateur système polkitd. Les Mechanism, Subject et les agents d’authentification communiquent avec l’autorité polkit en utilisant le bus de messages système (system message bus).
[Unit]
Description=Authorization Manager
Documentation=man:polkit(8)
[Service]
Type=notify-reload
BusName=org.freedesktop.PolicyKit1
CapabilityBoundingSet=CAP_SETUID CAP_SETGID
DeviceAllow=/dev/null rw
DevicePolicy=strict
ExecStart=/usr/lib/polkit-1/polkitd –no-debug –log-level=notice
User=polkitd
LimitMEMLOCK=0
LockPersonality=yes
MemoryDenyWriteExecute=yes
NoNewPrivileges=yes
PrivateDevices=yes
PrivateNetwork=yes
PrivateTmp=yes
ProtectControlGroups=yes
ProtectHome=yes
ProtectKernelModules=yes
ProtectKernelLogs=yes
ProtectKernelTunables=yes
ProtectSystem=strict
ProtectClock=yes
ProtectHostname=yes
RemoveIPC=yes
RestrictAddressFamilies=AF_UNIX
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
SystemCallArchitectures=native
SystemCallFilter=@system-service
UMask=0077
Mitigate memory leaks
MemoryMax=32M
MemorySwapMax=32M
OOMPolicy=stop
Restart=on-failure
Architecture
Version simplifiée :

Exemple de fonctionnement :
Tu branches une clé USB sur ton Fedora et tu cliques « monter » dans Dolphin.
Problème : monter un disque exige des privilèges root, mais Dolphin tourne avec ton UID.
Deux mauvaises solutions historiques :
- rendre le binaire setuid root (dangereux : tout le programme devient privilégié),
- ou demander le mot de passe root à chaque fois (invivable).
La solution polkit : séparer celui qui demande de celui qui agit, et confier la décision à un arbitre.
- Le sujet : ton processus non privilégié (Dolphin).
- Le mécanisme : un démon déjà privilégié qui sait faire l’action (ici udisks2, qui tourne en root).
- L’arbitre : polkitd, qui répond à une seule question : « ce sujet a-t-il le droit de faire cette action ? »
Les deux familles de fichiers
Les déclarations : /usr/share/polkit-1/actions/*.policy (XML). Chaque mécanisme y déclare ses actions (ex. org.freedesktop.udisks2.filesystem-mount) avec leurs implicit defaults, trois champs qui répondent « que faire si aucune règle ne tranche ? » selon le contexte du sujet :
allow_any: n’importe quel contexte (ex. session SSH distante) ;allow_inactive: session locale mais non active (autre TTY au premier plan) ;allow_active: session locale active (tu es physiquement devant l’écran — information fournie par systemd-logind).
C’est pourquoi monter une clé USB est souvent gratuit en local (allow_active = yes) mais demande un mot de passe en SSH. On ne modifie jamais ces fichiers : ils appartiennent aux paquets.
Les décisions : les fichiers .rules (JavaScript, norme ECMA-262 édition 5). Les règles vivent dans /etc/polkit-1/rules.d (administrateur) et /usr/share/polkit-1/rules.d (paquets systèmes), lues en ordre lexical de nom de fichier. Exemple minimal exécutable — autoriser le groupe admin_reseau à gérer les unités systemd sans mot de passe :
// /etc/polkit-1/rules.d/49-reseau.rules
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
subject.isInGroup("admin_reseau")) {
return polkit.Result.YES;
}
});
Sémantique cruciale : retourner une valeur (YES, NO, AUTH_SELF, AUTH_ADMIN, variantes _KEEP) est final ; retourner null (ou rien) passe à la règle suivante. Si toutes les règles rendent null → implicit defaults du .policy.
Distinction :
auth_self = le sujet prouve son identité avec son propre mot de passe ;
auth_admin = il faut le mot de passe d’un administrateur. Qui est « administrateur » ? C’est défini par une règle (polkit.addAdminRule) — par défaut le groupe wheel sur Fedora, sudo sur Debian/Ubuntu (dépendant de la distribution). Le suffixe _keep met le verdict en cache environ 5 minutes.
L’agent d’authentification
L’agent est un programme dans la session en cours (polkit-kde-agent sous KDE, intégré à gnome-shell sous GNOME, pkttyagent en console) qui s’enregistre auprès de polkitd. Quand le verdict est auth_*, polkitd demande à l’agent d’afficher la boîte de dialogue ; l’agent vérifie le mot de passe via PAM et rapporte à polkitd. Symptôme classique quand aucun agent ne tourne (session i3, TTY nu) : l’action échoue avec « No authentication agent found » alors que la règle est correcte.
pkexec, l’exception qui élève (un composant de sécurité devenu vecteur d’attaque.)
pkexec est l’outil livré avec polkit qui, lui, exécute un programme en tant qu’autre utilisateur (root par défaut) — c’est un binaire setuid, l’équivalent polkit de sudo. C’est l’exception à « l’UID ne change pas » : ici le but est le changement d’identité.
Note de sécurité pertinente : CVE-2021-4034 « PwnKit » (janv. 2022), une corruption de argv dans pkexec exploitable en élévation de privilèges locale root, présente ~12 ans dans le code et activement exploitée.
Versions et implémentations
≤ 0.105 : règles déclaratives .pkla (« local authority ») — Debian l’a conservé longtemps ; les distributions actuelles sont toutes passées aux .rules JS.
≥ 0.106 : moteur JavaScript embarqué. Historiquement SpiderMonkey/mozjs (lourd) ; depuis ~0.120/121, polkit peut être compilé avec duktape, un moteur JS compact — le choix mozjs/duktape est une option de compilation de la distribution. Conséquence pratique : n’utilise que du JavaScript ES5 dans tes règles, le moteur peut changer.
Après 0.120, le schéma de version a changé : 121, 122, … (Fedora récent embarque une version ≥ 124).
Exemple de règles polkit
Github :
Assisted-by-IA(Fable 5)