From 656bea2b20c4614537683079836117d320e31657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Bene=C5=A1?= Date: Fri, 7 Aug 2026 15:25:44 +0200 Subject: [PATCH] What the audit is worth keeping, and where Five passes produced a working document that said on its first line it was temporary. This is it being spent rather than abandoned. CLAUDE.md gains eleven paragraphs, each a thing that had shipped looking correct: a handler bound to a shared variable rather than its own socket, a script the base template already loads being loaded again, a control that stays clickable while it awaits permission, "is this name taken?" asked about visibility instead of ownership, root running a file the service account can write, sourcing anything under $PREFIX, a read-only command name that is not a read-only command, 0.0.0.0 being this machine, a folder that is not a label, a file that is not deleted by the row that named it, and a measuring harness that measured an unstyled page and reported a dramatic finding that was entirely an artefact. PLAN.md carries the seven things the audit found and deliberately did not fix, each with why: they change what something does rather than fix what it claims to do, which is not an audit's job. deploy/README.md says why root runs a copy, and that a host installed before this keeps the old wiring until the installer is re-run -- the button cannot fix it, because the button runs the old unit. docs/notes/audit-0.9.md is deleted, having been all three. Co-Authored-By: Claude Opus 5 (1M context) --- deploy/README.md | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index 1b85797..c91a7a6 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -95,19 +95,40 @@ The button is opt-in, and the reason is a boundary rather than caution: INSTALL_UPDATE_HELPER=1 SITE_HOST=chat.example ./deploy/install.sh ``` -That installs `lembas-update.path` and `lembas-update.service`. The web +That installs `lembas-update.path` and `lembas-update.service`, and puts a +**root-owned copy** of `update.sh` at `/usr/local/lib/lembas/update.sh`. The web interface writes `$PREFIX/data/update-requested`; the path unit notices and the -service runs `update.sh` **as root**, on the configured channel. +service runs that copy **as root**, on the configured channel. + +**Why a copy.** The unit used to point inside the checkout, and `install.sh` +clones the checkout *as the service user* — so root was executing a file the +unprivileged account could rewrite, and one that every update replaces with +whatever the branch contained. Either turns a compromise of the web application +into root, and the second needs no compromise at all. The cost is that changing +`update.sh` needs the installer re-run; the script tells you when its copy has +fallen behind, and says so loudly if it finds itself running from inside the +checkout. + +**If you installed the helper before 1.0.0, re-run the installer.** The old +wiring stays until you do, and the update button cannot fix it — the button runs +the old unit. **What that grants.** Anybody who can administer this web interface can then deploy whatever is on the configured branch and restart the service. That is the point of it, and it is why it is not the default. **What it deliberately does not grant.** The request file carries nothing that -reaches a command line — no ref, no branch, no channel, no arguments. Both are -baked into the unit at install time, so the button is always "deploy the channel -this host was configured with" and never "deploy something else". Re-running the installer without the flag removes both units and the -marker, and the page goes back to printing the manual command. +reaches a command line — no ref, no branch, no channel, no arguments, and its +*contents* are never read at all. Both are baked into the unit at install time, +so the button is always "deploy the channel this host was configured with" and +never "deploy something else". Re-running the installer without the flag removes +both units, the marker and the root-owned copy, and the page goes back to +printing the manual command. + +A re-run **keeps the channel this host already follows** rather than resetting it +to `stable`: the channel is declared in `lembas.env` and in the unit, a re-run +keeps the first while rewriting the second, and an installer that silently moved +one half was causing exactly the mismatch the Updates page detects. Without the helper the page says so and shows `sudo …/deploy/update.sh`, which is the same honest degradation the SSH and search extras have.