The dashboard, its API, the swagger UI and the agent routes move to their own vhost, `swarm.dashboardDomain` = `<hive>.hives.<swarm.domain>`, under the swarm domain so authelia's session cookie reaches it. `/`, `/api/` and `/api/docs/` ask authelia through `auth_request`, and authelia's `operatorsOnly` rule for each hive's dashboard name lets only the admins group in. The hive domain keeps matrix discovery and redirects every other path to the new name. The name rides as a SAN on the hive's own gateway leaf: the per-hive bao role allows it, and hive-tls asks for it and checks coverage. HTTP Basic auth is gone: the htpasswd writer and its test, the `hivectl gateway` verbs and host-socket requests, the `gateway.auth` options (now a removed-option error), the unauthorized page and the bcrypt dependency. tmpfiles deletes a leftover gateway.htpasswd, which held bcrypt hashes at 0644. c0re hands out dashboard and agent URLs on the new name (HYPERHIVE_DASHBOARD_DOMAIN), and the swarm controller's hive roster carries each hive's dashboard name for the swarm UI's hive list. Closes #3469
157 lines
5.8 KiB
Markdown
157 lines
5.8 KiB
Markdown
# First-run setup
|
|
|
|
What's left to do by hand after the first `nixos-rebuild switch` of the
|
|
[README's all-local quick start](../../README.md#quick-start-an-all-local-swarm)
|
|
— from a freshly built host to your first agent. Do the steps in order;
|
|
each one assumes the ones before it.
|
|
|
|
Every command runs as **root on the host**.
|
|
|
|
> **Not all-local?** Each step says which host it runs on. A split swarm
|
|
> also has credentials you can't generate where they're read — each
|
|
> host's mTLS identity at the secret store. Read [`swarm/secrets.md`](../swarm/secrets.md) first; it
|
|
> says which files you place, and where.
|
|
|
|
## 1 · Secret store
|
|
|
|
_On the host running `swarm-bao`._ Everything else fetches its credentials
|
|
from the store, so it comes first.
|
|
|
|
```bash
|
|
sudo bao operator init # keep the keys it prints and the root token OFF this host
|
|
```
|
|
|
|
Then bootstrap the **granter**, the one principal that writes every
|
|
`swarm-*` policy and role from then on. This is the only step that needs
|
|
the root token:
|
|
|
|
```bash
|
|
sudo -i
|
|
read -rs BAO_TOKEN && export BAO_TOKEN # paste the root token from `bao operator init`
|
|
bao policy write bao-bootstrap /etc/hyperhive/bao-bootstrap-policy.hcl
|
|
bao token create -policy=bao-bootstrap -ttl=24h -orphan -display-name=bao-bootstrap -field=token \
|
|
| install -D -m 0600 /dev/stdin /var/lib/swarm-bao-bootstrap/grant.token
|
|
unset BAO_TOKEN
|
|
systemctl restart swarm-bao-granter-role
|
|
```
|
|
|
|
Check `systemctl status swarm-bao-granter-role` logs
|
|
`Uploaded policy: bao-granter`, then restart the granting units that
|
|
failed while they waited, and remove the token:
|
|
|
|
```bash
|
|
systemctl reset-failed 'swarm-bao-*-policy.service' swarm-bao-agent-pki.service
|
|
systemctl restart 'swarm-bao-*-policy.service' swarm-bao-agent-pki.service
|
|
systemctl status swarm-bao-controller-policy # Uploaded policy, Data written to: auth/cert/certs/swarm-controller
|
|
rm /var/lib/swarm-bao-bootstrap/grant.token
|
|
```
|
|
|
|
⏱️ A first attempt right after a rebuild may fail with `local node not
|
|
active` while the store comes up; the units retry every 30s for a day.
|
|
|
|
With the default `pkcs11` seal the store unseals itself from here on. With
|
|
`deploy.bao.seal = "shamir"`, run `bao operator unseal` after every restart.
|
|
What the granter is, why it's root-equivalent, and the store's TLS:
|
|
[`swarm/bao.md`](../swarm/bao.md).
|
|
|
|
## 2 · Your SSO account
|
|
|
|
_On the host running authelia._ Until this runs, `auth.<swarm.domain>` serves
|
|
a login page that refuses everyone: its only subject is a disabled placeholder.
|
|
|
|
```bash
|
|
swarmctl user add mara --display-name Mara --email mara@example.com --group admins
|
|
```
|
|
|
|
It prints a generated password once — record it. Keep both flags:
|
|
|
|
- **`--group admins`** — the swarm UI and other operator surfaces gate on
|
|
it. Without it you log in fine and are then refused.
|
|
- **`--email`** — the forge won't create an account without one.
|
|
|
|
Fix either afterwards with `swarmctl user update mara --add-group admins
|
|
--email …`. Details: [`swarm/sso.md`](../swarm/sso.md).
|
|
|
|
The swarm UI is now at `https://<swarm.domain>/`. The name resolves on the
|
|
box itself through `/etc/hosts`; from anywhere else it needs a real DNS
|
|
record. → [`swarm/ui.md`](../swarm/ui.md)
|
|
|
|
## 3 · Forge admin
|
|
|
|
Sign in to the forge once through SSO — that first login creates your
|
|
forge account under the same username. Then, _on the swarm-controller's
|
|
host_:
|
|
|
|
```bash
|
|
swarmctl forge make-admin mara
|
|
```
|
|
|
|
If the forge already has a local account with your username, the first
|
|
SSO login asks for its forge password once, to link the two.
|
|
|
|
## 4 · Ruth's store identity
|
|
|
|
hive-c0re creates the manager agent, ruth, on its own at startup — so
|
|
unlike agents made through the swarm, she has no store identity yet:
|
|
|
|
```bash
|
|
swarmctl agent create ruth --hive <hive> # on the swarm-controller's host
|
|
hivectl agent ruth rebuild # on ruth's hive: hands her the identity
|
|
```
|
|
|
|
`agent create` declares an agent the swarm has no declaration for as
|
|
`paused`, so without a further step ruth keeps running but drives no turns.
|
|
`swarmctl` has no verb for wanted state: open `/agents` in the swarm UI and set
|
|
her `up` from her card.
|
|
|
|
Within about ten minutes the controller creates her forge user and matrix
|
|
account and mints their tokens into the store, where she fetches them.
|
|
`swarmctl agent mint-forge-token ruth` skips the wait for the forge token.
|
|
|
|
## 5 · Matrix
|
|
|
|
Your matrix account comes from SSO. Invite it to the hive Space, and
|
|
optionally to rooms:
|
|
|
|
```bash
|
|
hivectl matrix invite mara
|
|
hivectl matrix invite @mara:yourserver --room '#hive-chat:yourserver'
|
|
```
|
|
|
|
## 6 · Your first agent
|
|
|
|
Create it from the swarm UI, or:
|
|
|
|
```bash
|
|
swarmctl agent create iris --hive pr1ma
|
|
```
|
|
|
|
The controller provisions iris's identity, forge user and config repo
|
|
(`agent-configs/iris`, from the default template), then has the hive build
|
|
and start the container. It returns once the scheduler queues the job — watch the
|
|
swarm UI's job view for progress.
|
|
|
|
Later config changes are PRs on `agent-configs/iris`; you merge them on the
|
|
forge, and the merge deploys them. →
|
|
[`agent-lifecycle/config-changes.md`](../agent-lifecycle/config-changes.md#config-changes)
|
|
|
|
## The hive dashboard
|
|
|
|
The per-hive dashboard answers on `<hive>.hives.<swarm domain>`, behind
|
|
authelia: log in with the `admins` account you created above. The hive's
|
|
own domain redirects there.
|
|
|
|
→ [`networking/gateway.md`](../networking/gateway.md#dashboard-access)
|
|
|
|
## Day to day
|
|
|
|
```bash
|
|
hivectl list-agents # this hive's agents, status, rev
|
|
hivectl agent <name> restart # stop + start, no rebuild
|
|
hivectl agent <name> watch # follow its live event stream
|
|
hivectl agent <name> choom # interactive claude session in its container
|
|
hivectl open # this hive's dashboard (or: forge, matrix)
|
|
```
|
|
|
|
Every verb: [`tools/hivectl.md`](../tools/hivectl.md) ·
|
|
[`tools/swarmctl-cli.md`](../tools/swarmctl-cli.md).
|