Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/docs/getting-started/setup.md
atlas 99905f50b0 nix(authelia): start with a disabled placeholder user when the user set is empty
authelia 4.39.20 exits at startup on `users: {}` ("users: non zero value
required"), and the first-boot unit seeded exactly that, so a swarm with
no users crash-looped authelia and answered 502 until `swarmctl user add`
ran.

The first-boot unit now writes one subject, `swarm.placeholder`, when
the users database is absent, empty, or exactly `users: {}`:

- `disabled: true` — authelia returns "user not found" for a disabled
  user before any password check (file_user_provider.go,
  CheckUserPassword).
- password: an argon2id digest with an all-zero key. It decodes (authelia
  rejects a non-digest at startup) and no known password hashes to it.
- the `.` keeps it out of agent names (`[a-z0-9-]`), and `swarmctl user
  add` refuses it as already existing. Neither writer removes users, and
  both round-trip `disabled`.

A file with any user in it is never touched.

The docs that described the crash-loop (sso.md, gateway.md, setup.md,
the sso-unavailable error page) now describe the placeholder; the
writers' load_store docs and the seed fixtures follow. module-eval
nats-authelia asserts the seed branch.
2026-10-02 12:50:47 +02:00

157 lines
5.6 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, and each hive's telemetry
> ingest secret. 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 mint-identity ruth # on the swarm-controller's host
hivectl agent ruth rebuild # on ruth's hive: hands her the identity
```
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`, approved by you. →
[`agent-lifecycle/approvals.md`](../agent-lifecycle/approvals.md)
## Optional · Lock the hive dashboard
The per-hive dashboard has no SSO in front of it. To put it behind HTTP
Basic auth, set `services.hyperhive.gateway.auth.enable = true` and add
logins:
```bash
echo "hunter2" | hivectl gateway create-user mara --password-stdin
```
→ [`networking/gateway.md`](../networking/gateway.md#http-basic-auth)
## 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 approvals pending # what's waiting on you
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).