Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/docs/swarm/credentials.md
atlas 5fe71fd056 credentials docs: trim the page to what an operator running a swarm needs
- table cells: cut to what the credential is, where it comes from and what the operator does
- prose sections: cut the matrix-prefix, appservice-token and leaf-delivery sections; trimmed revocation and retry notes to their operator-visible effect
- progressive enhancement section: removed (contributor rules)
- intro: cut to the store, the on-disk certificate and the column meanings
- docs index: drop the "progressive-enhancement rule" clause from the credentials.md entry in docs/README.md
- matrix rows: one sentence saying the name `main` is reserved
2026-10-22 07:55:42 +02:00

19 KiB

Credentials: the target shape

The swarm's credential store is bao. This page lists each credential: who mints it, who reads it, and how it renews. It describes the target, not what's on disk today; secrets.md maps the files that exist right now.

Store secrets stay off disk. A process pulls a value from the store at runtime and holds it in memory only.

The mTLS client certificate is the only credential on disk. Each identity (an agent, a hive, a swarm-level service) has one. It's what logs a principal in to the store, so you place a hive's or service's certificate by hand. The nix option for it takes a path to the certificate, never its bytes, because a literal in a nix expression lands in the world-readable nix store. A hive hands each agent its certificate; the agent pulls everything else itself.

In the table, automatic re-mint is something replacing the stored value without an operator. Automatic re-pull is the reader picking up a replaced value without a restart. ✅ means it happens today, ❌ means it doesn't, and the rest of the cell says how.

store path minter reader automatic re-mint automatic re-pull
swarm/agents/<agent>/matrix/main swarm-controller, at agent creation and every 5 minutes the agent ✅ when missing or rejected by the homeserver ✅ the daemon restarts within 5 minutes of a rejection
swarm/agents/<agent>/matrix/<account> swarm-controller, from a credential you hand it the agent must be stated ✅ retried within 2 to 16 minutes after a rejection
swarm/agents/<agent>/matrix-recovery/<account> swarm-controller, a random passphrase per account the agent ❌ never replaced: the account's key backup opens only with this passphrase ❌ read when the account comes up
swarm/controller/swarm-controller/matrix/appservice-token swarm-matrix-ctl in hive-matrix, once swarm-controller ❌ minted once ✅ read every 5 minutes
swarm/controller/swarm-controller/oidc/client authelia, first boot swarm-controller ❌ minted once; swarm-secret-publish republishes a re-mint ✅ re-read when authelia refuses it
swarm/controller/swarm-controller/forge/token the forge, once swarm-controller ❌ minted once; delete /var/lib/forgejo/swarm-controller-token-name in the forge container to mint a new one ✅ re-read on a 401
swarm/controller/swarm-controller/grafana/token swarm-bao-grafana-controller-token on Grafana's host swarm-controller ✅ every 10 minutes, when Grafana refuses it or none is stored ✅ re-read on a 401
swarm/agents/<agent>/bao-mtls the store's agent PKI mount (deploy.bao.agentPkiMountPath), at agent creation hive-c0re, then the agent ✅ re-issued every 5 minutes once past half its 90-day validity ✅ the agent re-reads every 10 minutes; it renews only while its current leaf is valid
swarm/agents/<agent>/queue swarm-controller, at agent creation the agent; the queue, log and metrics auth services ✅ re-minted at 45 days; skipped for Destroyed agents, whose path is deleted ✅ read on every reconnect; an open connection keeps the old secret for up to an hour; the log and metrics stores honour a replaced secret for up to deploy.victorialogs.authVerdictTtl and deploy.victoriametrics.agentAuthVerdictTtl (60 s by default)
swarm/agents/<agent>/forge-token swarm-controller, at agent creation and every 5 minutes the agent ✅ when missing or no longer matching the forge ✅ every 10 minutes
swarm/agents/<agent>/forge/<label> swarm-controller, when you link an external forge account in the swarm UI the agent ❌ your token; delete it and link the label again ✅ every 2 minutes
swarm/agents/<agent>/github-token swarm-controller, when you link a GitHub account in the swarm UI the agent ❌ your token; delete it and link again ✅ every 2 minutes
swarm/agents/<agent>/claude-credentials swarm-claude-login, when you log the agent in from its card; one version per login the agent, while it waits for a login ❌ log in again ✅ every 30 seconds while waiting
swarm/hives/<hive>/matrix/sender-token swarm-controller, every 5 minutes swarm-controller and the hive ✅ when missing or rejected by the homeserver ✅ the hive re-reads on every sweep
swarm/hives/<hive>/forge/token swarm-controller, every 5 minutes swarm-controller and the hive ✅ when missing or no longer matching the forge ✅ read on every forge call
swarm/hives/<hive>/queue/agent authelia swarm-bao-queue-agent on the hive's host must be stated must be stated
swarm/hives/<hive>/oidc/client authelia, first boot; swarm-secret-publish copies it in the hive ❌ minted once; swarm-secret-publish republishes a re-mint ✅ re-read when authelia refuses it
swarm/services/<clientId>/oidc/client authelia that service must be stated must be stated
swarm/services/ci-runner/registration-token swarm-controller, from the forge, at start and every 5 minutes swarm-bao-ci-runner on the runner's host ❌ the forge keeps one token until an admin resets it; the controller then writes the new one within 5 minutes ✅ every 10 minutes; restarts the runner on a change
swarm/services/<grafana client id>/metrics/bearer swarm-bao-grafana-metrics-bearer on Grafana's host, when none is stored swarm-metrics-auth and swarm-logs-grafana-auth ❌ delete it and restart swarm-bao-grafana-metrics-bearer ✅ the auth services re-read within a minute; ❌ Grafana restarts when its copy changes
swarm/services/review-classifier/anthropic-api-key you, in the store's UI, field api_key swarm-review-classifier ❌ write a new key ✅ read on every run
swarm/services/review-classifier/acp-provider you, in the store's UI, field api_key swarm-review-classifier ❌ write a new key ✅ read on every run
swarm/services/review-classifier/forge/token swarm-controller, at start and every 5 minutes swarm-controller ✅ when missing or no longer matching the forge ✅ read on every review
swarm/services/builder/forge/token swarm-controller, at start and every 5 minutes swarm-builder, swarm-controller ✅ when missing or no longer matching the forge ✅ read on every build
swarm/services/ci-metrics/forge/token swarm-controller, at start and every 5 minutes swarm-ci-metrics, swarm-controller ✅ when missing or no longer matching the forge ✅ read on every pass
(not in the store) a hive's mTLS leaf the store's PKI, or you by hand the hive itself, from disk must be stated must be stated

