Files
computer-playbook/TODO.md
T
kevinveenbirkenbachandClaude Opus 5 8d1d45d246 fix(discourse): pin the OIDC issuer for the launcher-built container
Nextcloud#7 of run 33445831564 fails on three discourse specs, all on one
assertion, all for one reason. The received body is Discourse's own page:
"Sorry, there was an error while trying to authorize your account with oidc."

The browser leg works. What dies is Discourse's server-side back-channel:

    "GET /auth/oidc/callback?...code=..."  302  2.125 2.125
    "GET /auth/failure?message=openid_connect_request_failed&...&strategy=oidc"  200

Four of those, at 2.125 / 2.015 / 2.063 / 2.014 seconds. That is not the plugin's
10s HTTP timeout; it is Discourse's DNS budget, hard-coded at 2s in
lib/final_destination/resolver.rb (connect_timeout arrives nil, so the default
applies). openid_connect_request_failed has exactly one emitter --
omniauth_open_id_connect.rb:147-155, rescue Faraday::Error -- and the alternative,
SocketError -> LookupFailedError, is not a Faraday::Error and would have produced a
500 rather than the observed 302.

The correlation leaves no room: across 18 back-channel requests, all from
192.168.9.3 with UA Faraday v2.14.3, there are exactly two complete token 200 +
userinfo 200 pairs -- and exactly two specs passed. Thirteen truncated flows,
thirteen failures. No test that got a complete exchange failed; none that failed got
one.

Why discourse alone: discourse.inspect.json:72 reads "ExtraHosts": null. Grepping the
whole rescue bundle for the pin finds nextcloud, nextcloud-proxy, mailu-admin,
prometheus and prometheus-sso-proxy. Discourse could not have it: config.yml.j2's
docker_args: carried only --network= and --name=. It is built by discourse_docker's
launcher, not by a compose file, so the lookup's rendered block has nowhere to go --
hence entries_only, which returns the strings and lets the template write
--add-host= lines. The pin itself is NOT re-derived: _sso_pins() and
_gateway_address() stay the single place that knows compose from swarm.

Its existing allowed_internal_hosts cannot help, because ssrf_detector's
lookup_and_filter_ips resolves BEFORE host_bypasses_checks?; the setting only makes a
private answer acceptable once it arrives.

Rendered through a real Templar both ways: with SSO on, the two --add-host lines land
between the networks and --name; with SSO off the output is byte-identical to today,
so clearnet and variant-1 deployments render an unchanged app.yml and trigger no
launcher rebuild. 24 lookup tests green.

Not closed: the biber persona has never passed, here or in run 33317483326. Its
failure text and code path match administrator, which did pass, so it is explained --
but a persona-specific second defect is not positively excluded. Deploying discourse
variant 0 locally, which already has sso and tor enabled, settles it.

Separately worth queueing: discourse's own meta/variants.yml variant 1 sets
sso.enabled: false and only variant 1 is scheduled, so the role that owns these specs
never runs them. Only partner rounds like Nextcloud#7 catch this class.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-01 12:00:56 +02:00

7.6 KiB
Raw Blame History

Todos

  • Implement multi language
  • Implement rbac administration interface
  • Enable IP6 for docker.
  • backup docker to local für ca optimieren
  • Fork rpardini/docker-registry-proxy and teach the bundled nginx to handle GCP Artifact Registry redirect URLs (/artifacts-downloads/namespaces/<ns>/repositories/<repo>/downloads/<token>). Currently gcr.io blob pulls are bypassed via NO_PROXY=…,gcr.io,storage.googleapis.com,googleusercontent.com in compose/registry-cache/proxy.conf, which is a workaround that disables caching for those registries. Long-term: rebase upstream's proxy.conf / sub_filter rules to recognise the new redirect shape, ship the fix in our fork, point compose/registry-cache/Dockerfile (or its image tag) at the fork, and drop the NO_PROXY bypass.

Testing

  • re-run with different credentials/configuration
  • run over all distros for each app
  • msg: can not use content with a dir as dest for NGINX multi distro
  • split service database to postgres and mariadb

Onion e2e (feature/svc-net-tor) — remaining failures

