Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.neuraltrust.ai/llms.txt

Use this file to discover all available pages before exploring further.

This page is the single source of truth for the feature flags that change what the chart deploys. Use it when you need to decide between in-cluster and external infrastructure, mirror images, customize storage, or pre-create secrets. For end-to-end install walkthroughs, see the per-cloud guides. For the deployment-model decision (hybrid vs self-hosted), see Deployment models.

Component on/off toggles

The chart’s primary enabled flags decide which subcharts are rendered.
ComponentValues keyDefaultNotes
Data Planeneuraltrust-data-plane.dataPlane.enabledtrueAPI + worker + Kafka Connect
Control Planeneuraltrust-control-plane.controlPlane.enabledfalseOff = hybrid (CP on SaaS). On = self-hosted.
TrustGatetrustgate.enabledtrueadmin + gateway + actions + Redis
Firewallneuraltrust-firewall.firewall.enabledtruegateway + 5 workers — always on in supported topologies; the choice is CPU vs GPU workers (see Firewall deployment)
SIEM Connectorsneuraltrust-siem-connectors.siemConnectors.enabledfalseOff — opt-in
Watchdog (self-healing)neuraltrust-watchdog.enabledfalseOff — opt-in
OpenTelemetry Collectorglobal.observability.enabledfalseOff — opt-in
A zero-config helm install deploys Data Plane + TrustGate + Firewall + in-cluster infra, without Control Plane — i.e. a hybrid-shaped stack ready for SaaS enrollment.

PostgreSQL — in-cluster or external

PostgreSQL stores:
  • Control Plane schema (RBAC, integrations, dashboards) — only when CP is enabled
  • TrustGate schema (gateways, routes, plugins) — when TrustGate is enabled
  • Customer prompts and responses are never stored here — those go to ClickHouse.

In-cluster (default)

Values keyDefault
neuraltrust-control-plane.infrastructure.postgresql.deploytrue
neuraltrust-control-plane.controlPlane.components.postgresql.persistence.storageClass"" (cluster default)
neuraltrust-control-plane.controlPlane.components.postgresql.secrets.userneuraltrust
neuraltrust-control-plane.controlPlane.components.postgresql.secrets.password"" → auto-generated 32-char
neuraltrust-control-plane.controlPlane.components.postgresql.secrets.databaseneuraltrust
neuraltrust-control-plane.controlPlane.components.postgresql.secrets.hostcontrol-plane-postgresql
The in-cluster Postgres deploys regardless of controlPlane.enabled — TrustGate uses the same instance even in hybrid mode.

External (managed service)

neuraltrust-control-plane:
  infrastructure:
    postgresql:
      deploy: false
  controlPlane:
    components:
      postgresql:
        secrets:
          name: "postgresql-secrets"
          host: "<external-host>"
          port: "5432"
          user: "neuraltrust"
          password: "<password>"            # or pre-create the secret
          database: "neuraltrust"

trustgate:
  global:
    env:
      DATABASE_HOST: "<external-host>"
      DATABASE_PORT: "5432"
      DATABASE_USER: "trustgate"
      DATABASE_PASSWORD: "<password>"
      DATABASE_NAME: "trustgate"
      DATABASE_SSL_MODE: "require"          # "disable" only for in-cluster

Required databases & users when external

Create these before running helm upgrade. Most managed services let you create the cluster admin then run the CREATE DATABASE / CREATE USER statements below.
DatabaseUserRequired whenPermissions
neuraltrustneuraltrustAlwaysALL PRIVILEGES ON DATABASE neuraltrust — Prisma migrations need DDL on public schema
trustgatetrustgatetrustgate.enabled: trueALL PRIVILEGES ON DATABASE trustgate, schema DDL
Recommended SQL:
-- as the cluster admin
CREATE USER neuraltrust WITH PASSWORD '<strong-password>';
CREATE DATABASE neuraltrust OWNER neuraltrust;
GRANT ALL PRIVILEGES ON DATABASE neuraltrust TO neuraltrust;

