Skip to main content

Console Helm values

Configure the console chart with these Helm values.

This reference lists values declared in the chart's default values.yaml. Templates can also accept optional settings and inherited global values.

Chart: toolhive-cloud-ui. Chart version: 0.22.0. Generated from the platform source at e71926418e98c7598815d0abf07039d3c1646f21.

Values​

replicaCount​

Type: int

Default: 1

Number of replicas for the deployment. Ignored when ha.enabled or autoscaling.enabled is true.

ha​

Type: object

Default value
antiAffinityPreset: soft
enabled: false
podDisruptionBudget:
minAvailable: 1
replicaCount: 2

High availability. Bundles replica count, a PodDisruptionBudget, and pod anti-affinity together so they can't drift apart — specifically, so a PDB can never be enabled without enough replicas to back it. A PDB with minAvailable >= the actual replica count blocks every voluntary disruption forever (node drains, cluster upgrades, cluster-autoscaler scale-down all wait on a budget Kubernetes can never satisfy while evicting a pod). The chart refuses to render if ha.enabled is true with fewer than 2 replicas.

ha.enabled​

Type: bool

Default: false

Enable HA mode: replicaCount above is ignored in favor of ha.replicaCount, a PodDisruptionBudget is created, and pod anti-affinity spreads replicas across nodes and zones.

ha.replicaCount​

Type: int

Default: 2

Replica count used when ha.enabled is true.

ha.podDisruptionBudget.minAvailable​

Type: int

Default: 1

Minimum number of pods that must remain available.

ha.antiAffinityPreset​

Type: string

Default: "soft"

Pod anti-affinity preset spreading replicas across nodes: "soft" (preferred — schedules even if it can't spread) or "hard" (required — refuses to schedule a replica on a node that already has one). Spreading across zones is always preferred, never required, so a single-zone cluster still schedules every replica.

image.repository​

Type: string

Default value
image-proxy.stacklok.com/proxy/stacklok-enterprise/ghcr.io/stacklok/stacklok-enterprise/cloud-ui

Image repository. Enterprise build produced by _release-toolhive-cloud-ui.yml (Next.js multi-stage build over the source in enterprise/toolhive-cloud-ui/), then promoted to the platform tag by release.yml. Served to customers via Replicated's image proxy. Customers running their own mirror override this in their values file. task version-bump rewrites the trailing :<tag> via a regex anchored on ghcr.io/stacklok/stacklok-enterprise/<name>: — that anchor still matches inside this longer proxy URL.

image.tag​

Type: string

Default: ""

Image tag (defaults to .Chart.AppVersion when empty, which tracks /VERSION via task version-bump).

image.pullPolicy​

Type: string

Default: "IfNotPresent"

Pull from registry if available, use local image if not

imagePullSecrets​

Type: list

Default: []

Extra image pull Secrets to apply to the cloud-ui pod. On Replicated installs, the SDK injects global.replicated.dockerconfigjson and creates an enterprise-pull-secret Secret in the release namespace; the toolhive-cloud-ui.imagePullSecrets helper auto-detects that injection and merges the SDK secret in front of anything listed here, so customers do NOT need to add enterprise-pull-secret themselves. Use this list only for additional, customer-supplied registries.

nameOverride​

Type: string

Default: ""

Override the name of the chart

fullnameOverride​

Type: string

Default: ""

Override the full name of the resources

serviceAccount.create​

Type: bool

Default: false

Specifies whether a service account should be created

serviceAccount.automount​

Type: bool

Default: true

Automatically mount a ServiceAccount's API credentials

serviceAccount.annotations​

Type: object

Default: {}

Annotations to add to the service account

serviceAccount.name​

Type: string

Default: ""

The name of the service account to use (if not set and create is true, a name is generated using the fullname template)

podAnnotations​

Type: object

Default: {}

Annotations to add to the pod

podLabels​

Type: object

Default: {}

Labels to add to the pod

podSecurityContext​

Type: object

Default value
fsGroup: 1001
runAsGroup: 1001
runAsNonRoot: true
runAsUser: 1001
seccompProfile:
type: RuntimeDefault

Security context for the pod

securityContext​

Type: object

Default value
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1001

Security context for the container

runtimeWritableDirs​

Type: object

Default: {"nextCache":{"sizeLimit":""},"tmp":{"sizeLimit":""}}

emptyDir volumes mounted at /tmp and /app/.next/cache so the container keeps working under the read-only root filesystem above. Next.js's standalone server writes to both at runtime (general tmp usage, and the built-in image optimizer's disk cache for next/image). sizeLimit is a Kubernetes resource-quantity string; empty means unbounded.

service.type​

Type: string

Default: "ClusterIP"

Kubernetes service type

service.port​

Type: int

Default: 80

Service port

service.targetPort​

Type: int

Default: 3000

Container target port

service.nodePort​

Type: string

Default: nil

NodePort (only used if type is NodePort, range: 30000-32767)

resources​

Type: object

Default: {"limits":{"cpu":"500m","memory":"512Mi"},"requests":{"cpu":"100m","memory":"128Mi"}}

