docs: clear write-good.Passive hits in gateway/subagent/dashboard docs
Part of #4548 — rewriting the 353 hand-written-docs write-good.Passive hits so #4546 can flip the rule to error. This batch: docs/networking/gateway.md (27 hits), docs/tools/subagent.md (19), docs/web-ui/dashboard.md (18). Minimal, meaning-preserving rewrites to active voice only — no restructuring beyond what each flagged sentence needed. Genuine false positives (predicate-adjective state descriptions like "is required", "is broken", "is unchanged", adjectival past participles like "named buckets", and one quoted literal UI string) are left in place; the per-line reasoning is on the tracking issue. Note: docs/tools/forge-cli.md (37 hits, would have been the single biggest file) turned out to be generated from hive-forge's own clap help text (see hive-forge/src/main.rs's `MarkdownDocs` verb) — same category as the already-excluded hivectl-cli.md/swarmctl-cli.md, so it's untouched here. Flagged on #4548.
This commit is contained in:
parent
9fac33a026
commit
cb504f6863
3 changed files with 54 additions and 54 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# hive-gateway
|
||||
|
||||
This host's nginx fronts the hyperhive web surfaces running on it — next to hive-c0re, not in its own container: it shares the host netns anyway (see [Vhost map](#vhost-map) below), so containerizing it would buy no network isolation while costing a resolv.conf sync, a machine-bus reload, and three bind mounts. System-config (not meta-flake managed). Configured via `services.hyperhive.gateway.*` + per-subsystem opt-in flags in `services.hyperhive.{forge,matrix,...}`. `gateway.enable` and `gateway.dns.enable` are asserted by the modules that need them, so a host serving a vhost or resolving hive names gets them without an opt-in.
|
||||
This host's nginx fronts the hyperhive web surfaces running on it — next to hive-c0re, not in its own container: it shares the host netns anyway (see [Vhost map](#vhost-map) below), so containerizing it would buy no network isolation while costing a resolv.conf sync, a machine-bus reload, and three bind mounts. System-config (not meta-flake managed). Configured via `services.hyperhive.gateway.*` + per-subsystem opt-in flags in `services.hyperhive.{forge,matrix,...}`. the modules that need them assert `gateway.enable` and `gateway.dns.enable`, so a host serving a vhost or resolving hive names gets them without an opt-in.
|
||||
|
||||
## Vhost map
|
||||
|
||||
|
|
@ -151,7 +151,7 @@ as same-origin `/agent/<name>/…` URLs instead of the legacy direct
|
|||
`http://<host>:<container.port>/` TCP shape. The signal comes from
|
||||
`StateSnapshot.gateway_enabled`, sourced from the
|
||||
`HIVE_GATEWAY_ENABLED` env the c0re NixOS module now always sets
|
||||
(`services.hyperhive.gateway.enable` was removed — the gateway runs
|
||||
(`services.hyperhive.gateway.enable` no longer exists — the gateway runs
|
||||
unconditionally alongside hyperhive), so this is effectively always
|
||||
true; the `false` branch stays as a defensive fallback for the
|
||||
env being unset. Three render sites
|
||||
|
|
@ -166,15 +166,15 @@ frontend-side derivation.
|
|||
## TLS modes
|
||||
|
||||
The gateway always terminates TLS — self-signed is the implicit floor when
|
||||
nothing else is configured, so there is no http-only mode. Three modes,
|
||||
selected by which (if any) external TLS source is set:
|
||||
the operator configures nothing else, so there is no http-only mode. Three
|
||||
modes, selected by which (if any) external TLS source the operator sets:
|
||||
|
||||
⚠️ **One vhost class is exempt, so expect it during a TLS audit.** A vhost bound to loopback for a
|
||||
local consumer carries a single plain-HTTP listen and no TLS. `grafana-metrics`
|
||||
(`nix/host-modules/swarm-grafana.nix`) is the only one in the tree today: it listens on `127.0.0.1`
|
||||
alone and serves one `= /metrics` location from grafana's unix socket, for the collector on this
|
||||
host to scrape. Nothing off-host can reach it, so TLS there protects nothing. Every vhost with a
|
||||
routable name is covered by the modes below.
|
||||
host to scrape. Nothing off-host can reach it, so TLS there protects nothing. The modes below
|
||||
cover every vhost with a routable name.
|
||||
|
||||
| mode | config | cert source | `.well-known` scheme |
|
||||
|---|---|---|---|
|
||||
|
|
@ -209,7 +209,7 @@ Mutual exclusion: `tls.certDir` set together with `tls.acme.enable = true` fails
|
|||
|
||||
### Self-signed TLS (default)
|
||||
|
||||
On by default, and listens on `httpsPort` (default 443) on every routable vhost beside the plain-http `port` (default 80). (The loopback-only exception is named under *TLS modes* above.)
|
||||
On by default, and listens on `httpsPort` (default 443) on every routable vhost beside the plain-http `port` (default 80). (See the loopback-only exception under *TLS modes* above.)
|
||||
|
||||
The issuer is a **host-held hive CA**, not a bare self-signed leaf. A host service (`hive-tls-ca.service`, from the `hive-tls` module) generates a long-lived CA (`services.hyperhive.deploy.hive-controller.tls.caValidityDays`, default ~20y) under `services.hyperhive.deploy.hive-controller.tls.stateDir` (default `/var/lib/hive-tls`), then signs a gateway **leaf** (`leafValidityDays`, default 30d) with it. `hive-gateway-self-signed-cert` then imports the leaf into nginx's state dir (`/var/lib/hive-gateway/tls/{cert,key}.pem`).
|
||||
|
||||
|
|
@ -221,17 +221,17 @@ root:root`; nginx's pre-start `nginx -t` runs as the *nginx user*, so a
|
|||
**every cert path the nginx config names exists** — which is what the
|
||||
swarm-services fallback below is for.
|
||||
|
||||
**Why a CA, 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 a runtime-generated leaf can't be wired into an agent's build-time trust store at all. With a stable CA, agents and federation peers trust it *once*; leaf rotation never re-breaks them.
|
||||
**Why a CA, 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 nothing can wire a runtime-generated leaf into an agent's build-time trust store at all. With a stable CA, agents and federation peers trust it *once*; leaf rotation never re-breaks them.
|
||||
|
||||
**What consumers trust**: `trust-bundle.pem` in the same state dir, not `ca.pem`. The hive CA is itself issued under the swarm root ([`swarm/ca.md`](../swarm/ca.md) has the hierarchy), and an intermediate isn't a chain a verifier can terminate at — so the bundle carries the hive CA plus whatever it's rooted at. `hive-gateway-self-signed-cert` hands nginx the leaf with the hive CA appended for the same reason. Everything that trusts the hive's TLS reads the bundle: agents (via `security.pki.certificateFiles`), the CI and forge containers, and a federating peer.
|
||||
|
||||
**Why on by default**: matrix-dart-sdk (FluffyChat's SDK) hardcodes `https://<host>/.well-known/matrix/client` for homeserver discovery and refuses to fall back to plain http. Without TLS the browser client can't bootstrap.
|
||||
|
||||
**Cert shape**: leaf subject CN = bare hive domain; subjectAltName is `<hive>` plus wildcard `*.<hive>`, so all current and future sub-domain vhosts validate under the same leaf + the hive CA. A swarm service whose name is *not* under this hive's domain can't be added here — the hive CA is name-constrained to `<hive>`, and a violating SAN invalidates the whole leaf, not just that name. Those names get the swarm-services leaf instead ([`swarm/ca.md`](../swarm/ca.md)).
|
||||
**Cert shape**: leaf subject CN = bare hive domain; subjectAltName is `<hive>` plus wildcard `*.<hive>`, so all current and future sub-domain vhosts validate under the same leaf + the hive CA. You can't add a swarm service whose name is *not* under this hive's domain here — the hive CA is name-constrained to `<hive>`, and a violating SAN invalidates the whole leaf, not just that name. Those names get the swarm-services leaf instead ([`swarm/ca.md`](../swarm/ca.md)).
|
||||
|
||||
**Rotation**: `hive-tls-ca.service` is idempotent — it re-signs the leaf when it's missing or within 30 days of expiry, always under the same CA (so consumer trust is undisturbed). It regenerates the CA itself only if missing or already expired. To force a leaf rotation, delete `gateway.pem` under the state dir and restart the unit, then reload `nginx`.
|
||||
|
||||
**Cert prompts**: browsers still warn once per host until the operator adds the hive's `trust-bundle.pem` to the browser/OS trust store (an anchor, not the leaf, is the thing to trust). Agent trust is wired separately (see the agent-trust work for `/run/hive-ca`).
|
||||
**Cert prompts**: browsers still warn once per host until the operator adds the hive's `trust-bundle.pem` to the browser/OS trust store (an anchor, not the leaf, is the thing to trust). A separate mechanism wires agent trust (see the agent-trust work for `/run/hive-ca`).
|
||||
|
||||
### Operator-provided cert (`tls.certDir`)
|
||||
|
||||
|
|
@ -273,8 +273,8 @@ always advertise `https` (see [Discovery flow](#discovery-flow-matrix) above).
|
|||
|
||||
## Firewall posture (host-level)
|
||||
|
||||
The gateway is unconditional — `services.hyperhive.gateway.enable` was
|
||||
removed, there is no gateway-off mode. nginx is always the sole
|
||||
The gateway is unconditional — `services.hyperhive.gateway.enable` no
|
||||
longer exists, there is no gateway-off mode. nginx is always the sole
|
||||
external entry point and routes to agents over the UDS upstream
|
||||
described above (see [Per-agent unix-socket
|
||||
upstream](#per-agent-unix-socket-upstream)), so the per-agent web-port
|
||||
|
|
@ -297,14 +297,14 @@ listed in either case — it binds `127.0.0.1` only, so a firewall
|
|||
hole would be a no-op. Remote dashboard access flows through the
|
||||
gateway. Operators who opt out of the gateway lose external
|
||||
dashboard reach by design — the surface is privileged (approve /
|
||||
deny / destroy) and must not be exposed without a real reverse
|
||||
deny / destroy), and operators must not expose it without a real reverse
|
||||
proxy in front.
|
||||
|
||||
## `HIVE_FORGE_URL`: agents reach the forge via the gateway by domain
|
||||
|
||||
Agents poll `HIVE_FORGE_URL` for Forgejo notifications + run all
|
||||
`hive-forge` calls against it. Network isolation is always on (the
|
||||
shared-netns mode was removed), so agents run in a private netns and
|
||||
shared-netns mode no longer exists), so agents run in a private netns and
|
||||
can never reach the host's loopback.
|
||||
`nix/host-modules/hive-c0re/environment.nix` sets `HIVE_FORGE_URL` to
|
||||
`http://<forge.domain>` (default `forge.<swarm-domain>` — a swarm runs
|
||||
|
|
@ -355,10 +355,10 @@ only if you already have another process bound to 3000.
|
|||
|
||||
`sshPort` (default **2222**) is the port Forgejo's built-in SSH server
|
||||
uses for `git clone/push/pull` over SSH (`git@<domain>:owner/repo.git`
|
||||
via `-p 2222`). Port 22 is left alone on the host for openssh.
|
||||
via `-p 2222`). Port 22 stays alone on the host for openssh.
|
||||
|
||||
`openFirewall` (default **false**) controls whether `httpPort` and
|
||||
`sshPort` are opened in the host firewall. Off by default (secure by
|
||||
`openFirewall` (default **false**) controls whether the host firewall
|
||||
opens `httpPort` and `sshPort`. Off by default (secure by
|
||||
default): agents reach Forgejo through the gateway (`forge.<swarm-domain>` on
|
||||
the bridge), not the raw port, so no firewall hole is needed. Flip to
|
||||
`true` when you need:
|
||||
|
|
@ -529,7 +529,7 @@ is required. nginx reads it at that path directly.
|
|||
|
||||
Manage users with `hivectl gateway`. `hivectl` sends the request over the
|
||||
host admin socket and the `hive-c0re` daemon performs the write at its
|
||||
canonical path — no path is exposed to the CLI:
|
||||
canonical path — the daemon never exposes a path to the CLI:
|
||||
|
||||
```sh
|
||||
# Add or update a user (prompted for password):
|
||||
|
|
|
|||
Loading…
Reference in a new issue