CREATE USER trustgate WITH PASSWORD '<strong-password>';
CREATE DATABASE trustgate OWNER trustgate;
GRANT ALL PRIVILEGES ON DATABASE trustgate TO trustgate;

-- connect to each DB and grant on public schema (Postgres 15+)
\c neuraltrust
GRANT ALL ON SCHEMA public TO neuraltrust;
\c trustgate
GRANT ALL ON SCHEMA public TO trustgate;
The chart’s trustgate-postgresql-init Job can create the trustgate database/user automatically if the credentials in postgresql-secrets have CREATE USER and CREATE DATABASE rights on the external instance. Most managed Postgres services restrict these — pre-creating the DB/user is the safer path.

Cloud-managed Postgres notes

ProviderNotes
AWS RDS / Aurora PostgreSQLSet DATABASE_SSL_MODE: require. Use IRSA for password rotation via Secrets Manager if desired.
Azure Database for PostgreSQL Flexible ServerSet DATABASE_SSL_MODE: require. Use private endpoint for VNet-internal access.
Cloud SQL for PostgreSQLUse Private IP. Authorize the GKE subnet. Set DATABASE_SSL_MODE: require.
CloudNativePG (on-prem)Run CREATE DATABASE … OWNER from a privileged session; chart-side init Job works if the bootstrap user has CREATE rights.

Redis — in-cluster or external

TrustGate uses Redis for caching gateways, plugins, and rate-limit state. Data Plane and Control Plane do not use Redis.

In-cluster (default)

Redis ships bundled with the TrustGate subchart as trustgate-redis (single StatefulSet, 10 GiB PVC). No additional configuration needed.
Values keyDefault
trustgate.redis.replica.replicaCount1
trustgate.redis.image.tag7.2.0-v20
trustgate.redis.bind0.0.0.0 -:: (dual-bind)

External Redis

Point TrustGate at a managed Redis (ElastiCache, Memorystore, Azure Cache for Redis) by setting env vars:
trustgate:
  redis:
    enabled: false                          # config-only flag (see caveat below)
  global:
    env:
      REDIS_HOST: "<external-host>"
      REDIS_PORT: "6379"
      REDIS_PASSWORD: "<password>"          # required for managed Redis
      REDIS_DB: "0"
Current chart caveat: setting trustgate.redis.enabled: false changes the TrustGate env vars to point external, but the in-cluster trustgate-redis StatefulSet still deploys (the template isn’t guarded on the flag). The unused pod is small (~500m / 1 GiB) but it does consume cluster resources. A fix is planned for an upcoming chart release; until then, expect the in-cluster Redis pod to exist even when you target an external one.

Kafka — in-cluster or external

Kafka is the event backbone between TrustGate, Data Plane API, the Data Plane worker, Kafka Connect, and the Control Plane scheduler (audit events).

In-cluster (default)

Values keyDefault
infrastructure.kafka.deploytrue
kafka.replicaCount1
kafka.persistence.size10Gi
In-cluster Kafka has no auth — ClusterIP-only and never exposed outside the namespace.

External Kafka

infrastructure:
  kafka:
    deploy: false
    external:
      bootstrapServers: "kafka.example.com:9092"
      # 'brokers' (a list) is also accepted and joined with commas
This sets the bootstrapServers for components that read from infrastructure.kafka.external.*. Per-component Kafka env vars must also be overridden for components that use a hardcoded default (see below).

Authentication for external Kafka