Resource limits and requests for the container

startupProbe​

Type: object

Default value
failureThreshold: 30
httpGet:
path: /
port: http
initialDelaySeconds: 0
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 3

Startup probe configuration (checks if app is ready to start)

livenessProbe​

Type: object

Default value
failureThreshold: 3
httpGet:
path: /
port: http
initialDelaySeconds: 0
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5

Liveness probe configuration (checks if app is alive)

readinessProbe​

Type: object

Default value
failureThreshold: 3
httpGet:
path: /
port: http
initialDelaySeconds: 0
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 3

Readiness probe configuration (checks if app can receive traffic)

autoscaling.enabled​

Type: bool

Default: false

Enable Horizontal Pod Autoscaler

autoscaling.minReplicas​

Type: int

Default: 1

Minimum number of replicas

autoscaling.maxReplicas​

Type: int

Default: 5

Maximum number of replicas

autoscaling.targetCPUUtilizationPercentage​

Type: int

Default: 80

Target CPU utilization percentage

volumes​

Type: list

Default: []

Additional volumes for the pod

volumeMounts​

Type: list

Default: []

Additional volume mounts for the container

nodeSelector​

Type: object

Default: {}

Node labels for pod assignment

tolerations​

Type: list

Default: []

Tolerations for pod assignment

affinity​

Type: object

Default: {}

Affinity rules for pod assignment

networkPolicy​

Type: object

Default: {"allowExternalEgress":true,"egress":[],"enabled":false}

