This commit is contained in:
2026-10-13 10:02:20 +02:00
parent a93f865e91
commit 80e595c02e
24 changed files with 2210 additions and 4310 deletions
+65 -98
View File
@@ -1,139 +1,106 @@
# Secrets, modules and alerts
Three screens that have nothing to do with each other except that an
instance you actually depend on needs all of them.
Store credentials, manage node dependencies and choose where failures go.
These screens help keep an instance humming.
## Secrets
A node never holds a credential. A parameter written as
Open **Secrets** as a superuser, then add a name and value. The list shows
names only; saved values are not displayed again.
Reference a secret from a node setting:
```json
{"$secret": "influx-token"}
```
is replaced with the stored value when the node is built, and the editor
renders any field a node type marks as a credential as a picker over what you
have stored.
Fluksio resolves it when building the node. Credential fields in the editor
offer a secret picker. Missing names produce an error on the affected node.
**Secrets** is where the values live. Add a name and a value; the value is
never shown again, and the list only ever shows names.
Secrets are encrypted with a key derived from `SECRET_KEY` and stored outside
the flow repository. Using references keeps credentials out of saved flows.
They are encrypted at rest with a key derived from the instance's
`SECRET_KEY`, and kept **outside** the flow repository. That matters because
flows are a git repository you may well push somewhere: what gets committed and
shared never contains a password.
!!! warning "Keep your encryption key"
A name that no longer resolves is a clear error on the node that wanted it
("No secret named 'x'; add it under Secrets") rather than a mysterious
authentication failure.
!!! warning "Rotating `SECRET_KEY`"
The secrets store is encrypted with a key derived from it. Change
`SECRET_KEY` and the store no longer decrypts. Re-enter the secrets, or
plan the rotation properly.
Changing `SECRET_KEY` makes existing secrets unreadable. Keep the old key
for re-encryption, or re-enter the secrets. Source installations include
`backend/scripts/rotate_secret_key.py` for rotating the secrets store.
## Modules
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** shows the Python environment used by node code, its installed
packages and Python version. There are two setups:
**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.
- **Managed environment:** Docker uses a separate node environment. A
superuser edits **Requirements** and presses **Apply**. Packages are synced
with `uv pip sync`; deleting a requirement removes it. The manifest is
versioned with the flows, and successful installs refresh the workers.
- **Adopted environment:** a fresh pip installation inside your own virtual
environment can use that environment for nodes too. Modules is read-only.
Install dependencies there with pip or uv, then sync or restart Fluksio.
The page shows what is currently installed, the interpreter's Python version,
and whether the manifest and the environment agree. A failed resolve comes back
as `uv`'s own output, in the pane, because that is the only thing anyone can
act on.
Set `NODE_VENV=managed` to request a separate environment. Installation
failures show the package manager's output on the page.
An install takes effect immediately: the worker processes pick up the new
interpreter state without the engine restarting.
!!! note "Big scientific stacks"
Installing torch into this venv works and is often the simplest thing. The
alternative, when you already have an environment you would rather not
duplicate, is to attach it as a worker: `fluksio-worker --python
/path/to/venv/bin/python`. See [Remote workers](../code/workers.md).
For an existing scientific environment on another machine, attach a worker
with `fluksio-worker --python /path/to/venv/bin/python`. See
[Remote workers](../code/workers.md).
## Alerts
Everything that goes wrong already travels the engine's event bus. Alerts is
where you say who hears about it.
Create a channel, choose events in a rule, and use **Test** to check delivery.
Enable alerts for the rules to send.
### Channels
| Kind | Settings |
| Kind | Destination |
|---|---|
| **ntfy** | server, topic, and a token for a protected topic |
| **SMTP** | an address to send to (the instance's mail settings do the rest) |
| **Webhook** | a URL to POST to |
| **Dashboard** | a message name a notification widget reads |
| **ntfy** | server and topic; optional token |
| **SMTP** | recipient address, using the instance's mail settings |
| **Webhook** | URL that receives a POST |
| **Dashboard** | declared message read by a Notification widget |
| **webpush** | browsers subscribed from the Alerts page |
Any channel setting may hold a `{"$secret": "name"}` reference instead of a
literal, so a webhook URL with a token in it does not sit in the config.
Channel settings may use `{"$secret": "name"}` references. Browser push also
needs notification permission and a secure browser context.
### Rules
A rule is a set of events and the channels they go to. **A rule with no events
ticked covers all of them**, including ones added in later versions, which is
usually what you want for the first rule you write.
A rule selects events and destination channels. Leaving all events unchecked
matches every supported alert event, including future additions.
| Event | Fires when |
| Event | Trigger |
|---|---|
| `node_error` | a node failed |
| `node_health` | a connection dropped |
| `flow_quarantined` | a flow crashed often enough that the engine stopped restarting it |
| `task_crashed` | a background task crashed |
| `engine_degraded` | the engine is struggling |
| `cascade_dropped` | work was given up on |
| `queue_unavailable` | the work queue is unreachable |
| `node_error` | a node fails |
| `node_health` | a connection goes down |
| `flow_quarantined` | repeated crashes stop a flow's background work |
| `task_crashed` | a background task crashes |
| `engine_degraded` | engine health degrades |
| `cascade_dropped` | the engine drops work |
| `queue_unavailable` | the work queue becomes unreachable |
**Test** sends one message through a channel so you find out it is misconfigured
now rather than at three in the morning.
Repeated faults are deduplicated with a 15-minute default cooldown.
Flapping connections are suppressed, and the engine caps alert dispatches at
ten per hour. A quiet channel may be cooling down; **Test** helps distinguish
that from a broken configuration.
### What it mostly does is not send
## Admin: users and clients
This is the part worth knowing before you decide it is broken:
Superusers use **Admin** to add, edit and remove accounts, and manage OAuth
clients for [agents](../code/agents.md).
- the same fault repeating is **one** alert, with a cooldown (15 minutes by
default per rule)
- a connection flapping is one story, not one alert per transition
- however bad it gets, **ten alerts an hour** is the ceiling
An engine that is genuinely on fire produces a handful of messages, not
thirty-six thousand.
## Admin: users
Superusers get an **Admin** screen: add, edit and remove accounts, and see who
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, 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).
The same screen manages OAuth clients, which is how [agents](../code/agents.md)
are registered.
Accounts admitted from a portal are marked *Portal*. They sign in through the
portal, have no local password and are not superusers. To block local access,
edit the account and clear **Is active?**. See [Accounts and the portal](portal.md).
## Settings
Your own account: name, email, password, and appearance (light, dark, or
follow the system).
Change your name, email, password and appearance under **Settings**.
**Remote access** is where an instance is paired with a portal, remote
users are admitted, and the link is cut again. That has [its own
page](portal.md).
**Remote access** manages enrollment and admitted users; see
[Accounts and the portal](portal.md).
**Assistant** turns on the chat that builds and edits flows: pick a provider,
paste a key, fetch the model list and choose one. The key is stored encrypted
on the instance and never shown again. One provider serves everyone who signs
in here, and until one is set nothing in the interface mentions the feature.
How the chat works, and what it may do, is on the [agents
page](../code/agents.md#the-assistant).
A superuser can configure **Assistant**: choose a provider, store its key,
fetch models and select one. The encrypted key is shared for assistant access
on this instance. The chat appears after configuration; see
[The assistant](../code/agents.md#the-assistant).