max / alloy
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
- Claude-Session
- https://claude.ai/code/session_01WFBzMprSmNCfvdj2cGZyka
1 file changed,
+20 insertions,
-14 deletions
| @@ -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 |