Skip to content

Ingress & TLS

The single entry point for all browser- and mobile-originated traffic.

Topology

flowchart LR
  subgraph internet["Internet"]
    mobile[Mobile App]
    browser[Browsers]
  end

  subgraph cluster["Kubernetes"]
    ingress[Ingress Controller
NGINX] cert[cert-manager] senseApi[Sense API] genApi[Gen API] senseWeb[Planner Web] genWeb[Gen Web] chui[ClickHouse UI] kafkaui[Kafka UI] signozui[SigNoz UI] end mobile -- "HTTPS/2 (gRPC)" --> ingress browser -- "HTTPS" --> ingress ingress -- "GRPC backend" --> senseApi ingress -- "HTTP backend" --> genApi ingress --> senseWeb ingress --> genWeb ingress --> chui ingress --> kafkaui ingress --> signozui cert -. issues certs .-> ingress

Ingress controller

NGINX Ingress Controller is the default. Per-route annotations:

  • For Sense API gRPC routes: nginx.ingress.kubernetes.io/backend-protocol: "GRPC" — ingress speaks HTTP/2 to the backend, no protocol coercion.
  • For Sense API REST routes: standard HTTP/1.1.
  • For Gen API: standard HTTP/1.1.
  • For SSE endpoints (Gen Web's AI streaming via /api/agent/stream): increase proxy-read-timeout and disable buffering.

TLS

  • cert-manager issues certificates from Let's Encrypt (cloud) or an internal CA (on-prem).
  • One cert per public hostname; SAN-style certs aren't required.
  • Min TLS version: 1.2; prefer 1.3.

Hostnames (staging example)

Hostname Backend
axion-sense-staging.dev.axionx.ai Sense API + Planner Web (path-based split)
axion-gen-staging.dev.axionx.ai Gen API + Gen Web
axion-clickhouse-ui-staging.dev.axionx.ai ch-ui (admin only, IP-allowlisted)
axion-kafka-ui-staging.dev.axionx.ai Kafbat Kafka UI (admin only, IP-allowlisted)
signoz-staging.dev.axionx.ai SigNoz UI (admin only, IP-allowlisted)

Mobile gRPC uses the same Sense host with HTTP/2 negotiation.

Auth at the edge

We do not terminate auth at the ingress. JWT validation happens inside Sense API and Gen API — this keeps the ingress thin and lets services own their auth contract (different scope sets, different policies). Ingress passes the Authorization header through.

Admin UIs (ClickHouse UI, Kafka UI, SigNoz UI) are gated by IP allowlist at the ingress — they don't have OIDC integration in front of them. This is acceptable because they're accessed by a small ops team from known networks.

Body size

Frame uploads do not flow through the ingress (presigned S3 PUT). API routes don't accept large bodies — keep client-max-body-size modest (1–8 MiB) to avoid being a slow-loris target.

Rate limiting

Per-IP rate limits at the ingress for unauthenticated paths (login, health checks). Authenticated paths are rate-limited at the application level, scoped by user/org.

Observability

  • Ingress access logs ship to SigNoz logs.
  • Per-host latency exposed as a metric; alert on 5xx rate spikes.