Status after deploy-matrix run 29657147883 (commit 407b8a8a1). Every fixable failure class from that run is committed (hlth-csp onion-sibling skip, onion-aware Playwright request timeouts + lint guard, joomla server-side OIDC reachability). The items below are the ones that are NOT fixed yet. Runs 31756400129 and 31756560361 have since moved several of them; entries corrected against those runs say so inline.

  • https on the onion IdP — investigated and REJECTED, do not re-derive. OIDC Discovery / RFC 8414 want an https issuer, and an onion-exclusive Keycloak has none, so strict client libraries refuse it. Serving TLS on the onion is blocked on four independent things, in this order: (1) roles/svc-net-tor/templates/torrc.j2 publishes only HiddenServicePort 80, and no role declares 443 in ports.public/ports.local, so lookup('tor_ports') can never emit it — flipping TLS on first makes Keycloak unreachable over Tor entirely, because nginx_ssl_header.j2 is one if/else and port 80 disappears; (2) roles/sys-front-tls-selfsigned/tasks/00_core.yml writes an unguarded CN, which overflows X.509's 64-byte cap on a 62-char v3 onion — group_vars/all/02_tls.yml already guards exactly this for the root CA and nowhere else; (3) nginx_ssl_header.j2 emits HSTS in the same branch, and browsers offer no click-through on an HSTS host with an untrusted chain, so a self-signed interim locks real users out while staying invisible to Playwright's ignoreHTTPSErrors; (4) it fixes zero libcurl consumers, because RFC 7686 refusal happens at name resolution and is scheme-independent. Unblocking needs a CA that issues for v3 .onion (HARICA, CA/B Forum ballot 144) — procurement, not code. Until then the per-consumer fixes stand: SOCKS proxy for libcurl clients. peertube is no longer among them - it is a clearnet-only role.

  • dual-family providers — the one real remaining design gap. On a CI onion node, tor-enabled providers (e.g. mastodon) are onion-exclusive: their domain list contains only the .onion canonical, no clearnet sibling. The family-alignment resolver (utils/tls_common.py:align_domain_to_consumer, wired into plugins/lookup/tls.py) correctly bails in that case, so a clearnet-pinned consumer still receives an onion URL it can neither resolve nor reach. First hard evidence: web-app-fediwall variant 2 (tor=false) renders microblog.<onion> into wall-config.json.servers; the clearnet browser (no SOCKS) times out waiting for mastodon wall items (test-walls-surface-posts.js:24, deterministic across retries). The same class is expected to keep web-app-bigbluebutton, web-app-nextcloud, web-app-opentalk and web-app-jitsi red (clearnet-pinned apps whose peer refs — OIDC/cdn/matomo/logout — resolve onion-primary). Fix direction: providers must publish BOTH families (clearnet sibling alongside the onion canonical) so the resolver has something to align to; includes re-applying the deferred KC_HOSTNAME onion-gate for Keycloak that was dropped from the earlier bundle because it is only needed once dual-family exists.

  • joomla local-login fallback spec — test-oidc-fallback.js:52 (the ?fallback=local emergency hatch: local Joomla admin form login must reach the control panel). Root cause UNCONFIRMED. It is independent of the fixed OIDC-login spec: the fallback path short-circuits before the plugin's server-side discovery, so the committed extra_hosts fix does not cover it. The secure => true sticky-cookie hypothesis was rejected (.onion is a potentially-trustworthy origin and the e2e Firefox sets dom.securecontext.allowlist_onions, so Secure cookies are accepted over plain-http onion). Next step when it fails again post-fix: isolate the post-submit URL — Keycloak redirect (cookie lost) vs. form reject vs. slow control-panel render.

  • matomo container health flake (checkmk batch) — in the checkmk job the 4th deploy play failed at Wait for Matomo container to be healthy with container inspect: map has no entry for key "State" for the whole retry window (container started, then vanished — likely crash + prune). Plays 1–3 in the SAME job deployed matomo healthy, so classified transient (resource/prune pressure after ~3h). No code fix derivable. If it recurs, investigate as a real matomo crash/OOM (container logs, mem_limit).

  • server-side OIDC reachability candidates — joomla failed because its app container performs server-side OIDC discovery against http://auth.<onion> without an extra_hosts mapping. Roles with the same mechanic and no container_extra_hosts lookup yet (fix is the same one-line lookup, apply on CI evidence): wordpress (daggerhart plugin) and mediawiki (PluggableAuth) are structurally identical PHP in-app plugins (high likelihood); discourse is now confirmed and pinned (run 33445831564, job Nextcloud#7); jenkins, jira, confluence, odoo, openwebui, pretix, zammad, semaphore, jellyfin, listmonk, xwiki, mastodon consume the issuer server-side too (unverified network path). oauth2-proxy-based apps are NOT affected (proven green: prometheus admin SSO). Two names have left this list on evidence: mobilizon got the lookup in 0e39f3fad after its code-to-token call raised OAuth2.Error Connection refused twenty-four times, and gitlab was NEVER a member - run 31756560361 shows it resolving and connecting (peeraddr=172.30.0.10:443); its failure was the openid_connect gem rebuilding the discovery URL over https regardless of the issuer scheme, fixed in 2389b6e38.

  • baseline exclusions — web-app-fider and web-app-bookwyrm (also keycloak-job, n8n) were red before the tor branch and stay out of scope for it; bookwyrm fails its oauth2 trusted-header session spec, fider its baseline. Fix separately from the onion work. espocrm has left this list: its onion variant failed in the shared admin persona (fixed in b97cf8888) and its clearnet variant returns HTTP 500 on GET /api/v1/App/user, cause still open.

  • test-development environment jobs — all 5 distro jobs (arch, debian, ubuntu, fedora, centos) hit the 4h30m cap under congestion while still progressing (playwright image pull). Environmental, no code fix - distinct from the distro sweep's own budget, which did have one: 508669809 books a budget SIGKILL as skipped, which ad9222630 had only done for SIGTERM; note that onion e2e inherently lengthens the routine (×5 onion timeouts, circuit waits), so under congestion these jobs are the first to hit the cap.