Skip to content

Configuration overview

Choose how to configure networking, data stores, sandboxes, authentication, and advanced settings for self-hosted Dreadnode.

Everything in the Configure group is chart configuration. It is declarative, it is applied by a redeploy, and it rolls pods. Dreadnode exposes the same chart settings through three configuration interfaces:

InterfaceUse it forConfiguration shape
HelmExisting Kubernetes clustersUmbrella-chart values overlay
Admin ConsoleInteractive Embedded Cluster installs and editsLabeled fields under Config
KOTS ConfigValuesAutomated Embedded Cluster installationReplicated ConfigValues YAML

Settings that live in the running product instead — model deployments, credentials, users, organizations, signup rules — are not here. See Model deployments and Users and organizations.

Every configuration section below uses the same three tabs. Your selection follows you across this section. A KOTS ConfigValues file uses the Admin Console field’s internal item name, not the Helm value path. Every ConfigValues scalar is a string, including numbers and booleans; password items use valuePlaintext so KOTS encrypts them during installation.

Start with the domain, scheme, ingress class, and resource preset on this page. Use the focused guides for settings that need additional infrastructure or verification.

The domain appears in every URL Dreadnode generates, including OAuth redirects, presigned S3 URLs, and password reset links.

Set both values in your Helm overlay:

global:
domain: dreadnode.example.com
scheme: https # http (default) or https

Set both values correctly before first use. When you change either value, redeploy the release and access Dreadnode through the newly configured URL. Before changing an Embedded Cluster install from HTTP to HTTPS, create the TLS Secret and follow TLS certificates.

The domain also seeds the OpenSandbox runtime authority: leaving the sandbox domain empty derives sandbox.<domain>, so changing the platform domain moves the wildcard that browsers use to reach runtimes. Update DNS and the certificate alongside it — see Route browsers to OpenSandbox runtimes.

The chart emits standard Kubernetes Ingress resources. Set the class to the controller that should reconcile them:

global:
ingress:
className: traefik
annotations: {}
httpsRedirect: auto # auto | traefik | none

Global annotations cascade to the API, frontend, docs, and MinIO Ingress resources. Use subchart-specific annotations only when one route needs different controller behavior.

Choosing https decides what URLs Dreadnode generates. It does not by itself stop the ingress controller answering on port 80, so a bookmarked http:// link still loads a working UI whose API calls travel in cleartext. The httpsRedirect setting is what closes that:

ValueBehavior
autoDefault. Renders a Traefik redirect Middleware when an enabled Ingress resolves to class traefik. Covers Embedded Cluster, which bundles Traefik.
traefikAlways renders it. Use when Traefik is the cluster’s default class and you left className empty.
noneRenders nothing. Use only when a load balancer or proxy ahead of the cluster already redirects.

On a Helm install using another controller, the chart cannot render a portable redirect, so you own it through annotations. For ingress-nginx:

global:
ingress:
className: nginx
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: 'true'

If your cluster routes traffic through the Kubernetes Gateway API — Istio, Envoy Gateway, Cilium, or Traefik’s gateway provider — the chart can expose the platform as HTTPRoute resources attached to your existing Gateway instead of Ingress:

global:
httproute:
parentRefs:
- name: main-gateway
namespace: gateway-system
dreadnode-api:
ingress:
enabled: false
httproute:
enabled: true
dreadnode-frontend:
ingress:
enabled: false
httproute:
enabled: true
dreadnode-base:
minio:
apiIngress:
enabled: false
httproute:
enabled: true
dreadnode-sandbox-server:
gateway:
ingress:
enabled: false
httproute:
enabled: true

If the LiteLLM proxy is enabled, switch dreadnode-litellm the same way. Each service accepts its own httproute.parentRefs, hostnames, matches, and filters when the shared cascade is not enough — see the chart README for the full key reference.

The chart never creates the Gateway — your cluster operator owns it, along with its listeners and certificates. Ingress and HTTPRoute are mutually exclusive per service, and the chart fails the render with a pointed error if both are enabled.