The chart does not wire SASL/SCRAM/mTLS automatically. The infrastructure.kafka.external.secretName / secretKey keys exist in values.yaml but are not consumed by templates today. Use extraEnv on each Kafka consumer to inject the auth env vars yourself.
neuraltrust-data-plane:
  dataPlane:
    components:
      api:
        extraEnv:
          - name: KAFKA_BOOTSTRAP_SERVERS
            value: "kafka.example.com:9093"
          - name: KAFKA_SECURITY_PROTOCOL
            value: "SASL_SSL"
          - name: KAFKA_SASL_MECHANISM
            value: "SCRAM-SHA-512"
          - name: KAFKA_SASL_USERNAME
            valueFrom:
              secretKeyRef: { name: kafka-auth, key: username }
          - name: KAFKA_SASL_PASSWORD
            valueFrom:
              secretKeyRef: { name: kafka-auth, key: password }
      worker:
        extraEnv: *kafka-auth-env             # same as api.extraEnv
      kafka:
        connect:
          bootstrapServers: "kafka.example.com:9093"
Pre-create the kafka-auth Secret in your release namespace.

Per-component Kafka overrides

ComponentHardcoded defaultOverride path
Data Plane APIKAFKA_BOOTSTRAP_SERVERS=kafka:9092neuraltrust-data-plane.dataPlane.components.api.extraEnv
Data Plane WorkerKAFKA_BOOTSTRAP_SERVERS=kafka:9092neuraltrust-data-plane.dataPlane.components.worker.extraEnv
Kafka ConnectbootstrapServers=kafka:9092neuraltrust-data-plane.dataPlane.components.kafka.connect.bootstrapServers
Control Plane SchedulerKAFKA_BROKERS=kafka:9092, KAFKA_TOPIC=audit_eventsneuraltrust-control-plane.controlPlane.components.scheduler.config.kafkaBrokers / .kafkaTopic
Control Plane AppKAFKA_HOST=kafka, KAFKA_PORT=9092neuraltrust-control-plane.controlPlane.components.app.config.kafkaHost / .kafkaPort

Cloud-managed Kafka notes

ProviderNotes
AWS MSK (IAM)Use IRSA + aws-msk-iam-sasl-signer-java on consumers — currently requires custom image; chart does not bundle it.
Confluent CloudSASL/PLAIN over TLS; inject KAFKA_SECURITY_PROTOCOL=SASL_SSL and KAFKA_SASL_MECHANISM=PLAIN plus API key/secret.
Azure Event Hubs (Kafka surface)SASL/PLAIN over TLS on port 9093; username $ConnectionString, password = Event Hubs connection string. Inject via extraEnv.

ClickHouse — in-cluster or external

ClickHouse is the analytics database for the Data Plane — prompts, responses, traces, evals, metrics. All customer telemetry lives here.

In-cluster (default)

Values keyDefault
infrastructure.clickhouse.deploytrue
clickhouse.auth.usernameneuraltrust
clickhouse.auth.password"" → auto-generated 32-char in Secret clickhouse / key admin-password
clickhouse.auth.databaseneuraltrust
clickhouse.persistence.size50Gi

External ClickHouse

infrastructure:
  clickhouse:
    deploy: false
    external:
      host: "<external-host>"
      port: "8123"                          # HTTP port; "8443" for ClickHouse Cloud
      user: "neuraltrust"
      password: ""                          # use --set or pre-created secret
      database: "neuraltrust"
      secretName: "clickhouse"
      secretKey: "admin-password"

neuraltrust-data-plane:
  dataPlane:
    components:
      clickhouse:
        enabled: true                       # keep true to render clickhouse-secrets + migrations Job
        host: "<external-host>"
        port: "8123"
        user: "neuraltrust"
        database: "neuraltrust"

Required ClickHouse Cloud caveat

The Data Plane API runs an init container that connects to ClickHouse on native port 9000 to apply migrations — this is hardcoded in the chart today. ClickHouse Cloud exposes native on port 9440 (TLS) instead, so the migrations init container fails out of the box against Cloud.Workarounds: (a) pre-provision the schema yourself and disable the init container, (b) run a port-translating proxy that exposes 9000→9440 inside your VPC, or (c) deploy ClickHouse in-cluster instead. A configurable native port is on the chart roadmap.

