Skip to content

ADR-0011 — Same-origin /api on the apex: the one exception to the flat-subdomain scheme

  • Status: accepted
  • Date: 2026-07-02
  • Domain: routing · conventions

Context

The lab's locked convention is flat subdomains: every service is <name>.tarik-lab.dev. The front door at the apex now needs to call the exhibits backend from browser JavaScript. Under the flat scheme that backend would live at something like lab.tarik-lab.dev, which is a cross-origin call from tarik-lab.dev: CORS headers on the API, preflight requests, and the API hostname advertised in the page source.

Decision

Route tarik-lab.dev/api/* to the lab-api service via a Traefik PathPrefix rule with priority above the webapp's apex router. The page and its API share an origin: no CORS, no preflights, one hostname in the browser. This is a documented, single exception to the flat scheme — the apex was already the scheme's one exception (it serves the portfolio instead of a service), and the exhibits API is functionally part of that page, not an independent service surface.

Constraint: the router priority must not shadow Traefik's ACME HTTP-01 path (/.well-known/acme-challenge/*) — verified in the CP11 security review.

Consequences

  • Zero CORS configuration, which means zero risk of the classic failure mode (a wildcard-origin header added "temporarily" and never removed).
  • The exception is contained: exactly one path prefix on exactly one hostname; every other service still follows the flat scheme. The conventions doc gains one line.
  • lab-api is reachable only under /api on the apex — it has no subdomain of its own, which keeps the public surface minimal.

Alternatives considered

  • lab.tarik-lab.dev + CORS — rejected: keeps the scheme pure at the cost of a permanent CORS bug class and an extra advertised hostname.
  • Serve the page from FastAPI itself — rejected: breaks the webapp's single-static-file invariant and couples page deploys to API deploys for no gain.