Architecture & Security
This page describes what the RootCause Platform is made of, where each component runs, the choices the bootstrap wizard puts in front of you, and how the platform is secured, scanned and retained.
The platform is deployed into your own Kubernetes cluster by the RootCause Operator. Nothing runs in RootCause infrastructure, and platform data never leaves your cluster.
Platform components

The RootCause components are the Platform, the Data Service, the ML job pods they dispatch, and the optional telemetry service.
Platform
The interface people use, and the API gateway in front of everything else
3 replicas
Data Service
Data processing, orchestration, ontology and LLM work, and the in-process query engine
3 replicas
ML job pods
One ephemeral Kubernetes Job per task — causal discovery, digital twins, simulation, ontology extraction
0 → N
Telemetry service
Licence-gated collector for usage events and errors, off by default
3 replicas
Browsers, the Python and Node SDKs, the MCP server and the public REST API all arrive through one ingress controller, authenticate against your identity provider, and talk to the Platform. The Platform proxies to the Data Service over HTTP and WebSocket.
The Data Service does not run heavy compute in a request handler. Causal discovery, twin training, simulation and ontology extraction are dispatched as Kubernetes Jobs, one per task, which run to completion and are then removed.
LiteLLM is the only component that talks to model providers. Every call to OpenAI, Anthropic, Google, AWS Bedrock or Azure OpenAI — or to a model you host yourself — goes through it, so provider keys live in one place.
Deployment topology

Everything is deployed into a single namespace, rootcause-system. One wildcard DNS record and one TLS certificate cover the hostnames: platform, auth, litellm, and telemetry when the collector is self-hosted.
PostgreSQL, MongoDB, Redis, Temporal and LiteLLM are deployed in-cluster by default, and each can instead point at an instance you already run — set that in the bootstrap wizard and the operator skips deploying it. The object store and the identity provider are always external choices.
MongoDB is deployed as a 3-member replica set with MongoDB Search, managed by the unified MongoDB Kubernetes Operator (MCK).
The legacy MongoDB Community Operator cannot deploy MongoDB Search and is rejected by the operator's preflight checks.
Cloud differences
The deployment is identical on AKS, EKS and GKE except for the following.
Managed Kubernetes
AKS
EKS
GKE
Storage class
managed-csi
gp3
standard or premium-rwo
Object storage
Azure Blob Storage
S3
GCS
Ingress
Application Gateway (AGIC) or nginx
nginx or ALB Ingress Controller
nginx or GCE Ingress
Compute pool autoscaler
Built-in cluster autoscaler
Cluster Autoscaler or Karpenter, self-deployed
Built-in cluster autoscaler
Every cluster needs Kubernetes 1.26 or newer, Helm 3.12 or newer, amd64 nodes, and SSD-backed persistent volumes.
Azure Application Gateway requires additional ingress annotations and path configuration. The Deployment Guide covers them.
Object storage
The platform uses one bucket or container. Datasets, digital twins and trained models are stored as sub-directories of it.
Azure Blob Storage
Storage account, one container, and a connection string, account key or service principal
AWS S3 or S3-compatible
One bucket, access key, secret key and region — plus an endpoint URL for compatible stores
Google Cloud Storage
One bucket, project ID and service account credentials
Garage, in-cluster
Nothing. The operator deploys it, creates the bucket and wires the credentials
Garage covers clusters with no cloud bucket, including air-gapped ones. Single-node mode suits development; production mode needs three or more schedulable nodes.
Compute and ML jobs
A dedicated compute node pool is optional and recommended for production: tainted rootcause.ai/workload=compute:NoSchedule, labelled rootcause.ai/nodepool=compute, autoscaling from a minimum of zero.
A twin training run proceeds in this order:
Someone starts causal discovery or trains a digital twin.
The Data Service creates a Kubernetes Job carrying the compute toleration.
Nothing can schedule the pod, so the autoscaler adds a node to the compute pool.
The job runs — one partition per pod — and writes results to MongoDB and object storage.
The pod is cleaned up and the node is removed.
Without the pool, ML Job pods run on the default node pool; size it accordingly.
Language models
The platform needs a large language model. Which provider you use is your choice; having one is not optional — ontology extraction, document extraction and the agent surfaces all depend on it.
Models must support a context window of at least 256k tokens. Smaller models fail on real ontology and document work rather than degrading gracefully.
OpenAI
API key
Anthropic
API key
AI Studio or Vertex credentials
AWS Bedrock
Region and IAM credentials
Azure OpenAI
Endpoint, deployment name and key
Self-hosted
Any OpenAI-compatible endpoint, including models you run in-cluster
Every call goes through LiteLLM, so provider keys are held in one place and models can be swapped without touching the platform.
Network egress
The cluster needs outbound access to:
registry.gitlab.com
Container images and OCI Helm charts
Your model provider APIs
Unless you serve models inside the cluster
telemetry.rootcause.ai
Unless telemetry is switched off
Nothing else leaves the cluster on its own. Connectors reach whatever source systems you configure, and those are your endpoints.
Where a user can aim an outbound request — the agent's HTTP tool, or an application notification sink — the target is validated before any connection is made. Only http and https are allowed; private, loopback, link-local, unique-local, reserved and multicast addresses are refused, which includes the 169.254.169.254 cloud metadata endpoint; and in-cluster names ending .cluster.local, .svc, .internal, .local or .localhost are rejected. Name resolution is pinned to the vetted address, so a hostname that resolves to a public IP at validation time cannot be rebound to an internal one before the request is sent.
Telemetry