Required databases & users when external

DatabaseUserPermissions
neuraltrustneuraltrustGRANT ALL ON neuraltrust.* TO neuraltrust
The clickhouse-migrations initContainer applies the schema automatically the first time the Data Plane API starts.

Image registry — NeuralTrust GCR or your internal mirror

By default, every NeuralTrust image is pulled from
europe-west1-docker.pkg.dev/neuraltrust-app-prod/nt-docker/<name>.

Default (NeuralTrust GCR)

Pre-create the gcr-secret image pull secret in your release namespace. The chart does not create this secret — you have to do it yourself with the JSON key NeuralTrust provides:
kubectl create secret docker-registry gcr-secret \
  --docker-server=europe-west1-docker.pkg.dev \
  --docker-username=_json_key \
  --docker-password="$(cat path/to/gcr-keys.json)" \
  [email protected] \
  -n neuraltrust
The chart references this secret from every subchart’s imagePullSecrets (defaults: ["gcr-secret"]).

Internal mirror (one override)

global:
  imageRegistry: "registry.internal.example.com/neuraltrust"
The chart’s image helper strips the default GCP prefix and prepends yours — so
europe-west1-docker.pkg.dev/neuraltrust-app-prod/nt-docker/control-plane-api
becomes
registry.internal.example.com/neuraltrust/control-plane-api
with no other override required.

Three escalating customization levels

You mirror images with…What to override
Same short names, same tagsonly global.imageRegistry
Same short names, custom tagsglobal.imageRegistry + per-component image.tag
Renamed paths (e.g. my-registry.corp/cp-api)global.imageRegistry + per-component image.repository + image.tag
Per-component override paths:
PathComponent
neuraltrust-control-plane.controlPlane.components.{api,app,scheduler,postgresql}.image.{repository,tag}Control Plane
neuraltrust-data-plane.dataPlane.components.{api,worker}.image.{repository,tag}Data Plane
neuraltrust-data-plane.dataPlane.components.kafka.connect.image.{repository,tag}Kafka Connect
neuraltrust-firewall.firewall.gateway.image.* / workerDefaults.image.*Firewall
trustgate.global.image.{image,tag}TrustGate
trustgate.redis.image.{repository,tag}Redis
clickhouse.image.{repository,tag}ClickHouse
kafka.image.{repository,tag}Kafka

Mirroring for air-gapped installs

helm template neuraltrust-platform \
  oci://europe-west1-docker.pkg.dev/neuraltrust-app-prod/helm-charts/neuraltrust-platform \
  --version <VERSION> \
  -f my-values.yaml \
  | yq '.. | select(has("image")) | .image' \
  | sort -u
Mirror each image to your internal registry with crane, skopeo, or docker pull/push, then set global.imageRegistry. Verify rendered images:
helm template . -f my-values.yaml | grep -E '^\s+image:' | sort -u

Storage class — cluster default or explicit

PVCs are created for ClickHouse, Kafka, PostgreSQL, Redis, and the optional OpenTelemetry collector buffer.

Cluster default (default behavior)

Values keyDefault
global.storageClass""
When empty, the chart omits storageClassName from PVC specs, which falls back to the cluster’s default StorageClass. Confirm one exists:
kubectl get storageclass
# default class is marked with (default)

Explicit, cluster-wide

global:
  storageClass: "pd-balanced"               # GKE example
  # storageClass: "gp3"                      # AWS EKS
  # storageClass: "managed-csi-premium"      # Azure AKS
  # storageClass: "longhorn"                 # bare metal

Per-component overrides

