Watch
0
0
Fork
You've already forked hyperhive
0

matrix: the agent's daemon pulls its linked accounts from bao itself

hive-matrix-daemon now learns which external matrix accounts it has from
the swarm secret store, under the agent's own certificate, and the hive
push chain for matrix is gone.

The daemon lists swarm/agents/<agent>/matrix/ (the `list` its policy
grants on its own metadata subtree), reads each account's homeserver
from its credential, and brings the accounts up with their tokens from
the store. Every two minutes it lists again and exits with 75 when the
set of linked accounts changed; the unit restarts on 75 without counting
a failure. A listed name whose credential reads as absent is skipped and
logged once. At start it removes the matrix-token-<a> /
matrix-account-<a>.json pairs a hive delivered (a sidecar marks a pair
as delivered; a declared tokenFile keeps its token).

Removed: CredentialNotice and the $SWARM.credential.* subject and NATS
grant, the controller's publish and its queue precondition on the PUT
route, hive-c0re's credential subscription arm and workers/credential.rs,
priv_client::write_agent_matrix_token, hive-priv's WriteAgentMatrixToken
and its helpers, and the daemon's state-dir account discovery.

Kept: WriteAgentGithubToken and the external-forge path
(WriteAgentExtraForgeAccount, extra_forges.rs) are untouched, and a
declared matrixAccounts tokenFile is still read when the store has no
token for that account.

Refs #4348
This commit is contained in:
atlas 2026-10-01 17:41:20 +02:00
commit 97fb76ce99
22 changed files with 553 additions and 813 deletions

View file

@ -479,40 +479,11 @@ pub enum PrivRequest {
},
// --- Agent credential writes ---
/// Write a matrix access token into the agent's state dir. With
/// `account: None` it targets the hive-internal `matrix-token`; with
/// `account: Some(name)` it targets `matrix-token-<name>` for an extra
/// (external) account. hive-priv validates both `agent_name` and the
/// `account` suffix as plain identifiers before building the path, so a
/// crafted account name cannot traverse out of the state dir.
///
/// hive-priv validates the names, creates the state dir if absent,
/// writes the file 0600, and chowns it to the state dir's owner so the
/// agent process can read it. Required because hive-c0re runs
/// unprivileged and cannot write to agent-owned state directories.
WriteAgentMatrixToken {
/// Logical agent name (validated by `validate_agent_name`).
agent_name: String,
/// Token value. hive-priv appends a trailing newline before writing.
token: String,
/// Extra-account suffix. `None` → `matrix-token` (the hive account);
/// `Some(name)` → `matrix-token-<name>` (validated as a plain ident).
account: Option<String>,
/// Homeserver URL for an extra account. When `Some` (only meaningful
/// alongside `account: Some`), hive-priv also writes the sidecar
/// `matrix-account-<name>.json` (`{"homeserver": <url>}`, 0600,
/// chowned to the agent) so the daemon can auto-discover the account
/// without a config declaration. `None` → no sidecar written.
#[serde(default)]
homeserver: Option<String>,
},
/// Write `github-token` into `AGENT_STATE_ROOT/<agent_name>/state/github-token`.
///
/// The operator-supplied GitHub personal access token (PAT) for the
/// agent's GitHub integration (`services.hyperhive.agent.github.enable`). Same write
/// semantics as
/// `WriteAgentMatrixToken` — validates `agent_name`, creates the state dir
/// agent's GitHub integration (`services.hyperhive.agent.github.enable`).
/// hive-priv validates `agent_name`, creates the state dir
/// if absent, writes the file 0600, and chowns it to the agent so the
/// `gh` wrapper / git credential helper can read it. No account suffix
/// (single GitHub account per agent).
@ -528,15 +499,13 @@ pub enum PrivRequest {
/// `AGENT_STATE_ROOT/<agent_name>/state/forge-<label>-token` (0600) and
/// a `forge-<label>.json` sidecar (`{"base_url": <base_url>}`, 0600) so
/// the base URL survives without any host-side nix config — the whole
/// account (label + URL + token) is operator-entered on the dashboard,
/// same shape as `WriteAgentMatrixToken`'s homeserver sidecar.
/// account (label + URL + token) is operator-entered on the dashboard.
///
/// `label` MUST be validated as a plain identifier (same rule as the
/// matrix `account` suffix) before it goes into the filename — a
/// crafted label could otherwise traverse out of the state dir. Same
/// write semantics as `WriteAgentMatrixToken` — validates `agent_name`,
/// creates the state dir if absent, writes both files 0600, chowns to
/// the agent.
/// `label` MUST be validated as a plain identifier before it goes into
/// the filename — a crafted label could otherwise traverse out of the
/// state dir. Same write semantics as `WriteAgentGithubToken` — validates
/// `agent_name`, creates the state dir if absent, writes both files 0600,
/// chowns to the agent.
WriteAgentExtraForgeAccount {
/// Logical agent name (validated by `validate_agent_name`).
agent_name: String,