Watch
0
0
Fork
You've already forked hyperhive
0

docs(networking): fix round — argus review + audit E1/E2

observability.md: "Why two tiers" claimed the harness currently writes an
upstream token into the agent's own claude settings; that path was removed
with the direct-export mode it served (nix/agent-modules/otel.nix:56-63).
Reworded as the hypothetical the paragraph is actually making.

gateway.md: restored the agent-trust pointer to
/run/hive-ca/trust-bundle.pem in "Cert prompts" (hive-ca-trust.nix:41),
dropped by the earlier rewrite. Corrected the SPA-fallback section: only
the chat.<swarm> vhost uses the Accept-header map
(hive-matrix.nix:693-696); per-agent split mode uses file-existence
try_files (gateway_nginx.rs:93-134), not the same mechanism.

Refs #3902
This commit is contained in:
atlas 2026-10-01 23:53:27 +02:00
commit 54556e4661
2 changed files with 8 additions and 9 deletions

View file

@ -87,7 +87,7 @@ The issuer is a **host-held hive CA**, not a bare self-signed leaf. `hive-tls-ca
**Rotation**: `hive-tls-ca.service` re-signs the leaf when it's missing, within 30 days of expiry, or no longer covers the configured names, always under the same CA. It regenerates the CA only if missing or expired. To force a leaf rotation, delete `gateway.pem` under the state dir, restart the unit, then reload `nginx`.
**Cert prompts**: browsers warn once per host until you add the hive's `trust-bundle.pem` (the anchor, not the leaf) to the browser or OS trust store.
**Cert prompts**: browsers warn once per host until you add the hive's `trust-bundle.pem` (the anchor, not the leaf) to the browser or OS trust store. A container that needs to trust it for its own outbound TLS gets the bundle a different way, bind-mounted read-only at `/run/hive-ca/trust-bundle.pem` (`nix/host-modules/lib/hive-ca-trust.nix`).
### Operator-provided cert (`tls.certDir`)
@ -261,14 +261,12 @@ How the gateway does what the sections above describe. Read before changing `hiv
### SPA fallback (Accept-header pattern)
The per-agent UIs and the `chat.<swarm>` vhost serve a flutter/SPA bundle via the Accept-header pattern below. The dashboard instead routes by **path** — see [Dashboard: path-based routing](#dashboard-path-based-routing-not-accept-header) below. Two requirements collide:
The `chat.<swarm>` vhost (fluffychat) serves a flutter/SPA bundle via the Accept-header pattern below. Per-agent UIs solve the same two requirements differently, with file-existence `try_files` — see [Per-agent static frontend split](#per-agent-static-frontend-split). The dashboard routes by **path** — see [Dashboard: path-based routing](#dashboard-path-based-routing-not-accept-header) below. Two requirements collide for a vhost whose client-side router owns every route under `/`:
- hard-refresh on a sub-route must serve `index.html` (SPA's client-side router takes over after JS bootstrap)
- a non-navigation request that isn't an on-disk asset must NOT get HTML with the wrong content-type
Solution: an `nginx http`-context `map $http_accept $<name>_spa_target { ... }` keyed on the request's Accept header. Browser navigations (`Accept: text/html,...`) get `index.html`; everything else (`Accept: image/*`, `*/*`, `application/json`, `text/event-stream`, …) gets a sentinel nonexistent path, so `try_files $uri $<name>_spa_target <final>` falls through to `<final>`. No extension allowlist, no `if` block, no regex heuristics.
For matrix and per-agent static assets, `<final>` is `=404` (a missing asset is just missing).
Solution: an `nginx http`-context `map $http_accept $matrix_spa_target { ... }` keyed on the request's Accept header. Browser navigations (`Accept: text/html,...`) get `index.html`; everything else (`Accept: image/*`, `*/*`, `application/json`, `text/event-stream`, …) gets a sentinel nonexistent path, so `try_files $uri $uri/ $matrix_spa_target =404` falls through to a plain `404` — a missing asset is just missing. No extension allowlist, no `if` block, no regex heuristics.
#### Dashboard: path-based routing (not Accept-header)