Watch
0
0
Fork
You've already forked hyperhive
0

authelia: render the swarm apex's operator rules wherever authelia runs

The apex's `operatorsOnly` pair was guarded on
`deploy.swarm-controller.enable`, which is true only on the host that
runs the controller and with it the swarm UI's vhost. When authelia runs
on another host, that vhost still asks it, but the authelia host
rendered no rule for the apex at all, so every session reached the
swarm UI and its `/api/` through `default_policy = one_factor`.

The pair now renders whenever the swarm domain is set, like the bao UI's
pair. No vhost on a host that doesn't serve the apex asks about it, so
the extra rules there are inert. authelia 4.39.20's `validate-config`
accepts them on an authelia-only host's rendered access_control.

module-eval-swarm-otel-identity gains a case on the existing
`autheliaOnly` fixture (authelia without the controller): the apex has
exactly the allow+deny pair, the rule list is closed, and an account in
no group is refused `/api/agents` while `group:admins` passes.

Fixes #5120
This commit is contained in:
atlas 2026-10-14 21:47:15 +02:00 • committed by mara
commit 2a25ec3dff
2 changed files with 34 additions and 3 deletions

View file

@ -670,6 +670,35 @@ let
&& policy "group:admins" ui "/" == "one_factor"
&& policy "user:nobody" "forge.t.local" "/" == "one_factor";
}
{
# Authelia on a host that runs no swarm controller, so the swarm UI's
# vhost is elsewhere. That vhost still asks this authelia, so the apex's
# pair renders here regardless.
name = "authelia confines the swarm UI to operators on a host without the swarm controller";
ok =
let
h = autheliaOnly.services.hyperhive;
rules = autheliaRules autheliaOnly;
policy = autheliaPolicy autheliaOnly;
in
h.deploy.authelia.enable
&& !h.deploy.swarm-controller.enable
&&
lib.filter (r: r.domain == "t.local") rules == [
{
domain = "t.local";
subject = [ "group:admins" ];
policy = "one_factor";
}
{
domain = "t.local";
policy = "deny";
}
]
&& autheliaSubjectRulesClosed rules
&& policy "user:nobody" "t.local" "/api/agents" == "deny"
&& policy "group:admins" "t.local" "/api/agents" == "one_factor";
}
{
# Every subject-scoped rule the host renders, read in order. The `elem`
# clauses are the control for the predicate's vacuous case; the