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:
parent
e04616eb70
commit
97fb76ce99
22 changed files with 553 additions and 813 deletions
|
|
@ -498,17 +498,6 @@ impl Policy {
|
|||
// admission). Same failure mode as the knowledge event above: a
|
||||
// refused publish reaches the client as a timeout.
|
||||
swarm_queue_client::DEPLOY_SUBJECT_WILDCARD.to_owned(),
|
||||
// The credential notices: same per-hive family and same wildcard
|
||||
// reasoning as the deploy events, and the same timeout-not-error
|
||||
// failure if this line is missing.
|
||||
//
|
||||
// 🔑 Worth being explicit that this grant is not a confidentiality
|
||||
// boundary, because it looks like one. `sub` is unrestricted, so
|
||||
// any hive could subscribe to another's notices — which is exactly
|
||||
// why the payload names a credential and never carries one. What
|
||||
// scopes the secret is the store's own policy at read time, under
|
||||
// the reading hive's certificate.
|
||||
swarm_queue_client::CREDENTIAL_SUBJECT_WILDCARD.to_owned(),
|
||||
// The wanted-state buckets — one per hive, all created and written
|
||||
// by this single client.
|
||||
//
|
||||
|
|
@ -759,36 +748,6 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_reader_may_publish_a_credential_notice_to_any_hive() {
|
||||
let p = policy().permissions("swarm-controller").expect("a reader");
|
||||
assert!(
|
||||
p.publish
|
||||
.contains(&swarm_queue_client::CREDENTIAL_SUBJECT_WILDCARD.to_owned()),
|
||||
"without this grant the controller's publish is refused, and a \
|
||||
refusal arrives as a timeout — a hive that silently never receives \
|
||||
a credential, with nothing in either log saying why"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_hive_may_not_publish_a_credential_notice() {
|
||||
// A forged notice cannot leak a secret — the payload carries none — but
|
||||
// it can make a hive fetch and overwrite an agent's token file with
|
||||
// whatever the store holds for a name the forger chose.
|
||||
let p = policy()
|
||||
.permissions("hive-alpha")
|
||||
.expect("a hive is admitted");
|
||||
assert!(
|
||||
!p.publish
|
||||
.iter()
|
||||
.any(|s| s == swarm_queue_client::CREDENTIAL_SUBJECT_WILDCARD
|
||||
|| s == &swarm_queue_client::credential_subject("hive-alpha")),
|
||||
"a hive must not publish credential notices, its own included: {:?}",
|
||||
p.publish
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_hive_may_not_publish_a_deploy_event_to_anyone_including_itself() {
|
||||
// Same arm as the knowledge event's, and it matters more here: a forged
|
||||
|
|
|
|||
Loading…
Reference in a new issue