NetworkPolicy. Off by default. Turning this on matters most for clusters running a default-deny policy engine (Kyverno's add-network-policy, OPA Gatekeeper): those engines auto-attach a deny-all NetworkPolicy to any pod that has none of its own, so a chart that ships zero NetworkPolicy silently loses whatever traffic that engine decides to block. Shipping our own explicit policy — even a permissive one — means the cluster no longer treats this pod as unmanaged.

networkPolicy.allowExternalEgress​

Type: bool

Default: true

Allow all egress traffic. Recommended default: every outbound destination this app calls is a customer-configured URL (apiBaseUrl, global.stacklok.primaryIdp.issuer, enterpriseManagerUrl, gatewayApiUrl, redisUrl / redisUrlExistingSecret) that can point in-cluster or external — this chart has no way to know your actual values at template time, so a fixed allow-list here would be a guess. Set to false to lock egress down to exactly your deployment's destinations via the egress list below.

networkPolicy.egress​

Type: list

Default: []

Additional egress rules (Kubernetes NetworkPolicyEgressRule shape), applied when allowExternalEgress is false. Must cover DNS (UDP/TCP 53) plus every destination you've actually configured above — omitting one doesn't fail loudly, the app just can't reach it.

apiBaseUrl​

Type: string

Default: ""

Base URL of the Registry Server API. Required.

oidc​

Type: object

Default: {"additionalProviders":[]}

OpenID Connect (OIDC) and OAuth configuration. The primary provider's issuer, client credentials, and scopes come from global.stacklok.primaryIdp, shared with Enterprise Manager and Connector Gateway. For an IdP served by a private certificate authority, set global.stacklok.primaryIdp.caBundleRef with exactly one of secretRef or configMapRef, plus key (default ca.crt). The chart mounts that certificate bundle and sets NODE_EXTRA_CA_CERTS, extending Node's default trusted roots. Restart the pods after changing the bundle's contents. Changing the reference name or key triggers a rollout automatically. The console permits private IdP addresses.

oidc.additionalProviders​

Type: list

Default: []

Additional OIDC providers (opt-in; empty = single-provider mode). Each entry is rendered as OIDC_ADDITIONAL_PROVIDERS (JSON array) in the pod.

betterAuth​

Type: object

Default: {"existingSecret":"","existingSecretKey":"secret","secret":"","url":""}

Better Auth session management

betterAuth.secret​

Type: string

Default: ""

Token encryption secret as a plain value, at least 32 characters long. Required unless existingSecret is set. Prefer a Kubernetes Secret via existingSecret. Generate a value with openssl rand -base64 32.

betterAuth.existingSecret​

Type: string

Default: ""

Name of an existing Secret holding the token encryption secret. Takes precedence over secret above (rendered via secretKeyRef instead of a plaintext env var).

betterAuth.existingSecretKey​

Type: string

Default: "secret"

Key within existingSecret holding the token encryption secret.

betterAuth.url​

Type: string

Default: ""

Public URL of the console, used for authentication callbacks. Required. Must be externally reachable since the browser uses it during sign-in.

enterpriseManagerUrl​

Type: string

Default: ""

Base URL of Enterprise Manager, required for the administration experience. The console uses it for feature flags, configuration, and directory operations. When empty, administration pages fail with "No enterprise-manager API URL configured." There is no fallback URL.

gatewayApiUrl​

Type: string

Default: ""

LLM Gateway management API URL — server-to-server endpoint used by the cloud-UI for budget management, model catalog, etc. (calls /v1/budgets, /v1/models). NOT shown to end users. When set, takes effect via the GATEWAY_API_URL env var. May also be served by the config server's gateway.api_url directive; when both are set, the config-server value wins. Required (here or via the config server) for the "My Usage" page. NOTE: do not also set any of the vars below via .Values.env — the typed blocks emit before the env[] passthrough and produce a duplicate env entry.

gatewayProxyUrl​

Type: string

Default: ""

User-facing LLM Gateway proxy URL — the public proxy endpoint baked into the thv llm setup --gateway-url <url> command and shown in the "My Usage" connection banner. Typically distinct from gatewayApiUrl above. When set, takes effect via the GATEWAY_PROXY_URL env var. May also be served by the config server's gateway.proxy_url directive; when both are set, the config-server value wins.

connectorGatewayUrl​

Type: string

Default: ""

Base URL of the per-user Connector Gateway control-plane API (the /v1/users/me/gateway/... endpoints the "Connectors" pages call). When set, takes effect via the CONNECTOR_GATEWAY_API_URL env var; the nav entry + /tools/connectors*//neo/setup* routes are hidden while it is unset. Setting this alone is no longer sufficient to turn the feature on: those surfaces also require the connector-gateway install toggle (global.stacklok.connectorGateway.enabled at Helm render time, mirrored into the mounted AppConfig) to resolve true.

Address the CONTROL-PLANE Service, not the data-plane one: connector-gateway serves this API on its own port behind <fullname>-control-plane (controlPlane.port, default 8090) — e.g. http://<release>-connector-gateway-control-plane.<namespace>:8090. The data-plane Service (<fullname>, port 8443) serves /gw/mcp and will not answer these routes.

Unlike its sibling URL values above, this one is tpl-EVALUATED before it reaches the env var (deployment.yaml). That is what lets the umbrella chart hand this subchart a template string deriving the address from global.stacklok.connectorGateway.enabled — the component's own install toggle — rather than requiring an operator to set the same fact twice and get it silently wrong in either direction. A literal URL has no template actions and passes through unchanged, so nothing about setting this by hand changes.

Standalone default stays empty: with no umbrella above it, no safe cross-chart default exists (Service name/namespace and control-plane port are deployment-specific), and an empty value keeps the feature hidden rather than pointing the UI at a Service that may not exist.

thvCliOidcIssuerUrl​

Type: string

Default: ""

OIDC issuer URL used by the console's Stacklok CLI setup instructions. Set this and thvCliOidcClientId to enable the setup wizard.

thvCliOidcClientId​

Type: string

Default: ""

Public OAuth client ID used by the Stacklok CLI with PKCE. Set this and thvCliOidcIssuerUrl to enable the console's setup wizard.

thvCliOidcAudience​

Type: string

Default: ""

Optional OAuth audience included in the CLI setup command. Set it when the LLM gateway requires a specific JWT audience; empty omits the option.

thvCliOidcCallbackPort​

Type: string

Default: ""

Local OAuth callback port included in the CLI setup command. Set it to match the redirect URI registered with your IdP; empty uses the CLI default of 8666.

redisUrl​

Type: string

Default: ""

Optional Redis connection URL for server-side caching (currently used to cache SKILL.md previews pulled from OCI artifacts). External Redis only — the chart does not deploy a Redis instance. The SKILL.md preview is Redis-gated: when unset (or when Redis is unreachable) the cloud-ui hides the preview entirely rather than re-pulling on every request. Example: "redis://:password@redis.example.com:6379/0"

The URL embeds the Redis password. Prefer redisUrlExistingSecret below, which keeps the whole connection string (and its embedded credential) out of the rendered pod spec / Helm release object; redisUrl is kept for backward compatibility with existing installs that already set it directly.

redisUrlExistingSecret​

Type: string

Default: ""

Name of an existing Secret holding the full Redis connection URL. Takes precedence over redisUrl above (rendered via secretKeyRef instead of a plaintext env var).

redisUrlExistingSecretKey​

Type: string

Default: "redis-url"

Key within redisUrlExistingSecret holding the connection URL.

branding​

Type: object

Default: {"config":{"enabled":false,"json":{}},"faviconUrl":"","logoUrl":"","name":""}

Branding. Prefer the file-based config block below — it carries the app name, logo, favicon, and design tokens together as one payload. The legacy name/logoUrl/faviconUrl fields are also supported (they wire directly to env vars and skip the ConfigMap mount), useful for quick one-off overrides; when both are set, values from config.json win.

branding.config​

Type: object

Default: {"enabled":false,"json":{}}

File-based branding configuration mounted at /etc/branding/config.json and read by the console on each request. Set config.json to a branding object with app_name, logo_url, favicon_url, and design_tokens.

branding.name​

Type: string

Default: ""

Simple-override path (no ConfigMap required). Wires to BRAND_NAME, BRAND_LOGO_URL, FAVICON_URL env vars. Overridden by config.json when both are present.

env​

Type: list

Default: []

Additional env vars (escape hatch for experimental/uncommitted config). Prefer structured keys above when available.

envFrom​

Type: list

Default: []

Environment variables from ConfigMaps or Secrets