Skip to main content

Heimdall overview

Heimdall is a bounded, durable delivery path from event producers to Kafka. It owns HTTP admission, JetStream buffering, Kafka production, retry and DLQ behavior, and the operational APIs used to inspect the pipeline.

Architecture

Edge

The edge is the only Heimdall process that receives a player bearer token. The prepared dev contract targets http://spark-dev1-quasar-svc.core-spark-test1.svc.cluster.local/getPlayer; the production player-api-svc contract remains disabled and unverified. The edge:

  1. maps the exact browser Origin to trusted tenant, site, and player-validation configuration
  2. accepts X-Heimdall-Client-IP only from configured trusted proxy CIDRs
  3. applies Redis-backed request and validation limits
  4. resolves the logged player with a bearer-authenticated GET whose JSON body contains the trusted positive-decimal site_id and canonical client ip
  5. treats configured 4xx statuses as definitive invalid-player results; the default 401,403,422 contract includes Quasar's 422
  6. caches a successful player resolution for five minutes
  7. validates and sanitizes the event body
  8. overwrites tenant, site, and player identity with trusted values
  9. forwards the envelope to the private ingest listener without an application token

Dev1 uses one dedicated HTTPS Ingress hostname, not one Heimdall route per frontend host. Verified frontend origins remain exact CORS and trusted tenant/site/player-validation mappings. Generic frontend defaults and all production environments remain disabled.

Ingest

Ingest exposes two isolated listeners:

  • POST /v1/events on the public listener for existing service producers, protected by the existing ingest bearer when authentication is enabled
  • POST /internal/v1/events on private port 8082 for the edge, without application authentication

The listeners have separate in-flight budgets. Browser traffic cannot consume the public service-producer budget. Both publish to the same JetStream stream and share readiness state.

Worker

The worker pulls from the JetStream WorkQueue and publishes to Kafka. Failed deliveries are retried, then moved to the DLQ according to the existing worker policy. A message is not acknowledged when the DLQ write fails.

Admin API

The admin API is off the ingest hot path. It provides health and readiness, queue state, Kafka watermarks, live tail, statistics, routing inspection, DLQ reads, and explicit DLQ reprocessing.

HTTP interfaces

InterfaceAuthenticationIntended caller
POST /api/heimdall/eventsExisting player beareronline-services-front for logged players
POST /v1/eventsExisting Heimdall ingest bearerTrusted service producers
POST /internal/v1/eventsNo application tokenEdge pods through the private Service
/admin/v1/*Separate admin bearerDashboard and operators

The public ingest and admin credentials are separate. Neither credential belongs in the browser or edge deployment.

Delivery and trust boundaries

  • A 202 Accepted response means JetStream acknowledged the durable publish. It does not mean Kafka has already accepted the event.
  • The browser event UUID becomes the envelope event ID and remains stable across frontend retries.
  • The browser cannot choose source, event_type, tenant, site, or player identity.
  • The edge fixes the source to online-services-front. It assigns ui.analytics.v1 to ordinary analytics and player.casino-presence.v1 only to the allowlisted casino_presence classification.
  • The trusted client IP is sent only to the player-validation backend. It is not logged, stored as a raw value, or copied into the event sent to ingest and Kafka.
  • Session ID is the Kafka partition key for ordinary browser analytics. Casino presence uses a stable hash of trusted tenant, site, and player identity.
  • The edge-to-ingest listener is protected by Kubernetes network isolation, not an application token.
  • Readiness includes the dependencies required by each process. For the edge, Redis and the internal ingest readiness endpoint must both be available.

Static routing

The worker falls back to heimdall.events.v1 for ordinary and unknown trusted service event types. Casino presence is the first dedicated route:

Trusted event typeKafka topicPartitioning
ui.analytics.v1heimdall.events.v1Browser session ID
player.casino-presence.v1heimdall.player-casino-presence.v1Trusted tenant + site + player hash

GET /admin/v1/routing exposes this static table read-only. Adding or changing a route remains a reviewed code change and deployment, not runtime state.