Files
punktfunk/packaging/linux/49-punktfunk-update.rules
T
enricobuehlerandClaude Fable 5 06a249e49f feat(host/linux): opt-in one-click updates — the pf-update root helper, group-scoped polkit grant, per-PM legs
The U2 leg of planning:host-update-from-web-console.md. A new dep-free root helper
(crates/pf-update) runs the distro package manager against the INSTALLED punktfunk
packages — apt (index refresh scoped to our list when present), dnf, rpm-ostree
(single-transaction re-resolve, reported staged), sysext (the proven signed-feed
updater), pacman only behind the explicit PACMAN_FULL_SYSUPGRADE opt-in — then the
run-the-binary gate, then a root-written result record. Zero attacker-influenceable
parameters end to end: fixed ExecStart oneshot (punktfunk-update.service), polkit rule
scoped to that one unit's start verb for the shipped-EMPTY punktfunk-update group
(joining it is the auditable opt-in; every postinst creates it, none populate it).
The host starts the unit, interprets the record (staged / nothing-newer-yet / changed),
and crosses its own restart on the same intent/reconcile machinery as the Windows leg.
Status now reports staged results and the opt-in hint.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 15:55:27 +02:00

22 lines
975 B
Plaintext

// Members of the `punktfunk-update` group may START exactly one unit: the punktfunk
// root-helper oneshot that updates the punktfunk packages (planning:
// host-update-from-web-console.md §7). The group ships EMPTY — joining it is the explicit,
// auditable opt-in for web-console-triggered updates:
//
// sudo usermod -aG punktfunk-update <your user>
//
// Scope notes: `verb == "start"` keeps stop/restart/enable out of the grant, and the unit
// name pin keeps every other unit out. The unit's ExecStart is fixed and parameterless, so
// this grant authorizes "run the system's normal update for the punktfunk packages" and
// nothing else.
polkit.addRule(function (action, subject) {
if (
action.id == "org.freedesktop.systemd1.manage-units" &&
action.lookup("unit") == "punktfunk-update.service" &&
action.lookup("verb") == "start" &&
subject.isInGroup("punktfunk-update")
) {
return polkit.Result.YES;
}
});