count readers, not writers, of the pull token in the cache's roster pin
This commit is contained in:
parent
7d78869104
commit
525cbe0355
1 changed files with 34 additions and 3 deletions
|
|
@ -316,6 +316,15 @@ let
|
|||
best: g: if best == null || lib.stringLength g.path > lib.stringLength best.path then g else best
|
||||
) null globs;
|
||||
|
||||
# Whether the policy text in `text` lets its holder read `secret/data/swarm/<leaf>`,
|
||||
# by `grantFor`'s rule, so a glob that reaches the leaf counts and a write does not.
|
||||
grantReads =
|
||||
leaf: text:
|
||||
let
|
||||
g = grantFor (grantsIn text) "secret/data/swarm/${leaf}";
|
||||
in
|
||||
g != null && lib.elem "read" g.caps;
|
||||
|
||||
ungranted =
|
||||
grants: units:
|
||||
lib.concatLists (
|
||||
|
|
@ -2139,20 +2148,42 @@ let
|
|||
{
|
||||
# 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";
|
||||
# which only reads it (pinned above). The pull token's value is what
|
||||
# the roster guards, so it counts the units that may read it: the
|
||||
# operator's write-only grant on it, which replaces the token and
|
||||
# exposes nothing, stays outside.
|
||||
name = "no granting unit but the cache's names its signing key, and only it and the controller read its pull token";
|
||||
ok =
|
||||
lib.filter (
|
||||
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
|
||||
u: grantReads "services/attic/pull-token" baoGrantHere.systemd.services.${u}.script
|
||||
) grantingUnitNames == [
|
||||
"swarm-bao-controller-policy"
|
||||
"swarm-bao-attic-policy"
|
||||
];
|
||||
}
|
||||
{
|
||||
# Control for the property above: `grantReads` tells a read from a write
|
||||
# on the same path, and the operator's policy does name the pull token.
|
||||
name = "a grant that only writes the pull token is not a read of it, and one that reads it is";
|
||||
ok =
|
||||
let
|
||||
stanza = caps: ''
|
||||
path "secret/data/swarm/services/attic/pull-token" {
|
||||
capabilities = [${caps}]
|
||||
}
|
||||
'';
|
||||
viewer = baoGrantHere.systemd.services.swarm-bao-operator-viewer-policy.script;
|
||||
in
|
||||
!(grantReads "services/attic/pull-token" (stanza ''"create", "update"''))
|
||||
&& grantReads "services/attic/pull-token" (stanza ''"read"'')
|
||||
&& grantReads "services/attic/pull-token" (stanza ''"create", "read"'')
|
||||
&& lib.hasInfix "services/attic/pull-token" viewer
|
||||
&& !(grantReads "services/attic/pull-token" viewer);
|
||||
}
|
||||
{
|
||||
name = "the PKI unit signs the cache's leaf under its own subject";
|
||||
ok =
|
||||
|
|
|
|||
Loading…
Reference in a new issue