The name main belongs to the swarm's own homeserver account, which the controller mints, so the controller rejects any account you link under it.

swarm-controller checks every forge token itself: it looks at every agent that has a store identity at start and every five minutes. For any whose stored token is missing or stale it creates the forge user if there isn't one, then mints the token. To check one agent now:

swarmctl agent mint-forge-token <agent>

An agent without a store identity gets no swarm token and keeps using the forge-token file in its state dir, if it has one; re-create it with swarmctl agent create to give it one. The swarm leaves an agent it already declares as it is. For an agent with no declaration, such as one only its hive knows about, agent create declares it paused; set it up from its card in the swarm UI.

⚠️ Re-create existing agents before deploying a hive-side change that makes a container require a credential it may not have. A container whose store identity is absent doesn't start, so create the identities first, setting any newly paused agent up as above.

Revoking an agent's queue credential. Declaring an agent destroyed — PUT /api/hives/{hive}/agents/{agent}/state — deletes swarm/agents/<agent>/queue and every version it held. An open queue connection closes within an hour. An agent recreated under the same name gets a fresh secret. It leaves the agent's mTLS leaf alone. If the store refuses the delete, swarm-controller logs an error naming the agent and the teardown continues; declare the agent destroyed again to re-run the revocation.

A failed store login retries every 30 seconds for a day. When a later attempt lands a changed value, the service that loaded it restarts. If the fetch unit can't compare file times it logs cannot compare the mtime of <path> … — leaving <unit> as it is at err, and the service keeps the old value until the next timer tick.