swarm-authelia: one fact in three places, kept in two

`docs/swarm/sso.md` already argues that the OIDC provider is derived from
the client list rather than carrying its own `enable` — authelia refuses to
start without clients, so a separate flag would be a second fact free to
disagree. The module header said it again, and the definition site said it a
third time.

The doc keeps the argument. The definition site keeps a short version,
because someone changing `oidcEnabled` needs the reason there and not two
files away, along with the part no doc carries: that it is unconditionally
true today and stays derived so the OIDC-gated code below is self-documenting
about why it is conditional.

The header also restated the users-store rationale the doc's "does not
provision users" bullet owns. What survives there is the one clause the doc
does not have — why a file backend is right rather than a placeholder for
LDAP, the subject set being bounded by one swarm.

503 comment lines to 495. Comment-only: still 36 module-eval properties.
This commit is contained in:
atlas 2026-09-02 01:49:35 +02:00
commit 1f0b3cf0cc

View file

@ -9,20 +9,13 @@
# `deploy.allSwarmServices` asserts this module's `enable` # `deploy.allSwarmServices` asserts this module's `enable`
# (see ./swarm-required-services.nix); a hive is a client by default. # (see ./swarm-required-services.nix); a hive is a client by default.
# #
# Operator and agents are both subjects of the same provider, # The file backend is the right shape, not a placeholder for LDAP: what
# differentiated by roles/claims rather than by mechanism — there is one # makes a directory necessary is the size of the subject set, and this
# IdP and one auth path. The users store is written by a program # one is bounded by a swarm. Who writes that store, and why it is a
# (`swarm-authelia-bridge`, see that option's doc comment), not # program rather than a config file, is in `docs/swarm/sso.md`.
# maintained by hand: agents are created and destroyed continuously, so
# the subject set is *dynamic*. That is also why the file backend is
# right here, not a placeholder for LDAP: what makes a directory
# necessary is the size of the subject set, bounded by one swarm.
# #
# Two roles: a **session** provider always, an **OIDC** provider when # `docs/swarm/sso.md` owns the role model — session provider always, OIDC
# `oidc.clients` is non-empty (derived, not flagged). In practice OIDC # provider derived from the client list — and the secrets map.
# is always on now: the bridge needs its own machine-client identity for
# its introspection calls, contributed unconditionally, not behind
# `oidc.hiveIdentities`. Secrets map: docs/swarm/sso.md.
# #
# Per-service integration — putting authelia's `auth_request` in front # Per-service integration — putting authelia's `auth_request` in front
# of the gateway's existing `auth_basic` locations — is deliberately NOT # of the gateway's existing `auth_basic` locations — is deliberately NOT
@ -183,9 +176,8 @@ let
redirectUris = [ ]; redirectUris = [ ];
}; };
# authelia refuses to start with an OIDC provider that has no clients, # Derived from the client list rather than carrying its own `enable`;
# so the provider is derived from the client list rather than carrying # `docs/swarm/sso.md` says why that is one fact instead of two.
# its own `enable`: one fact, and it cannot contradict itself.
# #
# ⚠️ In practice this is now unconditionally `true` whenever the module # ⚠️ In practice this is now unconditionally `true` whenever the module
# is enabled: `bridgeClient` above is an unconditional definition of # is enabled: `bridgeClient` above is an unconditional definition of