ComponentValues keyRecommended for prod
ClickHouseclickhouse.persistence.storageClassSSD-backed (pd-ssd, io2, managed-csi-premium) for high-throughput
Kafkakafka.persistence.storageClassSSD-backed
PostgreSQLneuraltrust-control-plane.controlPlane.components.postgresql.persistence.storageClassSSD-backed
Redis (TrustGate)trustgate.global.storageClass (inherits umbrella global.storageClass)Default
OTel collector buffer (optional)global.observability.collector.bufferPVC.storageClassDefault
Per-component override wins over global.storageClass. Empty per-component = inherit global.storageClass = inherit cluster default.

Secrets — auto-generated, explicit, or pre-created

Two top-level flags control how the chart manages secrets.
Values keyDefaultBehavior
global.autoGenerateSecretstrueChart generates random secrets on first install; reuses existing on upgrade.
global.preserveExistingSecretsfalseWhen true, all secret templates are skipped (parent + subcharts). You must pre-create everything.
Use autoGenerateSecrets: true for quick installs and dev/test. Use preserveExistingSecrets: true when you manage secrets with Vault, Sealed Secrets, External Secrets Operator, SOPS, or any other secret manager.

Required secrets per scenario

Always required, regardless of mode:
SecretTypeCreated by
gcr-secretdocker-registryYou (manual, pre-install)
Auto-generated by default (when autoGenerateSecrets: true):
ScenarioSecretKeys
Hybrid (CP off)data-plane-jwt-secretDATA_PLANE_JWT_SECRET
trustgate-secretsDATABASE_HOST, DATABASE_PORT, DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME, DATABASE_SSL_MODE, DATABASE_URL, SERVER_SECRET_KEY, NEURAL_TRUST_FIREWALL_URL, NEURAL_TRUST_FIREWALL_SECRET_KEY
firewall-secretsJWT_SECRET (optional HUGGINGFACE_TOKEN)
postgresql-secretsPOSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB, POSTGRES_HOST, POSTGRES_PORT, DATABASE_URL, POSTGRES_PRISMA_URL
clickhouseadmin-password
clickhouse-secretsCLICKHOUSE_HOST, CLICKHOUSE_PORT, CLICKHOUSE_USER, CLICKHOUSE_DATABASE
neuraltrust-ingress-tls (if global.ingress.tls.autoGenerate: true)tls.crt, tls.key
Self-hosted (adds CP)control-plane-secretsCONTROL_PLANE_JWT_SECRET, TRUSTGATE_JWT_SECRET, FIREWALL_API_URL (optional Resend / LLM keys)
Optional (only if non-empty values)openai-secrets, google-secrets, resend-secrets, huggingface-secretsprovider-specific

Pre-creating secrets (preserveExistingSecrets: true)

Required for: production setups with external secret managers, GitOps flows where chart-rendered Secrets cause drift, or air-gapped environments where you bake secrets into your golden state.
global:
  preserveExistingSecrets: true             # chart will not render any secret templates
You must pre-create the secrets above before helm upgrade --install. The chart ships create-secrets.sh and SECRETS.md as a starting template. For per-secret keys and a worked example, see Secrets management.

Topology cheat sheet

A condensed view of the toggles people set on day one:
global:
  platform: "gcp"                  # aws | gcp | azure | openshift | kubernetes
  domain: "platform.example.com"
  storageClass: ""                 # "" = cluster default
  imageRegistry: ""                # "" = NeuralTrust GCR
  autoGenerateSecrets: true        # false + preserveExistingSecrets for prod
  preserveExistingSecrets: false

neuraltrust-control-plane:
  controlPlane:
    enabled: false                 # true = self-hosted
  infrastructure:
    postgresql:
      deploy: true                 # false = external

neuraltrust-data-plane:
  dataPlane:
    enabled: true

trustgate:
  enabled: true
  redis:
    enabled: true                  # false + REDIS_HOST env = external (see Redis caveat)

neuraltrust-firewall:
  firewall:
    enabled: true                  # always on in supported topologies (CPU or GPU workers)

infrastructure:
  clickhouse:
    deploy: true                   # false = external
  kafka:
    deploy: true                   # false = external