Requirements on the Gateway side:

  • The Gateway API CRDs and a controller must be installed, and the Gateway you reference must exist. Cross-namespace attachment requires the Gateway’s allowedRoutes to admit the install namespace.
  • Listeners must cover <domain>, storage.<domain> (the MinIO S3 endpoint), and the wildcard sandbox authority *.sandbox.<domain> used for per-sandbox URLs — a wildcard *.<domain> listener alongside the <domain> one covers storage, but the sandbox authority nests one level deeper and needs its own *.sandbox.<domain> listener with a matching wildcard certificate.
  • Under scheme: https, TLS terminates on the Gateway’s listener (mode: Terminate with certificateRefs), so the chart does not require global.tls.secretName. The HTTP-to-HTTPS redirect is also the Gateway’s job — an HTTP listener answering with a RequestRedirect filter, or your controller’s equivalent.

After deploying, confirm the routes attached:

Terminal window
kubectl -n <namespace> get httproute
# NAME HOSTNAMES AGE
# dreadnode-api ["dreadnode.example.com"] 1m
# dreadnode-frontend ["dreadnode.example.com"] 1m
# dreadnode-docs ["dreadnode.example.com"] 1m
# dreadnode-minio ["storage.dreadnode.example.com"] 1m
# dreadnode-sandbox-server-gateway ["*.sandbox.dreadnode.example.com"] 1m

A route that never becomes Accepted in its status conditions usually means no listener matches its hostname, or the Gateway’s allowedRoutes rejects the namespace.

Plane: chart values / Admin Console. The documentation you are reading ships inside the release and is served by the deployment at /docs on your domain, so every help link in the application resolves without leaving your network. It is on by default and needs nothing from you.

Disable it only if your users should read documentation somewhere else, and name that place at the same time. The application’s help links resolve against docsUrl, so the chart refuses to render the bundled docs turned off with nothing to replace them.

dreadnode-docs:
enabled: false
dreadnode-api:
config:
docsUrl: https://docs.internal.example.com/

If you run your own ingress with the chart’s disabled, route /docs to the dreadnode-docs Service the way you already route /api. In Gateway API mode the route is created for you. What the bundled copy leaves out on an isolated network is described under Air-gapped installation.

dreadnode-api:
config:
network:
trustedProxyHops: 1

Dreadnode reads the client address this many hops from the right of X-Forwarded-For. The default of 1 is correct when your ingress controller is the only thing in front of the platform. Add one for each additional load balancer or CDN. Setting it too low attributes activity to your load balancer instead of the user; setting it too high lets a client spoof its own address in the audit trail.

Item submission integrations deliver findings to external systems — Linear, Jira, bug bounty platforms, and arbitrary webhooks. Turn them off if findings must not leave your network:

dreadnode-api:
config:
integrations:
enabled: false

This is a hard stop rather than a display preference. The integrations API refuses every request while it is off, so a user driving the API directly cannot submit either, and a submission already in progress when you apply the change is recorded as failed instead of being delivered.

Existing connections and submission history are kept. Turning integrations back on makes them reachable again with nothing to reconfigure — but read the audit trail first if you switched off in response to an incident, because the history is unreachable through the product while the switch is off.

Bundled PostgreSQL, ClickHouse, and object storage each get their own volume:

dreadnode-base:
postgresql:
primary:
persistence:
size: 8Gi
storageClass: '' # empty uses the cluster default
clickhouse:
persistence:
size: 10Gi
minio:
persistence:
size: 10Gi

Size these before the first deploy. Growing a volume afterward requires a StorageClass with allowVolumeExpansion plus a manual edit, and shrinking one is not possible at all.

ClickHouse is the volume that fills first, because every agent run writes trace spans to it. If you would rather cap growth than add disk, see the retention settings in Operations.

global:
resourcesPreset: small # small | medium | large

The preset applies a component-specific resource profile across the release:

PresetSuggested deployment sizeAPI requestsAPI limits
smallUp to about 50 users250m, 1536Mi500m, 2Gi
mediumAbout 50–200 users500m, 2Gi1000m, 3Gi
largeMore than 200 users1000m, 3Gi4000m, 8Gi

The small preset is the default. See Install with Helm — Resource guidance for cluster capacity guidance. Resource presets do not size dynamically created OpenSandbox pods. Configure their scheduling requests separately under Sandbox Runtime; see Size OpenSandbox pods.

Keep your overlay in source control and apply it with helm upgrade:

Terminal window
helm upgrade dreadnode oci://registry.replicated.com/dreadnode/dreadnode \
--version <version> \
--namespace <namespace> \
-f values.yaml

For settings without a dedicated Admin Console field or ConfigValues item, use Advanced Helm Values. For every available Helm value and its default, pull the chart’s values file:

Terminal window
helm show values oci://registry.replicated.com/dreadnode/dreadnode --version <version>