feat(3167): authelia gates the swarm UI on an operators group
default_policy = one_factor means 'any authenticated user', which is authentication and not authorisation. The swarm UI is operator-only and agents are getting authelia accounts of their own, so a session alone would be enough to open it the day that lands - the vhost's auth_request would be a check nobody fails. Adds an access_control rule for the UI's domain requiring subject = group:operators, present only when the UI is enabled. The group name is a constant beside the rule: it is also what an operator types into 'swarmctl user add --group', and a configurable name is one more way for the rule and the account to disagree silently.
This commit is contained in:
parent
f2840612c0
commit
d337fec565
1 changed files with 27 additions and 1 deletions
|
|
@ -37,6 +37,13 @@ let
|
||||||
hyperhiveCfg = config.services.hyperhive;
|
hyperhiveCfg = config.services.hyperhive;
|
||||||
hyperhiveDomain = hyperhiveCfg.domain;
|
hyperhiveDomain = hyperhiveCfg.domain;
|
||||||
swarmDomain = hyperhiveCfg.swarm.domain;
|
swarmDomain = hyperhiveCfg.swarm.domain;
|
||||||
|
uiCfg = hyperhiveCfg.swarm.ui;
|
||||||
|
|
||||||
|
# Group an account must hold to reach operator-only surfaces. Named
|
||||||
|
# here because this module writes the rule that enforces it and
|
||||||
|
# `swarmctl user add --group <this>` is what grants it — the two must
|
||||||
|
# agree, and one constant is how they stay agreeing.
|
||||||
|
operatorGroup = "operators";
|
||||||
|
|
||||||
# Upstream's `services.authelia.instances.<name>` derives the unit,
|
# Upstream's `services.authelia.instances.<name>` derives the unit,
|
||||||
# user, group and StateDirectory from the instance name
|
# user, group and StateDirectory from the instance name
|
||||||
|
|
@ -536,7 +543,26 @@ in
|
||||||
|
|
||||||
authentication_backend.file.path = cfg.usersFile;
|
authentication_backend.file.path = cfg.usersFile;
|
||||||
|
|
||||||
access_control.default_policy = "one_factor";
|
# ⚠️ `one_factor` as the DEFAULT means "any authenticated
|
||||||
|
# user", which is authentication, not authorisation. The
|
||||||
|
# swarm UI is operator-only, and agents are getting
|
||||||
|
# authelia accounts of their own — so the day that lands,
|
||||||
|
# a session alone would be enough to open it. The rule
|
||||||
|
# below is what makes the distinction real; without it
|
||||||
|
# the vhost's `auth_request` is a check nobody fails.
|
||||||
|
#
|
||||||
|
# The group is a constant rather than an option: it is the
|
||||||
|
# value an operator types into `swarmctl user add --group`,
|
||||||
|
# and a configurable name is one more way for the rule and
|
||||||
|
# the account to disagree silently.
|
||||||
|
access_control = {
|
||||||
|
default_policy = "one_factor";
|
||||||
|
rules = lib.optional uiCfg.enable {
|
||||||
|
domain = uiCfg.domain;
|
||||||
|
subject = [ "group:${operatorGroup}" ];
|
||||||
|
policy = "one_factor";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# The cookie domain is the SWARM's domain, NOT authelia's
|
# The cookie domain is the SWARM's domain, NOT authelia's
|
||||||
# own host: the session cookie has to be sent to the apps
|
# own host: the session cookie has to be sent to the apps
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue