App-Hosting auf separater Origin
Gehostete App-Frontends (React/Svelte/Plain-mit-Source) müssen von einer
anderen registrierbaren Domain (eTLD+1) als der Control Plane ausgeliefert
werden. Würden Apps auf einer Subdomain des Control-Plane-Hosts (supacloud.run)
bereitgestellt, wären sie same-site mit der API – das JavaScript einer deployten
App könnte dann den Session-Cookie des Betreibers gegen /api verwenden. Die
Auslieferung über supacloud.net macht jeden Request cross-site, sodass
SameSite=Lax den Session-Cookie zurückhält, Cookie-Tossing unmöglich ist und
die CORS-Allowlist die Apps-Origin von Natur aus ausschließt. Das ist dasselbe
Isolationsmodell, das GitHub mit githubusercontent.com verwendet.
Das Feature ist zusätzlich durch SUPACLOUD_APPS_HOSTED_FRONTEND (Standard: false)
abgesichert. Das Flag darf nicht aktiviert werden, ohne dass eine separate
Apps-Domain konfiguriert ist – der Server verweigert in dieser Kombination den Start.
Voraussetzungen
Abschnitt betitelt „Voraussetzungen“- Eine registrierbare Domain (eTLD+1), die sich von deiner Control-Plane-Domain
unterscheidet. Für SupaCloud SaaS ist das
supacloud.net; Self-Hosting-Betreiber sollten eine eigene Entsprechung bereitstellen (z. B.myapp-content.example). - Ein Wildcard-TLS-Zertifikat für
*.yourapps.domainsowie DNS-Routing aller Subdomains auf den SupaCloud-Server. Das bw-infra-Referenz-Deployment verwendet ein Traefik-Wildcard-Zertifikat via DNS-01. - Das Runner-Image muss mit
vite --base=./neu gebaut worden sein, damit Artefakte unter beliebigen Subdomain-Roots gehostet werden können. Bis dieses Image ausgerollt ist, sollte das Flag deaktiviert bleiben.
Funktionsweise
Abschnitt betitelt „Funktionsweise“Jeder gehostete Frontend-Deployment-Eintrag erhält eine stabile, opake 80-Bit-Hex-
Subdomain (gespeichert in app_deployments.subdomain, Migration 172). Die Subdomain
wird einmalig vergeben und über Redeploys hinweg wiederverwendet, sodass die URL stabil
bleibt.
Wenn SUPACLOUD_APPS_BASE_DOMAIN gesetzt ist, wird eine Host-Dispatch-Middleware
(interfaces/http/apps_host.rs) als äußerste Schicht des Servers eingebunden. Jeder
Request, dessen Host-Header zur Apps-Domain oder einer ihrer Subdomains passt, wird
als App-Inhalt ausgeliefert und erreicht nie /api, die SPA oder die Login-Seite.
Auf der Apps-Origin werden ausschließlich GET- und HEAD-Requests akzeptiert; alle
anderen Methoden erhalten 405. Die pfadbasierte Route (/a/{workspace}/{route})
lehnt gehostete Frontends ab, wenn eine Apps-Domain konfiguriert ist – jede gehostete
App ist daher ausschließlich über ihre opake Subdomain erreichbar.
Der Boot-Guard in secret_hydration.rs lehnt einen apps_base_domain-Wert ab, der
eine eTLD+1 mit der Control Plane teilt (in beiden Richtungen geprüft via der
psl-Public-Suffix-Liste). Eine falsch konfigurierte Domain führt also zu einem
deutlichen Fehler beim Start, anstatt die Isolationsgrenze still zu durchbrechen.
Konfiguration
Abschnitt betitelt „Konfiguration“-
Apps-Content-Domain festlegen.
Füge
SUPACLOUD_APPS_BASE_DOMAINzu deiner Umgebung hinzu und setze sie auf deine separate registrierbare Domain:SUPACLOUD_APPS_BASE_DOMAIN=supacloud.netDer Wert muss eine reine Domain sein – kein Schema, kein Port, kein Pfad und keine Leerzeichen.
supacloud.netist korrekt;https://supacloud.netwird beim Start abgelehnt. -
Gehostetes Frontend-Serving aktivieren.
SUPACLOUD_APPS_HOSTED_FRONTEND=trueDer Server verweigert den Start, wenn dieses Flag gesetzt, aber keine Apps-Domain konfiguriert ist.
-
Wildcard-DNS auf deinen Server leiten.
Alle
*.yourapps.domain-Requests müssen SupaCloud erreichen. Im bw-infra-Referenz-Deployment verarbeitet Traefik ein Wildcard-Zertifikat*.supacloud.net(InternetBS DNS-01) und leitet alle Subdomains an den Server weiter. -
Server neu starten.
Der Boot-Guard validiert beide Variablen. Bei erfolgreichem Start enthält der
/config-API-Endpunkt"apps_base_domain": "yourapps.domain".
Bearer-Token pro Deployment
Abschnitt betitelt „Bearer-Token pro Deployment“Backend-Aufrufe einer gehosteten App (z. B. ein über ein Formular ausgelöster
Workflow-Trigger) sollten keine Benutzer-Session einbetten. Erstelle stattdessen
einen Deployment-spezifischen App-API-Token (Präfix scwa_, gespeichert als
Hash in app_deployments.api_token_hash, Migration 173):
POST /api/apps/{id}/deployment/tokenAuthorization: Bearer <owner-session>Die Antwort gibt den rohen Token-Wert einmalig zurück. Speichere ihn
serverseitig im Backend deiner App – bette ihn niemals in ein öffentliches
Frontend-Bundle ein. Der Token authentifiziert sich als workspace-scoped
Service-Identity und ist CSRF-exempt (kein Cookie-Credential; CORS-Preflight
verhindert das cross-site Anhängen eines benutzerdefinierten Authorization-Headers).
Widerrufe ihn, wenn er nicht mehr benötigt wird:
DELETE /api/apps/{id}/deployment/tokenAuthorization: Bearer <owner-session>Der Token wird außerdem automatisch beim Undeploy gelöscht, sodass ein Redeploy-Zyklus kein veraltetes Credential stillschweigend reaktivieren kann.
Setup überprüfen
Abschnitt betitelt „Setup überprüfen“Deploye nach dem Neustart eine React- oder Svelte-App über die SupaCloud-Oberfläche.
Die Deployment-Detailseite zeigt die zugewiesene Subdomain-URL
(https://<opaque>.yourapps.domain). Das Öffnen dieser URL sollte das gebaute
index.html mit folgenden Eigenschaften ausliefern:
- Einem
Content-Security-Policy-Header (Default-Deny;frame-ancestorsenthält die Control-Plane-Origin, damit der Live-Preview-iFrame cross-origin funktioniert). X-Content-Type-Options: nosniff.<base href="/">inindex.htmleingefügt.
Requests von der Apps-Origin an die Control-Plane-Origin (/api) werden durch
SameSite=Lax am Session-Cookie und den Ausschluss aus der CORS-Allowlist blockiert.
Verwandte Themen
Abschnitt betitelt „Verwandte Themen“- Referenz Umgebungsvariablen
- ADR 0041 — vollständiger Entscheidungseintrag zum App-Hosting und zur Separate-Origin-Architektur.