KamuiDash receives tenant applications and custom domains through one Cloudflare edge.
This article follows a request from the public entry point to a tenant application's response.
From the public edge to a tenant application
Every HTTP request first reaches a Cloudflare Worker. The Worker resolves the target application from the Host. Dynamic requests then pass through Cloudflare Tunnel to an internal router and the tenant application in the cluster.
The Worker owns domain resolution and path selection at the entry point. Only requests that need application execution reach the cluster.
1. Resolve the Host in the Worker
The Worker normalizes the received Host, then reads a KV mapping between domains and internal applications. Custom domains and platform subdomains are both inputs to the same question: which application does this request identify? An unknown external domain returns a 404 at the Worker rather than entering the cluster.
After identifying an application, the Worker checks its serving mode. When the response does not finish at the edge, it reads the dynamic destination and forwards through Tunnel. The KV data is separated by purpose.
Domain mapping Host → internal application
Destination registry internal app → dynamic application destinationDomain mappings and dynamic destinations change at different rates and tolerate different propagation windows, so they are not kept in one record.
- 01Resolve the HostMap a custom domain to an internal application
- 02Check serving modeOnly dynamic requests enter the cluster
- 03Resolve the destinationSelect a Tunnel path from application placement
- 04Normalize failures at the edgeKeep timeouts, upstream errors, and tracing consistent
2. Dynamic requests continue through Tunnel and the internal router
When a response does not finish at the edge, the Worker reads the application-to-destination mapping and selects a Tunnel path. It attaches the resolved application identifier and routing context before forwarding. Any client-supplied values with the same purpose are replaced by the Worker's resolved values.
For each forward, the Worker builds a new upstream request from the received headers. It explicitly sets the Host and routing context from its resolution, and adds a request ID. Tenant selection is therefore not delegated to an arbitrary value sent by the client.
The Tunnel connector establishes an outbound connection to Cloudflare, so the cluster does not expose an internet-reachable receiving endpoint. The internal router receives the resolved context on the other end of the Tunnel and forwards to the target tenant application.
The upstream fetch is bounded with an AbortController. Connection failures, timeouts, and upstream server errors become gateway errors at the entry point. Internal routing information is removed from responses, and a dynamic response without Cache-Control receives a non-shared-cache default. WebSocket upgrades pass through separately from normal HTTP responses.
3. Limit the entry point after Tunnel too
The internal router uses routing information supplied by the Worker, so it accepts only requests that arrived through Tunnel. KamuiDash applies a NetworkPolicy that limits ingress to the internal router to Tunnel connector pods.
The policy permits the Tunnel connector alone as a source. This closes a path where another workload in the same cluster could reach the router directly and forge context that should have been resolved by the Worker. Host resolution at the public edge and source restriction in the cluster sit at opposite ends of the same request path.
4. What changes during domain registration and deployment
When adding a custom domain, KamuiDash completes ownership validation and certificate issuance through Cloudflare's custom-domain capability, then registers the mapping between the domain and the internal application. Removal releases that mapping and the domain-side state in sequence.
Moving a dynamic application changes its destination-registry mapping. Domain mappings and destinations change at different rates, so they use separate cache durations.
KV is not a store where a write immediately clears every edge cache: a missing result can persist briefly too. Registration and movement are tracked through DNS, certificates, and KV propagation. The Worker writes request IDs and edge tracing data to structured logs while excluding credentials and cookies, allowing the same request to be traced through Tunnel, the internal router, and the tenant application.
What Cloudflare handles in this path
For custom domains, Cloudflare handles ownership validation and certificate issuance and renewal. KamuiDash retains the mapping from a domain to a tenant application, without a separate certificate and public-entry workflow for every domain.
The Worker is the shared execution point for every public request. It centralizes Host resolution, upstream request construction, error normalization, and request-ID creation instead of requiring each tenant application to implement the same entry logic.
With Tunnel, connectors in the cluster establish outbound connections. Tenant applications and the internal router do not need public receiving endpoints, while KamuiDash retains the NetworkPolicy that limits allowed sources.
Summary
KamuiDash centralizes three things at the Cloudflare entry point.
- Resolve tenant applications from the Host — Custom domains and platform subdomains use the same mapping, and the Worker determines the destination.
- Pass only resolved context into the cluster — The Worker builds the upstream request, then Tunnel and the internal router deliver it to the target tenant application.
- Treat changes as part of the request path — Domain registration and application movement are followed through certificates, KV cache propagation, and routing.
Putting Cloudflare at the entry point lets KamuiDash avoid a separate public path for every tenant while keeping the Worker, Tunnel, and internal router as distinct responsibilities.
For KamuiDash's broader design philosophy and the basic GitHub-to-deployment flow, see Why Use KamuiDash.