copy the cache's pull facts to each hive and create them in the in-swarm cache
the in-swarm cache stores its address, name and public key beside its tokens, create-only. swarm-controller copies the four cache facts to swarm/hives/<hive>/attic/* every five minutes, with read on the sources and write on the copies. part 1 of 3: nothing reads the copies until the hive reader and probe land.
This commit is contained in:
parent
c79c41e004
commit
1e5070796d
1 changed files with 640 additions and 67 deletions
|
|
@ -1722,6 +1722,38 @@ let
|
|||
&& !(lib.hasInfix "secret/data/swarm/hives/*" s)
|
||||
&& !(lib.hasInfix "secret/metadata/swarm/hives" s);
|
||||
}
|
||||
{
|
||||
# `attic_copy` reads the cache's four facts and writes each into every
|
||||
# hive's `attic/` prefix. Pinned as whole stanzas, per leaf: a read of
|
||||
# the services prefix would reach every service's secrets, and `*` under
|
||||
# `hives/` every hive's queue credential. The read side has no
|
||||
# `create`/`update`, so the controller cannot replace the cache's token.
|
||||
name = "the controller reads the cache's four facts and writes a copy of each into every hive";
|
||||
ok =
|
||||
let
|
||||
s = baoGrantHere.systemd.services.swarm-bao-controller-policy.script;
|
||||
leaves = [
|
||||
"pull-token"
|
||||
"url"
|
||||
"cache"
|
||||
"public-key"
|
||||
];
|
||||
grants = grantsIn s;
|
||||
in
|
||||
lib.all (
|
||||
l:
|
||||
(grantFor grants "secret/data/swarm/services/attic/${l}").caps == [ "read" ]
|
||||
&&
|
||||
(grantFor grants "secret/data/swarm/hives/+/attic/${l}").caps == [
|
||||
"create"
|
||||
"read"
|
||||
"update"
|
||||
]
|
||||
) leaves
|
||||
&& lib.hasInfix "path \"secret/data/swarm/hives/+/attic/pull-token\" {\n capabilities = [\"create\", \"read\", \"update\"]\n}" s
|
||||
&& (grantFor grants "secret/data/swarm/services/attic/jwt-secret") == null
|
||||
&& (grantFor grants "secret/data/swarm/services/attic/push-token") == null;
|
||||
}
|
||||
{
|
||||
# `forge::runner_token` writes the runner's registration token and keeps
|
||||
# the last value in memory, so its stanza has no `read`. Pinned as the
|
||||
|
|
@ -1988,11 +2020,11 @@ let
|
|||
lib.hasInfix "/notify-router.pem ]" s && lib.hasInfix "swarm-notify-router \"\" clientAuth" s;
|
||||
}
|
||||
{
|
||||
# The cache's host units create each of its three secrets and read them
|
||||
# The cache's host units create each of its six secrets and read them
|
||||
# back, and may not replace one: no `update`. Its container's journal
|
||||
# forwarder reads its own client secret, read only. The notification
|
||||
# router's grant is the control that `grantsIn` reads a one-path grant too.
|
||||
name = "the cache's grant is create and read on its signing key and its two tokens, read on its forwarder client, and nothing else";
|
||||
name = "the cache's grant is create and read on its signing key, its two tokens and its three public facts, read on its forwarder client, and nothing else";
|
||||
ok =
|
||||
let
|
||||
s = baoGrantHere.systemd.services.swarm-bao-attic-policy.script;
|
||||
|
|
@ -2005,24 +2037,33 @@ let
|
|||
(grantFor grants "secret/data/swarm/services/attic/jwt-secret").caps == caps
|
||||
&& (grantFor grants "secret/data/swarm/services/attic/push-token").caps == caps
|
||||
&& (grantFor grants "secret/data/swarm/services/attic/pull-token").caps == caps
|
||||
&& (grantFor grants "secret/data/swarm/services/attic/url").caps == caps
|
||||
&& (grantFor grants "secret/data/swarm/services/attic/cache").caps == caps
|
||||
&& (grantFor grants "secret/data/swarm/services/attic/public-key").caps == caps
|
||||
&&
|
||||
(grantFor grants "secret/data/swarm/services/swarm-attic-collector/oidc/client").caps == [ "read" ]
|
||||
&& lib.length grants == 4
|
||||
&& lib.length grants == 7
|
||||
&& lib.length (grantsIn baoGrantHere.systemd.services.swarm-bao-notify-router-policy.script) == 1
|
||||
&& lib.hasInfix "auth/cert/certs/swarm-attic" s
|
||||
&& lib.hasInfix "allowed_common_names=swarm-attic" s
|
||||
&& lib.hasInfix "token_policies=swarm-attic" s;
|
||||
}
|
||||
{
|
||||
# The signing key and the pull token are the cache's alone; the push
|
||||
# token is also the builder's, and is read there.
|
||||
name = "no granting unit but the cache's names its signing key or its pull token";
|
||||
# The signing key is the cache's alone; the push token is also the
|
||||
# builder's, and is read there. The pull token is also the controller's,
|
||||
# which only reads it (pinned above).
|
||||
name = "no granting unit but the cache's names its signing key, and only it and the controller name its pull token";
|
||||
ok =
|
||||
lib.filter (
|
||||
u:
|
||||
lib.hasInfix "services/attic/jwt-secret" baoGrantHere.systemd.services.${u}.script
|
||||
|| lib.hasInfix "services/attic/pull-token" baoGrantHere.systemd.services.${u}.script
|
||||
) grantingUnitNames == [ "swarm-bao-attic-policy" ];
|
||||
u: lib.hasInfix "services/attic/jwt-secret" baoGrantHere.systemd.services.${u}.script
|
||||
) grantingUnitNames == [ "swarm-bao-attic-policy" ]
|
||||
&&
|
||||
lib.filter (
|
||||
u: lib.hasInfix "services/attic/pull-token" baoGrantHere.systemd.services.${u}.script
|
||||
) grantingUnitNames == [
|
||||
"swarm-bao-controller-policy"
|
||||
"swarm-bao-attic-policy"
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "the PKI unit signs the cache's leaf under its own subject";
|
||||
|
|
|
|||
Loading…
Reference in a new issue