Components
Frontend
Next.js 16 (App Router) + React 19, TypeScript, Tailwind, shadcn/ui.
Backend
Go with the Chi router; a dynamic Kubernetes client per supervisor.
PostgreSQL
Control-plane state: supervisors, cluster templates, addons, IAM policies/ groups, audit logs, cached data.
ClickHouse
Network-flow analytics powering the security topology and forensics views.
Request pipeline
Every API request passes through an ordered middleware chain before reaching a handler:1
Tracing + access log
An OpenTelemetry span (named after the route pattern) and a structured access log line.
2
Recoverer
Panics are caught and turned into
500s instead of crashing the process.3
CORS
Cross-origin handling scoped to the configured frontend origin.
4
Session
Validates the
k8s-gate-session cookie (or a Bearer API token) and puts the user’s identity and groups into the request context.5
Audit
Mutating requests (POST/PUT/DELETE) are recorded with user, action, resource, status, and duration.
6
Authorization (IAM)
The route is resolved to an action + KRN and checked against the user’s policies. See Permissions model.
Multi-supervisor model
Celum manages many supervisor clusters at once. Each supervisor is a kubeconfig — provided as a file (filename = supervisor name) or stored in the database. An empty supervisor name resolves to a synthesized__default__. Kubernetes clients are cached per supervisor, and every supervisor call is tagged with its name in traces. See Supervisors & clusters for the full model.
Provider detection
A cluster’s provider is read from its Cluster APIspec.infrastructureRef.kind and mapped to a friendly name — for example:
Unmapped kinds fall back to the kind name with the
Cluster suffix stripped.
Data fetching
The frontend uses two helpers, never rawfetch:
The client API base URL is injected at request time via a runtime-config script (
window.__APP_CONFIG__), so the same build runs against any environment.
Observability
The backend emits OpenTelemetry traces over OTLP/HTTP whenOTEL_EXPORTER_OTLP_ENDPOINT is set (a no-op tracer otherwise, so there’s no overhead when unconfigured). Spans cover HTTP handlers, per-supervisor Kubernetes calls, and PostgreSQL/ClickHouse queries, and structured logs carry the active trace ID for correlation.
Performance patterns
Read-only endpoints that hit a supervisor’s API use a stale-while-revalidate cache: fresh values are served immediately, stale values are returned while a refresh runs in the background, and a cold miss is bounded by a short timeout with an empty fallback — so one unreachable supervisor can’t hang a page. Helm release listings use a fast path that reads release Secrets directly, avoiding the Kubernetes API discovery cost.A consequence worth knowing: a page can show data from a supervisor that has since become unreachable. Values are served stale while a refresh runs behind them, and a cold miss returns empty rather than an error.
Backend layout
The Go backend is organized underbackend/internal/:
Plus integration packages for DNS, IPAM, GitOps, and related services.
Related
Supervisors & clusters
How supervisors are discovered, named, and cached.
Permissions model
How a request becomes an action + KRN, and how it is evaluated.