Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd4b79f04a | ||
|
|
f5fdbaae1a |
1 changed files with 34 additions and 14 deletions
|
|
@ -79,6 +79,14 @@ let
|
|||
# per service from it. Were the queue to declare this list, the next
|
||||
# consumer would collide on the same client id — and only at the
|
||||
# moment it landed.
|
||||
#
|
||||
# Fed to the option as a DEFINITION in the config block below, rather
|
||||
# than appended to the declared list downstream. That is what puts it
|
||||
# through the submodule: one list, one type, every option's default
|
||||
# present. Appending a raw attrset instead left the list half-typed —
|
||||
# and a field later added to the submodule then existed on the
|
||||
# declared entries and not on these, which is an eval error reachable
|
||||
# only once hive identities are on.
|
||||
hiveClients = lib.mapAttrsToList (name: _: {
|
||||
id = "hive-${name}";
|
||||
description = "HyperHive hive ${name}";
|
||||
|
|
@ -86,21 +94,18 @@ let
|
|||
redirectUris = [ ];
|
||||
}) hyperhiveCfg.swarm.hives;
|
||||
|
||||
# Everything downstream renders and mints from this, not from the
|
||||
# declared list alone.
|
||||
allClients = cfg.oidc.clients ++ lib.optionals cfg.oidc.hiveIdentities hiveClients;
|
||||
|
||||
# authelia refuses to start with an OIDC provider that has no clients,
|
||||
# so the provider is derived from the client list rather than carrying
|
||||
# its own `enable`: one fact, and it cannot contradict itself. An empty
|
||||
# list is the default, which makes every hive that has not opted in
|
||||
# byte-identical to before.
|
||||
#
|
||||
# ⚠️ Derived from `allClients`, so hive identities can turn the provider
|
||||
# on by themselves. That is only reachable where the queue is already
|
||||
# enabled (`hiveIdentities` defaults to it) — and a queue-enabled hive
|
||||
# already contributes a client, so no existing deployment flips.
|
||||
oidcEnabled = allClients != [ ];
|
||||
# ⚠️ The derived hive identities are definitions of this same option,
|
||||
# so they can turn the provider on by themselves. That is only
|
||||
# reachable where the queue is already enabled (`hiveIdentities`
|
||||
# defaults to it) — and a queue-enabled hive already contributes a
|
||||
# client, so no existing deployment flips.
|
||||
oidcEnabled = cfg.oidc.clients != [ ];
|
||||
|
||||
# Secrets that are 64 random bytes of hex and nothing more. The OIDC
|
||||
# hmac key joins them; the issuer key does not (see below — it is RSA).
|
||||
|
|
@ -144,6 +149,11 @@ let
|
|||
printf -- " client_secret: '%s'\n" "$(cat ${lib.escapeShellArg "${clientsDir}/${c.id}.digest"})"
|
||||
printf -- ' authorization_policy: one_factor\n'
|
||||
''
|
||||
# Read plainly, and that is a property of the list rather than of
|
||||
# this line: every entry reaching here is a definition of
|
||||
# `oidc.clients`, so the module system has applied the submodule and
|
||||
# each option's default is present. A derived entry that names only
|
||||
# the fields it cares about still arrives with the rest filled in.
|
||||
+ lib.optionalString (c.tokenEndpointAuthMethod != null) ''
|
||||
printf -- ' token_endpoint_auth_method: %s\n' ${lib.escapeShellArg c.tokenEndpointAuthMethod}
|
||||
''
|
||||
|
|
@ -219,7 +229,7 @@ let
|
|||
|
||||
${lib.concatMapStrings (c: ''
|
||||
mint ${lib.escapeShellArg c.id}
|
||||
'') allClients}
|
||||
'') cfg.oidc.clients}
|
||||
|
||||
# Re-rendered every boot, deliberately: the secret is minted once,
|
||||
# but the metadata around it (a new redirect URI, a renamed client)
|
||||
|
|
@ -230,7 +240,7 @@ let
|
|||
printf -- 'identity_providers:\n'
|
||||
printf -- ' oidc:\n'
|
||||
printf -- ' clients:\n'
|
||||
${lib.concatMapStrings renderClient allClients}
|
||||
${lib.concatMapStrings renderClient cfg.oidc.clients}
|
||||
} > ${lib.escapeShellArg "${clientsFile}.tmp"}
|
||||
chmod 0600 ${lib.escapeShellArg "${clientsFile}.tmp"}
|
||||
mv ${lib.escapeShellArg "${clientsFile}.tmp"} ${lib.escapeShellArg clientsFile}
|
||||
|
|
@ -538,6 +548,14 @@ in
|
|||
};
|
||||
|
||||
config = lib.mkIf (hyperhiveCfg.enable && cfg.enable) {
|
||||
# The derived half of the client list, declared the same way an
|
||||
# operator declares one. Everything downstream then reads a single
|
||||
# uniformly-typed `cfg.oidc.clients` and cannot tell the two apart —
|
||||
# including the assertions below, which is why a hive named `x`
|
||||
# colliding with a declared `hive-x` is caught rather than rendered
|
||||
# twice.
|
||||
services.hyperhive.swarm.authelia.oidc.clients = lib.mkIf cfg.oidc.hiveIdentities hiveClients;
|
||||
|
||||
# A redirect URI on a machine client is not harmless-but-unused: it
|
||||
# means whoever wrote it believes a browser is involved. Failing here
|
||||
# is how that belief gets corrected at the point it was expressed,
|
||||
|
|
@ -550,7 +568,7 @@ in
|
|||
+ "kind = \"machine\" but declares redirectUris. A client_credentials "
|
||||
+ "client has nobody to redirect; drop the URIs or make it "
|
||||
+ "kind = \"interactive\".";
|
||||
}) allClients
|
||||
}) cfg.oidc.clients
|
||||
# Two clients sharing an id renders two YAML entries under one name.
|
||||
# Newly reachable now that part of the list is DERIVED: a hive called
|
||||
# `x` and a service client called `hive-x` never met before. Authelia
|
||||
|
|
@ -558,12 +576,14 @@ in
|
|||
# sources here is the cheaper failure.
|
||||
++ [
|
||||
{
|
||||
assertion = lib.length (lib.unique (map (c: c.id) allClients)) == lib.length allClients;
|
||||
assertion = lib.length (lib.unique (map (c: c.id) cfg.oidc.clients)) == lib.length cfg.oidc.clients;
|
||||
message =
|
||||
"services.hyperhive.swarm.authelia: duplicate OIDC client id(s): "
|
||||
+ lib.concatStringsSep ", " (
|
||||
lib.unique (
|
||||
lib.filter (id: lib.count (x: x == id) (map (c: c.id) allClients) > 1) (map (c: c.id) allClients)
|
||||
lib.filter (id: lib.count (x: x == id) (map (c: c.id) cfg.oidc.clients) > 1) (
|
||||
map (c: c.id) cfg.oidc.clients
|
||||
)
|
||||
)
|
||||
)
|
||||
+ ". Hive identities are named `hive-<name>` from "
|
||||
|
|
|
|||
Loading…
Reference in a new issue