fix: render a client field that only half the list carries

allClients concatenates two shapes: cfg.oidc.clients comes through the
submodule and carries every option default, hiveClients is a raw attrset
built in the let block with four fields. renderClient read
tokenEndpointAuthMethod plainly, which is fine for a declared client and
an eval error for a derived one -- so all-local, where hiveIdentities is
on, stopped evaluating.

Read it with `or null`. The comment records that the list is not
uniformly typed, because the next field added to that submodule has the
same trap waiting.
This commit is contained in:
atlas 2026-08-16 20:03:42 +02:00 committed by mara
commit f5fdbaae1a

View file

@ -144,7 +144,19 @@ let
printf -- " client_secret: '%s'\n" "$(cat ${lib.escapeShellArg "${clientsDir}/${c.id}.digest"})"
printf -- ' authorization_policy: one_factor\n'
''
+ lib.optionalString (c.tokenEndpointAuthMethod != null) ''
# ⚠️ `or null`, and it is not defensive noise: `allClients` is NOT
# uniformly submodule-typed. `cfg.oidc.clients` entries come through
# the submodule and carry every option's default; `hiveClients` is a
# raw attrset built in this file's `let` block and carries only the
# four fields written there. So a field added to the submodule exists
# on one half of this list and not the other, and reading it plainly
# is an eval error the moment `hiveIdentities` is on.
#
# That is exactly how this broke: `tokenEndpointAuthMethod` was added
# to the submodule and read here, which is fine for a declared client
# and fatal for a derived one. Anything read here needs `or` unless
# every producer is known to set it.
+ lib.optionalString ((c.tokenEndpointAuthMethod or null) != null) ''
printf -- ' token_endpoint_auth_method: %s\n' ${lib.escapeShellArg c.tokenEndpointAuthMethod}
''
+ (