TLS, ingress & networking
The backend serves plain HTTP and assumes you terminate TLS at the edge. What to expose, the WebSocket paths that must survive your proxy, and which way traffic flows between clusters.
Exo's backend is a single HTTP server with the UI embedded. No separate web tier, no built-in TLS. Front it with whatever ingress your platform already trusts. The one non-obvious requirement: two paths carry long-lived WebSockets, so your proxy must allow upgrades.
Ports
1Platform (exo-app)2 9092/tcp HTTP — UI, dashboard API, Exo Operator WebSocket, shell channel3 4autonomic-manager (autonomic-system)5 443 → 9443 webhook (admission reviews; TLS, cert self-bootstrapped)6 8080 metrics (Prometheus /metrics)7 8081 probes (/healthz, /readyz)8 8082 invoke (agent invocation API; in-cluster or via apiserver proxy)The platform Service is a ClusterIP on 9092; the manager Service exposes the four ports above inside autonomic-system.
TLS & ingress
Terminate TLS at your ingress controller and forward to the exo-app ClusterIP on 9092. The backend reads EXO_BASE_URL for the public origin in email links and OAuth callbacks, so set it to your HTTPS hostname.
1apiVersion: networking.k8s.io/v12kind: Ingress3metadata:4 name: exo5 namespace: exo6 annotations:7 cert-manager.io/cluster-issuer: letsencrypt8 nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"9spec:10 ingressClassName: nginx11 tls:12 - hosts:13 - exo.example.com14 secretName: exo-tls15 rules:16 - host: exo.example.com17 http:18 paths:19 - path: /20 pathType: Prefix21 backend:22 service:23 name: exo-app24 port:25 number: 9092WebSockets
Exo Operator egress
In managed mode the operator opens one outbound WebSocket from its cluster to the platform at wss://<EXO_BASE_URL>/api/autonomic/connect, authenticated with the deployment token. No inbound ports open on the operator's cluster; it only needs egress to your platform host on 443. That's what keeps air-gapped and tightly-firewalled clusters working. See Connecting to the control plane.
CORS
The API responds with permissive CORS (Allow-Origin: *; methods GET/POST/PUT/PATCH/DELETE/OPTIONS; headers including Authorization and X-Tenant-ID). If you put the API behind a gateway that injects its own CORS, make sure you don't double up the headers.