feat(demo): add full inventories for mbazürich and phbern #2

Open
Simon wants to merge 5 commits from feat/demo-mbaz-phbe-inventories into main

5 commits

Author SHA1 Message Date
Simon Bärlocher
d45e358efc
feat(demo): add full inventories for mbazürich and phbern
Both demo sites had only a hosts.yml, so every role ran on its
defaults (authentik.local.test etc.) and nothing was reachable under
the real FQDN. Add the complete group_vars + host_vars analogous to
gymburgdorf, with the mbaz.souveredu.ch / phbe.souveredu.ch domain
bases, matching Bao mounts, DMZ split-horizon (public + *.int.*),
authentik OIDC/LDAP/proxy outposts, nextcloud with S3+LDAP+OIDC,
collabora, drawio, garage, send, opnform, homarr and bookstack.

authentik_domains lists the *.int.* name too so Traefik requests a
cert the DMZ can verify; the storage proxy outpost carries a config
block (required by the outpost blueprint serializer).
2026-07-02 17:22:21 +02:00
Simon Bärlocher
a8c8ac3e1e
fix(bao-seed): seed proxy_outpost_token, garage and nextcloud secrets
The seed script only generated authentik LDAP, opnform, homarr and
bookstack secrets. Proxy outposts, garage and nextcloud were never
seeded, so a fresh demo mount was missing garage/*, nextcloud/* and
authentik/proxy_outpost_token — the proxy outpost then failed to
authenticate (403) and garage/nextcloud roles aborted on missing vault
keys. Add the three blocks; merge semantics keep existing keys.
2026-07-02 17:22:08 +02:00
Simon Bärlocher
91d5be8d21
fix(demo-gymburgdorf): verify authentik TLS chain from outposts
Both outposts reach authentik over auth.gymb.*, which presents a valid
Let's Encrypt cert via the reverseproxy (verified: ssl_verify_result=0
from the storage subnet). Drop the insecure TLS skip:

- proxy outpost: authentik_outpost_proxy_insecure -> "false"
- ldap outpost: pin authentik_outpost_ldap_insecure "false" instead of
  relying on the role default ("true").

Addresses the automated security review finding (TLS verification disabled).
2026-06-05 14:29:18 +02:00
Simon Bärlocher
e32c2202ea
feat(demo-gymburgdorf): gate garage-webui via storage-local proxy outpost
Finish the garage-webui SSO that the DNS cleanup left broken. Two coupled
fixes, both relying on roles added in digitalboard.core:

- console.s3 now has an internal name. garage_webui_domains lists both the
  public and console.s3.int.* FQDN, and the DMZ garage-webui route sets
  backend_host: console.s3.int.* so the DMZ->storage hop verifies the
  backend cert against a matching SAN instead of failing on a raw IP (500).

- garage-webui ForwardAuth moves off the embedded outpost (cross-host hop
  mangled X-Forwarded-Host -> 404) onto a dedicated proxy outpost deployed
  on storage (authentik_outpost_proxy). The garage Traefik middleware now
  talks to it over the local docker network, and the storage-proxy-outpost
  is registered in authentik with the garage-webui provider. The stale
  auth.gymb pin on storage is dropped; the outpost reaches authentik via
  the reverseproxy (firewall now permits backend -> DMZ).

Requires a new bao secret key: <mount>/data/authentik proxy_outpost_token.
2026-06-05 14:27:37 +02:00
Simon Bärlocher
2942dabc54
refactor(demo-gymburgdorf): drop DNS workarounds now backend can reach DMZ
The firewall now permits the backend subnet (172.16.19.0/24) to reach the
DMZ reverseproxy on 443, so server-to-server calls can use the public
FQDN over the reverseproxy instead of the previous workarounds:

- Remove the `*_extra_hosts` pins from nextcloud, opnform, bookstack and
  homarr; their OIDC discovery/issuer now uses the public auth.gymb.* FQDN
  (verified: discovery returns 200 with the public iss over the reverseproxy).
- Switch nextcloud OIDC discovery_url from auth.int.* to auth.gymb.*.
- Drop authentik_host_rewrite_domains and authentik_outpost_domains; point
  the LDAP outpost (both host_vars) at the public auth.gymb.* FQDN.
- Repoint the garage-webui ForwardAuth from the never-functional dedicated
  outpost FQDN to auth.gymb.*. The embedded outpost only serves the auth
  path when Host is a configured authentik_domain and matches the protected
  app via X-Forwarded-Host, so auth.gymb.* stays pinned to the application
  host on storage to bypass the reverseproxy's X-Forwarded-Host stripping.

The *.int.* names and their cert SANs are kept: the DMZ verifies the
backend cert (acme cert_mode) and connects by name, so they remain
structural to the DMZ->backend hop. The console.s3 DMZ route limitation
is pre-existing and tracked separately.
2026-06-05 13:49:30 +02:00