ByteBite Docs
ArchitectureADRs

ADR-014: Tenant Resolution

Status: Accepted

Kontext

Restaurants verwenden ByteBite-Subdomains oder eigene Domains. Der Tenant darf nicht durch einen frei manipulierbaren Client-Parameter bestimmt werden.

Entscheidung

Der Tenant wird primär über den Hostname/Domainnamen aufgelöst.

hostname
  -> restaurant_domains.hostname
  -> restaurant_id

Konsequenzen

  • Subdomains und Custom Domains verwenden denselben Mechanismus.
  • Domainverifikation ist Bestandteil des Onboardings.
  • Unbekannte oder nicht verifizierte Hosts werden abgelehnt.
  • restaurantId aus Query, Body oder Client-Headern ist keine Tenant-Autorität.

Interne Storefront-SSR-Aufrufe

Browser-Requests (einschließlich same-origin /api) liefern den Tenant über den Host-Header. Traefik erhält den Browser-Host und leitet ihn an Fastify weiter. trustProxy ist nicht aktiv; X-Forwarded-Host von Clients wird nicht als Tenant verwendet.

Next.js Server-Komponenten rufen Fastify intern über API_INTERNAL_URL (http://api:3001). Dabei wäre der Host api / api:3001, nicht das Restaurant.

Für diesen Server-zu-Server-Pfad sendet der Storefront den originalen Host in X-ByteBite-Tenant-Host. Fastify akzeptiert diesen Header nur, wenn der Request-Host die interne API-Identität ist (api, localhost, 127.0.0.1, ::1).

Öffentliche Hosts — einschließlich api.bytebite.test und luigi.bytebite.test — ignorieren den Header. Ein Browser kann damit keinen anderen Tenant wählen.

Vertrauensgrenze (interner Pfad)

X-ByteBite-Tenant-Host ist nur auf Anfragen autoritativ, die Fastify über den privaten internen Service-Pfad erreichen (API_INTERNAL_URL → Docker-Service api:3001). Der API-Container-Hostname ist nicht öffentlich exponiert; Traefik routet Browser-Anfragen über die externe Host-Domain und leitet den Header nicht als Tenant-Autorität weiter.

Öffentliche Anfragen über Traefik leiten die Tenant-Autorität ausschließlich aus dem externen Host ab. Der interne Header kann sie nicht überschreiben. Kein Header-Signing in diesem Slice.

Fehlerverhalten bei Tenant-Auflösung

  • Bekannte, aktive Domain → normaler Request
  • Unbekannte Domain → öffentliche 404 (Restaurant not found)
  • Inaktives Restaurant → öffentliche 404 (gleiche Antwort wie unbekannt)
  • Datenbank-/Infrastrukturfehler während der Hostname-Auflösung → 503 (Service Unavailable), ohne Datenbankdetails in der Antwort
  • /health und /health/db bleiben unabhängig von der Tenant-Auflösung

On this page