The api service now also receives FRONT_API_SECRET so AuthenticateJWT
accepts the UI's server-side JWT forwards instead of blacklisting them
on UA mismatch. On the ui service the var is renamed FRONT_API_SECRET ->
NUXT_API_SECRET so Nuxt's runtimeConfig.apiSecret is actually populated
(NUXT_<key> convention) and injected as x-api-secret, short-circuiting
the UA-fingerprint check that otherwise 401s every reload.
- authentik: address the rewrite service by compose service name instead
of a network alias on the public FQDN, which shadowed extra_hosts pins
and broke OIDC discovery for c-ares-based (Node) resolvers
- homarr: add homarr_extra_hosts to pin the IdP FQDN to a LAN IP so OIDC
discovery stays in-network while the issuer matches the browser-facing URL
- opnform: add opnform_oidc_sso_redirect_root to 302 the root URL to the
SSO path (deep-links untouched, /login?bypass=1 break-glass); restart
ingress via container restart so envsubst re-renders nginx.conf
- nextcloud: make the UserConfig sed workaround fail loud on upstream
drift instead of silently skipping (nextcloud/server#59629)
- gitignore: exclude the local .ansible/ collection cache
Bundle of cross-role changes for the gymb services deployment:
- Traefik routers: OR-combine opnform/homarr/bookstack Host rules with new
*_extra_domains (internal *.int.* FQDNs for a DMZ reverseproxy), and emit
tls.certresolver only when traefik_cert_mode == acme (drawio, homarr,
opnform, send).
- Split-horizon: bookstack_extra_hosts / opnform_extra_hosts add container
/etc/hosts overrides so containers reach the IdP public FQDN over the LAN.
- bookstack: assert the OIDC issuer resolves concretely (reject "//v2.0"),
allowing non-Entra IdPs that override bookstack_oidc_issuer.
- homarr: derive the bcrypt salt from the password digest so the admin hash
is idempotent — no spurious template changes / container restarts.
- opnform: PATCH an existing OIDC connection instead of skipping (applies
corrected inventory on re-run); add OIDC_FORCE_LOGIN (enabled only after
bootstrap) and an optional direct-SSO ingress entrypoint.
Docs: READMEs and meta/argument_specs.yml updated for all new variables.
Rename roles/OpnForm → roles/opnform so the role resolves as
digitalboard.core.opnform (Ansible collection convention is
lowercase). Update tests/test.yml reference accordingly.
Add automated admin user creation via POST /api/register, gated on
opnform_admin_email + opnform_admin_password. Idempotent through a
prior login probe. Without these vars the manual setup page flow is
preserved.
Add automated OIDC IdentityConnection setup via the per-workspace
/api/open/workspaces/{id}/oidc-connections endpoint, gated on
opnform_oidc_enabled. Hard-coupled to the admin bootstrap (the API
requires an authenticated admin token); validation block fails fast
if OIDC is enabled without admin credentials. Supports both an
explicit opnform_oidc_group_role_mappings list and a fallback
opnform_oidc_admin_group convenience var.
Convert opnform_oidc_scopes from space-separated string to YAML list
to match OpnForm's API expectation. Rewrite README "First login" and
"OIDC setup" sections to reflect that self-hosted OpnForm does not
ship a pre-seeded admin and to document the new bootstrap paths.
BREAKING CHANGE: opnform_oidc_scopes changed from space-separated
string to YAML list. Inventories that override it must update from
"openid profile email" to [openid, profile, email].