Make changing engine-run code superuser-only

Writing node source, installing modules and any flow save that adds,
retypes or repoints a code node (Function, Command), edits a Command
node's settings or changes a node's resources.env now answer 403 for
everyone but a superuser. MCP tools and the assistant reach the same
routes, so they inherit the gate. Node types report runs_code.

The editor shows code read-only with a note, disables a Command node's
settings, leaves code nodes and reusable nodes out of the palette and
paste, and the Modules page offers no install.
This commit is contained in:
2026-10-06 11:36:30 +02:00
parent 2914d860b1
commit 6802cd2203
19 changed files with 391 additions and 26 deletions
+7 -1
View File
@@ -62,6 +62,12 @@ curl -X PUT $FLUKSIO/flows/house/nodes/decide/source -H "Authorization: Bearer $
-H 'Content-Type: application/json' -d '{"code": "def process(x):\n return {\"y\": x * 2}\n"}'
```
Writing a source is a superuser's, and so is any `PUT /flows/{name}` that
adds a Function or Command node, retypes or repoints one, changes a Command
node's settings, or changes any node's `resources.env`: each of them is code
the engine runs. Anyone else gets a 403 and keeps the rest — wiring, titles,
a Function node's settings and every other node.
`POST .../share` promotes a node's source to the shared library;
`POST .../unshare` gives it a private copy back. `GET /flows/library` lists the
shared sources and which flows use each.
@@ -197,7 +203,7 @@ curl -X POST $FLUKSIO/alerts/test/my-phone -H "Authorization: Bearer $TOKEN"
```
Secrets are write-only over the API: you can list names and set values, never
read one back.
read one back. Secrets and `POST /modules/apply` are a superuser's.
## Observability
+2
View File
@@ -297,6 +297,8 @@ helper a node calls into is reported as that node changing (`train: updated
(flow, fit)`) and re-runs it, while editing something the node never reaches
is left alone.
Uploading node code takes a superuser's token; anyone else's sync is refused.
A sync that changed nothing says `unchanged`, which is the answer worth
having. `published` and `draft` are said only when there was something to
publish or a draft was genuinely left behind. An engine too old to store what
+4
View File
@@ -80,6 +80,10 @@ reloads without the flow stopping. A node file defines `process(...)`; if it
defines exactly one public function under another name, that one is used
instead.
Code runs as the engine, so changing it is a superuser's. Anyone else sees the
editor read-only, a Command node's settings disabled, and no Function, Command
or reusable nodes to add.
**Shared** turns a node's code into a library entry other flows can reuse.
Editing a shared node edits the copy every flow using it runs, which is the
point and also the caution.
+3 -2
View File
@@ -39,7 +39,8 @@ Node code runs in a virtual environment of its own, on the instance's data
volume, separate from the packages Fluksio itself runs on. A pin of yours can
never shadow one of ours, and vice versa.
**Modules** is a pip manifest and an **Apply** button. It is installed with
**Modules** is a pip manifest and an **Apply** button, which only a superuser
sees: a package runs its own code on install. It is installed with
`uv pip sync`, so a line you delete is uninstalled rather than left behind.
The manifest is versioned alongside your flows, so what a deployment installed
is recorded with what uses it.
@@ -114,7 +115,7 @@ is a superuser.
Accounts that arrived through a portal are badged *Portal*. They have no
password (they sign in at the portal, not here) and they are never
superusers. Deleting one cuts their access immediately and independently of the
superusers, so they read node code but cannot change it. Deleting one cuts their access immediately and independently of the
portal, so it works even if the portal cannot be reached. See
[Accounts and the portal](portal.md).
+1
View File
@@ -244,6 +244,7 @@ The cheapest fix for a sensor that reports every second and changes every hour.
### Command
**`exec`** — run a command in the engine's container and read its output.
Adding one or changing its settings is a superuser's, since the command is code.
| Setting | Default | Notes |
|---|---|---|