The Platform and Data Service emit usage events, errors and application logs, tagged with TELEMETRY_CLIENT_ID to identify the installation. Datasets, models and results are not part of it.
RootCause cloud — the default
Events and errors are sent to telemetry.rootcause.ai
Egress to that host, and a TELEMETRY_CLIENT_ID
Self-hosted collector
A telemetry service runs in your cluster with its own hostname and sign-in, keeps dashboards, an error inbox and Slack alerts in the platform's MongoDB, and forwards upstream
A licence that permits it, plus one more hostname and TLS certificate
Off
Nothing is emitted
DISABLE_TELEMETRY set in the bootstrap wizard
The self-hosted collector still forwards upstream via
TELEMETRY_FORWARD_URL. It is the option for in-cluster dashboards and alerting, not for stopping telemetry egress — that isDISABLE_TELEMETRY.
What telemetry contains
Collected:
Usage events
Event name, type (event, counter or gauge), numeric value, free-form event data, labels, source, client ID, container version, session ID
Errors
Error name, message, stack trace, correlation ID, and the same envelope fields
Application logs
Severity, timestamp, logger name and log fields, when a telemetry service URL is set
Authentication events
Login and registration success and failure, carrying email address, IP address, user agent, authentication method and failure reason
Not collected:
Dataset contents. No rows, no column values, no file contents.
Digital twin parameters, causal graphs, simulation results or forecasts.
Query results, SQL, or anything returned by the query engine.
Documents you upload, and anything extracted from them.
Credentials of any kind: model provider keys, database passwords, connector credentials or API keys.
Authentication events include the signing-in user's email address and IP. Set
DISABLE_AUTH_TELEMETRY=trueto suppress them independently of the rest of telemetry.
Product analytics through Google Tag Manager run only on RootCause's own hosted platform, gated on TELEMETRY_CLIENT_ID. A customer deployment never loads them.
DISABLE_TELEMETRY
Stops all telemetry emission
DISABLE_AUTH_TELEMETRY
Stops authentication events only
TELEMETRY_SERVICE_URL
Where telemetry is sent. Unset means nothing is emitted
TELEMETRY_CLIENT_ID
Identifies your installation in what is received
Product telemetry is not the observability stack. It answers "how is the product being used"; the stack below answers "what is this cluster doing right now". They are configured separately and can be run independently.
Observability

