Watch
0
0
Fork
You've already forked hyperhive
0

swarm-archive: back up every agent's state to an append-only restic repository per agent

swarm-archive serves restic repositories with rclone, append-only, one login
and one repository per agent. swarm-controller writes each placed agent's
login and restic password to the store, replaces them on a move and removes
them when the agent is destroyed. Every hive backs its agents up hourly under
its own store identity. The archive host prunes by retention.
This commit is contained in:
atlas 2026-11-10 07:49:49 +01:00
commit 306aae0378

View file

@ -195,6 +195,7 @@ let
"swarm-bao-claude-login-policy"
"swarm-bao-notify-router-policy"
"swarm-bao-attic-policy"
"swarm-bao-archive-policy"
];
# Comment lines dropped first: both the HCL and the scripts explain
@ -2166,6 +2167,30 @@ let
in
lib.hasInfix "/notify-router.pem ]" s && lib.hasInfix "swarm-notify-router \"\" clientAuth" s;
}
{
# The archive reads the users and the repositories' passwords and writes
# nothing; the hive-side copies of the REST password are not its to read.
# The controller is the only writer: the control is its own grant.
name = "the archive's grant is read on its users and restic passwords, list on its users, and nothing else, and only the controller writes them";
ok =
let
s = baoGrantHere.systemd.services.swarm-bao-archive-policy.script;
grants = grantsIn s;
c = grantsIn baoGrantHere.systemd.services.swarm-bao-controller-policy.script;
in
(grantFor grants "secret/data/swarm/services/archive/users/atlas").caps == [ "read" ]
&& (grantFor grants "secret/data/swarm/services/archive/restic/atlas").caps == [ "read" ]
&& (grantFor grants "secret/metadata/swarm/services/archive/users/").caps == [ "list" ]
&& grantFor grants "secret/data/swarm/hives/h1/archive/atlas" == null
&& lib.length grants == 3
&& lib.hasInfix "allowed_common_names=swarm-archive" s
&& lib.hasInfix "token_policies=swarm-archive" s
&& lib.elem "create" (grantFor c "secret/data/swarm/services/archive/users/atlas").caps
&& lib.elem "create" (grantFor c "secret/data/swarm/hives/h1/archive/atlas").caps
&& (grantFor c "secret/metadata/swarm/hives/h1/archive/atlas").caps == [ "delete" ]
&& (grantFor c "secret/metadata/swarm/services/archive/users/atlas").caps == [ "delete" ]
&& !(lib.elem "delete" (grantFor c "secret/data/swarm/services/archive/restic/atlas").caps);
}
{
# The cache's host units create each of its six secrets and read them
# back, and replace only the public key: `update` there and nowhere else.