Routing: how a developer's traffic reaches their copies

Nezal runs one router per Baseline next to the application's services. Every in-cluster Service name (ledger or payments-api) points at the router. The real pods sit behind <name>-baseline. An Environment's copies live in their own namespace and are reached only through the router.

The routing key

Requests carry the environment name in X-Nezal-Env: <environment>. The router also accepts and sets the W3C baggage member nezal-env=<environment> so services that already propagate OpenTelemetry baggage need no change.

Your services must forward X-Nezal-Env (or baggage) on every outgoing call the same way they forward trace context. Without it a call from a baseline service to a service the environment overrides lands on the baseline copy.

What the router does with a request

Arrives on Environment taken from Client routing headers Goes to
Service port (in-cluster) X-Nezal-Env or else baggage trusted copy if the environment overrides the service or else <name>-baseline
Edge port (from the Ingress) Host header only discarded the Baseline entrypoint service with copy or baseline chosen as above

Unknown environment names fall open to the baseline. Each occurrence is counted in nezal_router_unknown_env_total and recorded as an UnknownEnvironment Event on the Baseline so a developer whose environment was deleted mid-session is visible.

Ports declared protocol: tcp and services marked shared: true never pass through the router. They always reach the baseline pods directly.

Preview URLs and TLS

With --ingress-domain=<domain> the operator publishes:

Both are exact-host Ingress objects in the application namespace and are backed by the router's edge Service. Set --ingress-class if the cluster has more than one ingress controller.

TLS has two shapes and Nezal issues nothing in either. The product never contacts a certificate authority so certificates are yours whether you hold them or run something that obtains them.

Preview URLs are served over plain HTTP until one of these is in place and each Baseline shows the condition IngressTLS=False with reason NoTLSSecret. With per-host issuance the reason is CertificatePending until the baseline host's Secret exists.

Preview URLs require sign-in by default (previewAuth.enabled in the chart). The router checks a signed cookie that the API issues after the normal session check. A visitor without one is sent to the sign-in page. This covers shared mode. A full-mode environment has no router and its preview URL does not require sign-in yet.

Diagnostics