Watch
0
0
Fork
You've already forked hyperhive
0

hive-gateway: keep matrix discovery on the hive domain of a homeserver host without a hive

The hive-domain vhost renders where a hive or the homeserver runs. Its
matrix .well-known JSON and /matrix/ redirect are served wherever the
homeserver runs; the dashboard, swagger UI, agent routes and the
agents.conf include only where a hive runs, since they proxy to hive-c0re.

The gateway doc's vhost map says which rows exist without a hive, and the
trust-bundle text describes ca.pem by what it is rather than as retired.

Refs #4588
This commit is contained in:
atlas 2026-10-04 17:58:16 +02:00 • committed by mara
commit 3e1ac4e678
5 changed files with 91 additions and 51 deletions

View file

@ -21,14 +21,14 @@ You rarely switch it on yourself. `gateway.enable` defaults to off, and every mo
| `chat.<swarm>/config.json` | inline JSON (FluffyChat boot config) | `hive-matrix.nix`, `swarm.matrix.gatewayHost != null` |
| `grafana.<swarm>`, `metrics.<swarm>`, `logs.<swarm>`, `otel.<swarm>`, `bao.<swarm>` | the matching swarm service | that service's module → [`swarm/services.md`](../swarm/services.md) |
**The hive's own vhost**, named for the hive domain:
**The hive domain's own vhost**, named for the hive domain. It renders where a hive runs (`deploy.hive-controller.enable`) or the homeserver does (`deploy.matrix.enable`); on a host with neither there is no such vhost. On a host without a hive only the two matrix rows exist:
| URL | upstream | when |
| --- | --- | --- |
| `<hive>/` | dashboard dist (static, from `servedFrontend`) | always |
| `<hive>/api/`, `/health/` | hive-c0re (`7000`) | always |
| `<hive>/api/docs/` | themed Swagger UI dist (static) | always |
| `<hive>/agent/<name>/` | per-agent harness over its unix socket | `agents.conf` (runtime-generated) |
| `<hive>/` | dashboard dist (static, from `servedFrontend`) | `deploy.hive-controller.enable` |
| `<hive>/api/`, `/health/` | hive-c0re (`7000`) | `deploy.hive-controller.enable` |
| `<hive>/api/docs/` | themed Swagger UI dist (static) | `deploy.hive-controller.enable` |
| `<hive>/agent/<name>/` | per-agent harness over its unix socket | `deploy.hive-controller.enable`; `agents.conf` (runtime-generated) |
| `<hive>/.well-known/matrix/{client,server}` | inline JSON | `deploy.matrix.enable` |
| `<hive>/matrix/` | 301 → `chat.<swarm>/` | `deploy.matrix.enable` and `gatewayHost` set |
@ -80,7 +80,7 @@ The issuer is the **secret store's `pki` mount**, not a bare self-signed leaf. `
**Why an issuer, not a bare leaf**: a bare self-signed leaf is its own trust anchor, so every regeneration is a new anchor every consumer must re-trust, and an agent's build sets its trust store once, before any leaf exists. Agents and federation peers trust the store's root once; leaf rotation never breaks them.
**What consumers trust**: `trust-bundle.pem` in the same state dir. It carries the store's `pki` root, plus the retired hive CA's public `ca.pem` and the swarm root where they exist ([`swarm/ca.md`](../swarm/ca.md#the-trust-bundle)). nginx serves the leaf alone, since its issuer is a self-signed root. Agents (via `security.pki.certificateFiles`), the CI and forge containers and federating peers all read the bundle.
**What consumers trust**: `trust-bundle.pem` in the same state dir. It carries the store's `pki` root, plus a hive CA's public `ca.pem` and the swarm root where they exist ([`swarm/ca.md`](../swarm/ca.md#the-trust-bundle)). nginx serves the leaf alone, since its issuer is a self-signed root. Agents (via `security.pki.certificateFiles`), the CI and forge containers and federating peers all read the bundle.
**Why on by default**: matrix-dart-sdk (FluffyChat's SDK) fetches `https://<host>/.well-known/matrix/client` and never falls back to plain http, so without TLS the browser client can't bootstrap.

View file

@ -49,8 +49,8 @@ identity a swarm service uses.
`hive-tls-resign.timer` once a day. It asks the store for a new leaf when
the current one is missing, past half the role's 720-hour lifetime, missing
a configured name, doesn't match the key beside it, or doesn't chain to the
store's root (`swarm-services-root.pem`). That last check is what replaces a
leaf the retired hive CA signed, on the first run that reaches the store.
store's root (`swarm-services-root.pem`). The first run that reaches the
store replaces a leaf that doesn't chain to that root, whoever signed it.
**The gateway doesn't wait for the store.** Nothing orders the gateway after
`hive-tls-resign.service`, so a hive holding a valid leaf starts its gateway
@ -65,8 +65,9 @@ self-signed root a consumer already holds in its trust bundle.
**A gateway host that runs no hive** (`deploy.hive-controller.enable` off,
such as a dedicated swarm-services or secret-store host) has no hive leaf, no
`hive-tls-resign.service`, no hive identity and no hive-domain vhost. Its
gateway serves the swarm-services leaf as its default certificate too. Where it
`hive-tls-resign.service`, no hive identity and no dashboard or agent routes;
its hive-domain vhost exists only to serve matrix discovery where the
homeserver runs there. Its gateway serves the swarm-services leaf as its default certificate too. Where it
fronts other swarm names it waits for `swarm-services-cert.service` at start.
Where the store's UI is its only swarm name it starts on a throwaway
self-signed certificate and switches to the services leaf once the store
@ -79,16 +80,16 @@ the file every consumer anchors on. It holds whichever of these exist:
- `swarm-services-root.pem`, the store's `pki` root, which the gateway leaf
and the swarm-services leaf both chain to.
- `ca.pem` and `ca-previous.pem`, the retired hive CA's public certificates,
so a leaf it signed keeps verifying until it's replaced. Removing them is a
deliberate later step.
- `ca.pem` and `ca-previous.pem`: a hive CA's public certificates. Nothing
issues under that CA; they stay in the bundle so a leaf it signed verifies
until `hive-tls-resign` replaces it. Removing them is a deliberate later
step.
- the swarm root, `<swarm.ca.stateDir>/root.pem`, on the host that generates
it.
No hive generates a CA or signs with a CA key. A
`<deploy.hive-controller.tls.stateDir>/ca-key.pem` an earlier generation left
stays on disk, unread: removing it comes with dropping `ca.pem` from the
bundle.
`<deploy.hive-controller.tls.stateDir>/ca-key.pem` stays on disk, unread:
removing it comes with dropping `ca.pem` from the bundle.
⚠️ **A consumer reads its trust when it starts.** An agent or service
container that last started before the store's root reached the bundle