Watch
0
0
Fork
You've already forked hyperhive
0

render the matrix appservice registration from the store onto tmpfs

swarm-matrix-ctl appservice render now reads the registration's tokens
from the store and renders swarm.yaml under /run/swarm-matrix-appservice,
which tuwunel loads through LoadCredential. It mints a pair only when the
store answers and holds none; a host that has the old files stores their
pair once instead. A store that does not answer fails the unit and keeps
tuwunel down; sync starts it once the store answers.

Refs #4998 (item 3)
This commit is contained in:
atlas 2026-10-30 05:47:39 +01:00 • committed by mara
commit 3a4b0ffabf

View file

@ -125,11 +125,12 @@ creation doesn't depend on registration being open to anyone who learns
a token.
1. **`swarm-matrix-ctl appservice render`**, inside the `hive-matrix`
container and before tuwunel starts, renders the registration to
`/var/lib/swarm-matrix-appservice/swarm.yaml` (mode `0600 root:root`)
from the `as_token` and spec-required `hs_token` beside it. It mints
them only on a container that has none, and never reaches the store, so
a store outage can't keep the homeserver down.
container and before tuwunel starts, fetches the `as_token` and
spec-required `hs_token` from the store and renders the registration to
`/run/swarm-matrix-appservice/swarm.yaml` (mode `0600 root:root`) on the
container's tmpfs, so no token sits on disk. It mints a pair only when
the store answers and holds none. While the store doesn't answer, `render`
fails and retries, and tuwunel stays down.
2. **systemd `LoadCredential=`** copies the registration into
`/run/credentials/tuwunel.service/swarm-appservice.yaml`, owned by
tuwunel's dynamic user with mode `0400`, at service start. The source
@ -167,15 +168,17 @@ account with it.
The swarm secret store holds the registration's tokens, at
`swarm/controller/swarm-controller/matrix/appservice-registration`.
`swarm-matrix-ctl appservice render` renders the registration tuwunel
loads as a credential from the copy of them in the `hive-matrix`
container, before tuwunel starts and without the store.
`swarm-matrix-ctl appservice render` fetches them and renders the
registration tuwunel loads as a credential onto the `hive-matrix`
container's tmpfs, before tuwunel starts.
`appservice sync` runs beside tuwunel on a timer. The store's tokens win:
when they differ from the container's, it writes them there. It
when they differ from the rendered copy, it rewrites it. It
restarts tuwunel whenever the registration is newer than tuwunel's last
start, so the next run retries one that failed after writing. A store that holds none takes the container's
tokens with a create-only write, so a running swarm keeps its value, and
a container that has none mints a pair. `sync` then writes the `as_token`
start, so the next run retries one that failed after writing, and starts
one that failed because `render` couldn't reach the store. A store that
holds none takes the tokens an earlier version kept in
`/var/lib/swarm-matrix-appservice` with a create-only write, so a running
swarm keeps its value; the files stay, unused. A host with neither files nor stored tokens mints a pair. `sync` then writes the `as_token`
to `swarm/controller/swarm-controller/matrix/appservice-token`. No hive's
policy reaches either path: only matrix-ctl (which holds `create` and
`read` on the registration, and writes the token) and `swarm-controller`
@ -263,8 +266,8 @@ both are swarm-level operations.
<details><summary>Appservice identity</summary>
`swarm-matrix-ctl appservice render` renders the registration from the
container's copy of the appservice tokens before tuwunel starts, so every
boot has both halves, with the store up or down.
store's copy of the appservice tokens before tuwunel starts, so every
boot has both halves. With the store down or sealed, tuwunel waits for it.
<!-- vale write-good.Passive = NO -->
- **Access tokens live on the device that minted them.**