Skip to main content

Components

Self-hosted Radar Cloud architecture: nginx + web app in front of the radar-hub Go API, with Postgres and in-cluster Radars connected to the API. Optional license heartbeat to api.radarhq.io.

Data flow

A user’s browser request to a cluster

  1. Browser → https://radar.acme.example/c/{cluster-id}/api/...
  2. nginx (radar-hub-web Pod) reverse-proxies to the radar-hub Service.
  3. radar-hub’s auth middleware validates the session cookie (sealed with HUB_COOKIE_PASSWORD).
  4. The control plane looks up the cluster’s session in the in-memory registry (one entry per connected in-cluster Radar).
  5. The control plane opens a yamux stream on that cluster’s long-lived WebSocket.
  6. The request body streams over the yamux stream to the in-cluster Radar.
  7. The in-cluster Radar serves the request out of its existing chi router and streams the response back.
  8. nginx + the control plane forward each chunk to the browser.
Per-request overhead: one yamux stream (~1KB), no DB roundtrip beyond the auth check.

A cluster connecting

  1. In-cluster skyhook-connector runs helm install ... cloud.url=wss://radar.acme.example/agent cloud.token=rhc_....
  2. The connector dials /agent with Authorization: Bearer rhc_....
  3. The control plane looks up the SHA-256 hash of the token in clusters and validates the cluster id.
  4. The control plane upgrades the connection to WebSocket, wraps it as a net.Conn, and starts a yamux server-side session.
  5. Connector registers with its cluster id; the control plane stores the session in the in-memory registry.
  6. Tunnel stays open until the connector process dies or the network drops.
The cluster always initiates - the control plane never makes outbound calls into customer infrastructure. This is the firewall-friendly property that lets self-hosted radar-hub connect clusters in different VPCs / accounts / providers without poking holes.

Trust boundaries

What we don’t have access to

In a self-hosted install, Skyhook has access to:
  • Whatever metadata you choose to send in the license heartbeat (license id, version, cluster count, audit-event volume - shape documented in Licensing).
  • Nothing else.
We don’t have:
  • Customer kubernetes-cluster data (Pods, Deployments, secrets, etc.) - that lives in your kube-apiserver and Radar’s per-cluster cache.
  • User identities (emails, OIDC subjects) - they’re in your Postgres.
  • Audit log content - same.
  • Tunnel traffic - never crosses your VPC.

Single-replica deployment

The control plane runs as a single replica. The tunnel-session registry is in-memory, so a second replica without sticky routing would split tunnels across pods. Practical guidance:
  • Single replica handles hundreds of clusters; the control plane is mostly wait-on-network.
  • Tune hub.resources.limits if CPU pressure shows up under fleet calls. Each fleet endpoint fans out to every connected cluster in parallel with bounded timeouts.
  • If you outgrow this, talk to us — multi-replica needs a sticky-routing layer we’ll build to your shape.