The platform ships an opt-in, in-cluster observability stack, deployed by the operator from spec.config.observability. It is off by default.
OTel agent
DaemonSet. Collects pod logs with the filelog receiver and tags them with Kubernetes attributes
OTel gateway
Deployment. Every signal routes through it before export
Loki
Log storage, default 10Gi
Prometheus
Metric storage, bundling node-exporter and kube-state-metrics
Grafana
Dashboards over both, single-node, default 2Gi
The Platform and Data Service are instrumented with OpenTelemetry. The Data Service reads OTEL_EXPORTER_OTLP_ENDPOINT and honours OTEL_SDK_DISABLED.
Both Prometheus and Loki retain data for 7 days unless you set retentionDays, and their persistent volumes use spec.cloud.storageClass.
To ship signals to your existing tooling, configure the gateway's forward target with a base URL — for example https://otel.example.com — plus basic-auth headers if it needs them. Forwarding is in addition to the local Loki and Prometheus backends, not instead of them.
Security posture
The platform runs entirely inside your cluster. RootCause has no inbound access to it, no control plane in your environment, and no copy of your data.
Data location
Datasets, digital twins, models and application data stay in your bucket and your databases
Authentication
Delegated to your identity provider over OIDC or SAML. The platform stores no password unless you choose managed FusionAuth
Authorisation
API keys are scoped per workspace and per permission scope. See API Access
Secrets
Held as Kubernetes Secrets in your namespace, generated by the operator at install
Connector credentials
Encrypted before storage and redacted on read. The API never returns them
Transport
TLS terminates at your ingress controller, under one wildcard or per-host certificate
Cluster permissions
The Data Service service account manages Jobs in its own namespace and reads pods, pod logs and events, plus read-only node visibility for scheduling
Registry access
A GitLab deploy token limited to the read_registry scope
Authentication

External OIDC
Recommended. Entra ID, Okta, Auth0, Google Workspace or any OIDC provider
External SAML
Your provider only speaks SAML, or your security team requires it
Managed FusionAuth
No identity provider yet, or a proof of concept. The operator deploys and configures it
OIDC needs an issuer URL, client ID, client secret and well-known configuration URL. SAML needs the metadata URL or XML, entity ID and certificate.
Released images are promoted, not rebuilt. A commit that passes the gating suites on the default branch writes a content-addressed provenance attestation; the release tag verifies that record and restamps the image that was already built and scanned, so the artifact you run is the artifact that was tested.
Dependencies, licences and scanning
Vulnerability scanning. Container images are scanned with Trivy at HIGH and CRITICAL severity on every merge request, on the default branch, and on every release tag. A green scan is attested and reused by the tag pipeline for 24 hours, so a tag re-verifies rather than rebuilds.
Licence policy. Nothing that ships carries a hard copyleft licence. Both repositories gate on it in CI and fail the pipeline rather than warn:
Platform
Fails on GPL, AGPL or SSPL in production dependencies. A dual-licensed package passes if one alternative is permissive. Dev-only and unknown licences are reported, not failed
Backend
Fails on any GPL-family licence — GPL, AGPL or LGPL — in the runtime dependency tree
Both gates publish a full inventory as a CI artifact: every dependency, its licence and its project URL. The most recent platform scan covered 2,067 packages, overwhelmingly MIT, Apache-2.0, ISC and BSD.
Advisories. Dependency advisories are checked in CI. An advisory can only be allowlisted with a written justification and a review-by date, and a separate hygiene job fails the pipeline when an allowlist entry goes stale.
Minimum versions.
Kubernetes
1.26+
Helm
3.12+
PostgreSQL
15.0+
MongoDB
8.0+, deployed with MongoDB Search
Redis
7.2.4+
Temporal
1.26.2+
FusionAuth
1.57.1, when the operator deploys it
LiteLLM
Pinned per release
Data retention
Datasets, digital twins, trained models
Your object storage
Until you delete them
Workspaces, ontologies, application data
MongoDB
Until you delete them
Workflow history
Temporal, on PostgreSQL
3 days
ML job pods
The cluster
Removed 60 seconds after completion, configurable with ML_JOB_TTL_SECONDS
Logs and metrics
Loki and Prometheus, when observability is enabled
7 days by default, set with retentionDays
Grafana dashboards
Its own volume
Persist across restarts
Telemetry received by RootCause
RootCause
Per your agreement
Deleting a dataset removes it from the bucket and from MongoDB. Object storage lifecycle rules, backup schedules and snapshot policies are yours to set: the platform does not impose or override them.
Next steps
Requirements is the checklist for your infrastructure team. The Deployment Guide walks through the install.
Last updated

