fix(dev-sso): route Traefik labels on Compose 2.40 + shared Traefik #47

Merged
longjacksonle merged 1 commit from fix/dev-sso-traefik-label-interpolation into main 2026-05-28 23:00:23 +02:00

Problem

just dev-sso never routed https://${USER}-mokosh-api.a8n.run. Hitting the host returned the Traefik default self-signed cert and a 404 page not found. Two independent bugs in compose.dev-sso.yml, each sufficient on its own to break routing.

Bug 1: map-syntax label keys are not interpolated

Docker Compose interpolates ${USER} inside mapping VALUES but NOT inside mapping KEYS (verified on Compose v2.40.0; docker compose config renders the key as mokosh-api-$${USER} while the value renders as long). The Traefik router name lives in the label key, so map syntax baked a literal ${USER} into the router name. Traefik rejects that name and creates no router. Converting the four traefik.* labels to list (sequence) syntax puts the whole key=value into a single string value, so ${USER} interpolates in the router name too.

Bug 2: wrong entrypoint name

The labels pinned the router to web-secure, which on the shared a8n.run Traefik is :20443 (bound to the LAN IP). Public HTTPS for *.a8n.run lands on the nebula-secure entrypoint (:443, asDefault=true) - the same entrypoint every other working app on that Traefik uses (syncthing, cadvisor, netdata). Switched to nebula-secure.

Verification

With both fixes, the OIDC IdP serves a valid Let's Encrypt cert and a complete discovery document over the Nebula overlay:

  • /api/v1/version returns the server JSON
  • /.well-known/openid-configuration returns issuer: https://long-mokosh-api.a8n.run and all endpoints
  • /.well-known/jwks.json returns the EdDSA dev-key
  • TLS cert issuer is Let's Encrypt, not the Traefik default

Follow-up (separate repo)

mokosh-clients/compose.dev-sso.yml has the identical pair of bugs (mokosh-${USER} map key + web-secure entrypoint) and needs the same change for the client SSO stack to route.

🤖 Generated with Claude Code

## Problem `just dev-sso` never routed `https://${USER}-mokosh-api.a8n.run`. Hitting the host returned the Traefik default self-signed cert and a `404 page not found`. Two independent bugs in `compose.dev-sso.yml`, each sufficient on its own to break routing. ## Bug 1: map-syntax label keys are not interpolated Docker Compose interpolates `${USER}` inside mapping VALUES but NOT inside mapping KEYS (verified on Compose v2.40.0; `docker compose config` renders the key as `mokosh-api-$${USER}` while the value renders as `long`). The Traefik router name lives in the label key, so map syntax baked a literal `${USER}` into the router name. Traefik rejects that name and creates no router. Converting the four `traefik.*` labels to list (sequence) syntax puts the whole `key=value` into a single string value, so `${USER}` interpolates in the router name too. ## Bug 2: wrong entrypoint name The labels pinned the router to `web-secure`, which on the shared a8n.run Traefik is `:20443` (bound to the LAN IP). Public HTTPS for `*.a8n.run` lands on the `nebula-secure` entrypoint (`:443`, `asDefault=true`) - the same entrypoint every other working app on that Traefik uses (syncthing, cadvisor, netdata). Switched to `nebula-secure`. ## Verification With both fixes, the OIDC IdP serves a valid Let's Encrypt cert and a complete discovery document over the Nebula overlay: - `/api/v1/version` returns the server JSON - `/.well-known/openid-configuration` returns `issuer: https://long-mokosh-api.a8n.run` and all endpoints - `/.well-known/jwks.json` returns the EdDSA `dev-key` - TLS cert issuer is `Let's Encrypt`, not the Traefik default ## Follow-up (separate repo) `mokosh-clients/compose.dev-sso.yml` has the identical pair of bugs (`mokosh-${USER}` map key + `web-secure` entrypoint) and needs the same change for the client SSO stack to route. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(dev-sso): route Traefik labels correctly on Compose 2.40 + shared Traefik
All checks were successful
Check / fmt + clippy + compile + tests (pull_request) Successful in 25s
Create release / Create release from merged PR (pull_request) Has been skipped
d13ba4032b
Two independent bugs kept `just dev-sso` from ever routing `https://${USER}-mokosh-api.a8n.run`; both produced the same symptom (Traefik default cert + 404).

1. Map-syntax label keys don't interpolate. Docker Compose interpolates `${USER}` inside mapping VALUES but not inside mapping KEYS (verified on Compose v2.40.0). Because the Traefik router name lives in the label key, map syntax left a literal `${USER}` in the router name, which Traefik rejects, so no router was created. Converting the four `traefik.*` labels to list (sequence) syntax puts the whole `key=value` in a single string value, so `${USER}` interpolates in the router name too.

2. Wrong entrypoint name. The labels pinned the router to `web-secure`, which on the shared a8n.run Traefik is `:20443` (LAN-IP bound). Public HTTPS for `*.a8n.run` lands on the `nebula-secure` entrypoint (`:443`, `asDefault=true`), which is what every other working app on that Traefik (syncthing, cadvisor, netdata) uses. Switched to `nebula-secure`.

Verified: with both fixes the OIDC IdP serves a valid Let's Encrypt cert and a complete discovery document over the Nebula overlay. mokosh-clients/compose.dev-sso.yml has the identical pair of bugs and needs the same change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch fix/dev-sso-traefik-label-interpolation 2026-05-28 23:00:23 +02:00
Author
Owner

Scope expanded beyond the original title. This branch now also:

  • Migrates the dev SSO domain from a8n.run to a8n.systems (router Host rule, MOKOSH_AUTH_ISSUER, MOKOSH_AUTH_COOKIE_DOMAIN, MOKOSH_ACCEPT_BASE_URL, MOKOSH_AUTH_LOGIN_URL). Routing + OIDC discovery/JWKS verified live on a8n.systems over the Nebula overlay.
  • Adds dev-docs/sso-dev.md, a runbook for just dev-sso (Nebula DNS via /etc/hosts, cert prerequisites, client registration, troubleshooting), plus its dev-docs/README.md index row.

Infra prerequisite for trusted TLS on the new domain: the shared Traefik's Cloudflare ACME token (CF_DNS_API_TOKEN / CF_ZONE_API_TOKEN in the network-traefik project) must include the a8n.systems zone. Until then ACME fails with cloudflare: failed to find zone a8n.systems and Traefik serves its default cert; routing still works. Documented in the runbook troubleshooting table.

Scope expanded beyond the original title. This branch now also: - Migrates the dev SSO domain from `a8n.run` to `a8n.systems` (router Host rule, `MOKOSH_AUTH_ISSUER`, `MOKOSH_AUTH_COOKIE_DOMAIN`, `MOKOSH_ACCEPT_BASE_URL`, `MOKOSH_AUTH_LOGIN_URL`). Routing + OIDC discovery/JWKS verified live on `a8n.systems` over the Nebula overlay. - Adds `dev-docs/sso-dev.md`, a runbook for `just dev-sso` (Nebula DNS via `/etc/hosts`, cert prerequisites, client registration, troubleshooting), plus its `dev-docs/README.md` index row. Infra prerequisite for trusted TLS on the new domain: the shared Traefik's Cloudflare ACME token (`CF_DNS_API_TOKEN` / `CF_ZONE_API_TOKEN` in the `network-traefik` project) must include the `a8n.systems` zone. Until then ACME fails with `cloudflare: failed to find zone a8n.systems` and Traefik serves its default cert; routing still works. Documented in the runbook troubleshooting table.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-server!47
No description provided.