docs: the forge, knowledge, archetypes, matrix and SSO pages move their implementation detail out
Account minting, knowledge sync, the archetype refresh, the matrix appservice flow and the SSO secret delivery move to pages under 4-implementation/swarm. Each handbook page keeps what an operator does or sees, with a pointer.
This commit is contained in:
parent
c6b24359cd
commit
0f39bdaaa4
1 changed files with 708 additions and 563 deletions
88
docs/4-implementation/swarm/forge-accounts.md
Normal file
88
docs/4-implementation/swarm/forge-accounts.md
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
# Forge accounts: hives and agents
|
||||
|
||||
How swarm-controller gives each hive a read-only forge account and each agent
|
||||
its own user and token, and where each token lives. The operator's view of the
|
||||
forge is [the forge page](../../2-handbook/swarm/forge.md).
|
||||
|
||||
## How a hive reads the forge
|
||||
|
||||
Each hive in swarm-controller's hive directory has its own forge account,
|
||||
`hive-<hive>`. swarm-controller creates it, makes it a member of the `hives`
|
||||
team in `agent-configs`, and mints one token named `swarm-hive` into the
|
||||
swarm secret store at `swarm/hives/<hive>/forge/token`. The team has read
|
||||
permission on `repo.code` and `repo.pulls` of every repo in the org,
|
||||
including repos created later. A pass at start and every five minutes
|
||||
creates what's missing and re-mints a token that's missing or no longer
|
||||
matches the forge. A pass whose store or forge reads fail queues nothing, so
|
||||
an outage never rotates every hive's token.
|
||||
|
||||
swarm-controller refuses to create an agent whose name starts with `hive-`:
|
||||
these accounts own that prefix. An agent that already had such a
|
||||
name keeps it, so the accounts are also told apart by email. swarm-controller
|
||||
creates the hive's account with the email `hive-<hive>@hives.hyperhive.local`
|
||||
and refuses an account by that name with any other email: it never adds an
|
||||
agent's account to the team or mints a token for it. An agent's own forge
|
||||
account setup refuses the hive's account the same way.
|
||||
|
||||
hive-c0re reads the token with `forge::reader_token()`, under the hive's own
|
||||
store certificate, every time it reads the forge. A hive whose store holds
|
||||
none reads nothing. These reads go through it, and none of them needs a local
|
||||
forge container:
|
||||
|
||||
- cloning and pulling `/knowledge`
|
||||
|
||||
The hive builds nothing, so no nix process reads the forge as the hive's
|
||||
account. hive-c0re hands the token to each `git` command it runs
|
||||
(`http.extraHeader`) and keeps no copy on disk. A hive whose store holds no token
|
||||
reads nothing private from the forge. This also holds on a hive with no forge
|
||||
container.
|
||||
|
||||
Roll a change to any of this out store host first (its granter writes the
|
||||
controller's grant on `swarm/hives/+/forge/token`), then the controller host,
|
||||
then the hives. A hive that starts before its token exists reads nothing, and
|
||||
builds nothing, until the controller's next pass.
|
||||
|
||||
## Per-agent forge accounts
|
||||
|
||||
Each agent gets its own Forgejo user and access token. swarm-controller
|
||||
creates the user when it creates the agent, and mints one token named
|
||||
`swarm-agent` with the admin API into the swarm secret store at
|
||||
`swarm/agents/<agent>/forge-token`. A pass at start and every five minutes
|
||||
covers every agent with a store identity: it creates a missing forge user and
|
||||
re-mints any token that's missing or no longer matches the forge;
|
||||
a rotation deletes the old `swarm-agent` token first, so each agent holds at
|
||||
most one. The agent fetches the token under its own store certificate into
|
||||
`/run/hive-agent-forge-token/token` (`nix/agent-modules/forge-token.nix`),
|
||||
and `hive-forge`, the git credential helper, the `forge_notify` poller and
|
||||
the avatar sync read it from there, falling back to `<state>/forge-token`,
|
||||
the file hive-c0re wrote before. hive-c0re no longer creates agent users or
|
||||
mints agent tokens. swarm-controller deletes the `hyperhive-<unix-seconds>`
|
||||
tokens it left behind, for each agent whose current `swarm-agent` token is
|
||||
live; tokens of other names are never touched.
|
||||
|
||||
Two things live in the `agent-configs` Forgejo organization:
|
||||
|
||||
- A config repo per agent (`agent-configs/<name>`). The
|
||||
agent is a **write collaborator on its own** repo — it can push
|
||||
config-change branches and open config PRs — but `main` is
|
||||
branch-protected by swarm-controller: the merge and approval
|
||||
allowlists are the `operators` team, and the agent can neither push
|
||||
`main` directly nor self-merge. An operator's merge in the Forgejo UI
|
||||
deploys the merged commit (see
|
||||
[config-changes.md § Config changes](../../2-handbook/agents/config-changes.md#config-changes)).
|
||||
hive-c0re pushes nothing to this org and reads nothing from it.
|
||||
Repos stay private, so an agent can't read another
|
||||
agent's config. The agent's **persistent meta flake input** is this repo's `main` head,
|
||||
pinned by sha in `internal/meta` (`agent-<n>.url =
|
||||
git+<forge>/agent-configs/<n>.git?rev=<sha>`; see
|
||||
[config-changes.md § Meta flake](../../2-handbook/agents/config-changes.md#meta-flake)).
|
||||
|
||||
The `hive-forge` CLI (separate workspace crate, see
|
||||
[`README.md`](../../README.md) file map) wraps the Forgejo REST API
|
||||
with the per-agent token; agents call it for issue / PR / comment
|
||||
ops as if it were a peer. All REST calls across the workspace
|
||||
(`hive-forge` verbs, hive-c0re provisioning, this poller) go through
|
||||
the typed `forgejo-api` crate; only non-`/api/v1` web-router routes
|
||||
(attachment / artifact downloads, log streaming) and the poller's
|
||||
enrichment fetches of server-provided subject URLs stay on raw
|
||||
reqwest.
|
||||
Loading…
Reference in a new issue