Skip to main content

max / alloy

Correct what the wifi join actually asks for, measured on a booted install CONSOLE.md said joining a new network needs a polkit answer every time, because the shipped rule deliberately does not grant settings.modify.system. Measured on fw12 (Alloy 0.1, build 20260907.211740) with build/check-installed.sh --policy: it reads allow_active=yes, so on a local seat the join is answered without asking, and no rules file makes it stricter. 50-alloy-settings.rules already recorded that value in its own header and CONSOLE.md disagreed with it. The stdin argument for tier 3 is untouched, because it was never a privilege argument: argv is world-readable, nmcli --ask wants a pipe, and a suspended child has no pipe left. What the passage claimed wrongly is that this one action forced the agent. Its callers are the rpmostree1 rows, which read auth_admin_keep, and a join over SSH, which is not an active local session.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session
https://claude.ai/code/session_01WFBzMprSmNCfvdj2cGZyka
Author: Max Johnson <me@maxj.phd> · 2026-09-08 17:36 UTC
Signed with PGP, not checked
Commit: e2a9bef4afb71db001ad4e846def356bcea022f9
Parent: 961f4ad
1 file changed, +20 insertions, -14 deletions
M docs/CONSOLE.md +20 -14
@@ -144,21 +144,27 @@
144 144 need no privilege at all, which is a fact rather than a design: NetworkManager's shipped
145 145 policy grants `network-control` and `enable-disable-wifi` to an active session outright.
146 146
147 - Joining a *new* network is `settings.modify.system`, which the shipped rule deliberately
148 - does not grant, so it needs an answer every time. The screen asks three questions in three
149 - modes — which device, which network in range, what is the passphrase — and Esc walks back
150 - through them. The passphrase is never an argument: `nmcli --ask` prompts for it and reads
151 - the prompt from stdin, so it does not appear in `ps` for every user on the machine the way
152 - `device wifi connect SSID password PW` would.
147 + Joining a *new* network is `settings.modify.system`, and on a local seat that is answered
148 + without asking. NetworkManager's shipped policy already reads `allow_active=yes` for it, so
149 + there is nothing for Alloy's rules file to grant; `50-alloy-settings.rules` says so in its
150 + own header, and `build/check-installed.sh --policy` is the check. The screen asks three
151 + questions in three modes, which device, which network in range, what is the passphrase, and
152 + Esc walks back through them. The passphrase is never an argument: `nmcli --ask` prompts for
153 + it and reads the prompt from stdin, so it does not appear in `ps` for every user on the
154 + machine the way `device wifi connect SSID password PW` would.
153 155
154 - That one action is what forced tier 3 of wiki `alloy-privilege`, because tier 2 cannot
155 - reach it. Tier 2 answers polkit by suspending the console and running the command under
156 - `pkttyagent`; a suspended child inherits the terminal's stdio, so there is no pipe left to
157 - carry the passphrase on, and a secret and a suspend cannot both be had. So the join runs
158 - beside the event loop with an authentication agent the console registers for its own
159 - process, and polkit's question arrives as a modal in Akari naming the action. The PAM
160 - conversation is still polkit's own setuid helper — Alloy supplies the cookie, draws the
161 - prompt, and hands back what was typed, and decides nothing about whether it was right.
156 + That stdin requirement is what tier 2 of wiki `alloy-privilege` cannot serve, and the
157 + constraint is stdio rather than privilege. Tier 2 answers polkit by suspending the console
158 + and running the command under `pkttyagent`; a suspended child inherits the terminal's
159 + stdio, so there is no pipe left to carry the passphrase on, and a secret and a suspend
160 + cannot both be had. So the join runs beside the event loop with an authentication agent the
161 + console registers for its own process, and polkit's question arrives as a modal in Akari
162 + naming the action. What that agent is worth is the actions that do prompt: every
163 + `rpmostree1` row reads `auth_admin_keep`, so `alloy pkg` and `alloy update` ask, and a join
164 + over SSH asks too, because an SSH login is not the active local session the vendor policy
165 + grants to. The PAM conversation is still polkit's own setuid helper: Alloy supplies the
166 + cookie, draws the prompt, and hands back what was typed, and decides nothing about whether
167 + it was right.
162 168
163 169 `alloy disk` is the one pane that rewrites a partition table, and the only place
164 170 in the console where a keypress can destroy data that was not already being