Skip to content

Helm Values Reference

Full reference for values.yaml. Pass overrides via --set key=value or a values.yaml file.

helm upgrade --install kubemanta oci://registry.kubemanta.com/kubemanta/charts/stable/kubemanta \
  --version CHART_VERSION \
  -n kubemanta-system --create-namespace \
  -f my-values.yaml

Which version?

Replace CHART_VERSION with the release you are installing. The newest is at the top of the Changelog, or read it from the registry once you are logged in:

helm show chart oci://registry.kubemanta.com/kubemanta/charts/stable/kubemanta | grep '^version:'

Always pin it. An unpinned install resolves to whatever stable points at today, which is not necessarily the release you tested against.


Global

Value Default Description
global.hostname "" Public hostname for the UI. When set, triggers Ingress creation + CORS auto-config.
global.tls true Enable HTTPS on the Ingress.
global.tlsProvider "" TLS mode: gcp-managed · acm · cert-manager · manual. Auto-detected from ingressClassName when empty.
global.tlsSecret "" Name of an existing TLS Secret (manual mode).
global.certManagerIssuer letsencrypt-prod cert-manager ClusterIssuer name.
global.installCertManager false Install cert-manager as a subchart + create a Let's Encrypt ClusterIssuer automatically. Requires certManagerIssuerEmail.
global.certManagerIssuerEmail "" Email for Let's Encrypt ACME registration (required when installCertManager=true).
global.ingressClassName "" Ingress class: gce · alb · nginx, or any installed class. These three are the ones the chart auto-detects a TLS mode for (gce→Google-managed, alb→ACM, nginx→cert-manager); any other class, traefik included, takes the cert-manager path.
global.staticIpName "" GCP only: name of a reserved global static IP to pin the GCE load balancer.
global.acmCertificateArn "" AWS only: ACM certificate ARN for ALB TLS termination.
global.pullToken "" GHCR PAT fallback (internal/dev only). Use license.key for all customer installs.

License

Value Default Description
license.key "" Per-cluster license key. Stored in a Secret; auto-creates the registry pull secret for registry.kubemanta.com.
license.accountId cf6c7851-... Pre-set licensing account ID — do not change.
license.apiUrl https://api.keygen.sh License service URL (override only for a self-hosted licence service).

RBAC

Value Default Description
rbac.allowWrites false Grant the agent write verbs: pod restart/delete, deployment scale, namespace create, pod exec. Read-only without this.
rbac.readSecrets true Grant the agent get/list on Secrets. On by default: an operator with a plain kubeconfig reads Secrets in k9s anyway, so withholding it only made KubeManta look less capable than the tool it replaces. Secret values are still protected where it matters — every AI/MCP tool result crosses the redaction boundary, and per-tool grants can deny object-reading tools outright. Scope it with rbac.secretsNamespaces, or set false to withhold it. DELETE is never granted.

Security

Value Default Description
security.adminPassword "" Admin password, seeded at install (the agent sets it on first startup — there is no first-login setup, which is blocked from a public URL by design). Empty = auto-generate a stable one; retrieve it with kubectl get secret <release>-admin -n <ns> -o jsonpath='{.data.password}' \| base64 -d. The seed never overwrites an already-set password (a later recovery or Admin change survives upgrades). Min 8 chars.
~~security.apiKey~~ Removed. Programmatic access and the MCP server now use per-user API keys, created in Admin → Users. There is no shared secret to configure. See Security model.
security.appArmorProfile runtime/default AppArmor profile applied to every container. Relax knob for policy-enforced clusters: set unconfined to emit no AppArmor annotation (e.g. if a terminal user's tooling needs syscalls the default profile blocks), or localhost/<name> to pin a custom loaded profile.
security.cookieSecure auto Session-cookie Secure attribute. auto computes it from the exposure (true when serving HTTPS via Ingress, false for port-forward / HTTP-only). Set an explicit true/false to override — required (true) when you serve HTTPS through your own edge with no hostname set.
security.aiRateLimitPerMin 10 Per-session AI request rate limit.
security.discoveryRateLimitPerMin 300 K8s API discovery rate limit.
security.requireApproval false Force approval for all AI write operations (overrides agent mode).
security.viewerPassword "" Optional viewer password → read-only "viewer" role (bcrypt hash or plaintext). Empty = single-admin mode.
security.encryptionAtRest true Encrypt cloud/Helm/integration/SSO credentials in SQLite with AES-256-GCM. A random key is generated on first install and preserved across upgrades (helm.sh/resource-policy: keep).
security.encryptionKey "" BYO encryption key (raw 16/24/32 bytes or base64). Empty = auto-generated.
security.blockImds true NetworkPolicy that blocks access to the cloud Instance Metadata Service (169.254.169.254) from all pods in kubemanta-system.
security.trustedProxyCidrs "" Comma-separated CIDRs of proxies/LBs allowed to set X-Forwarded-For. Empty = trust nothing (always use the socket peer). Required in service-only mode.
security.sessionIdleTimeout 28800 Sliding session idle-timeout in seconds (every authenticated request extends it). 0 disables the idle check; the absolute 24h TTL always remains the hard ceiling. Runtime-editable in Admin → Access Control.

Hardened by default (OPA Gatekeeper / restricted clusters)

Every container ships non-root with a read-only root filesystem, dropped capabilities, RuntimeDefault seccomp, an AppArmor annotation, projected ServiceAccount tokens, and CPU + memory limits — no profile flag to flip. On a policy-enforced cluster you must allowlist the KubeManta images (registry.kubemanta.com/kubemanta/*, the python:3.12-alpine preflight image, and aquasec/trivy:* for self-scan). security.appArmorProfile and terminal.readOnlyRootFilesystem are the two relax knobs. See Restricted / policy-enforced clusters.


Container scanning

Value Default Description
security.scanning.enabled true Read-only: grants the reader role get/list on CRDs (to detect trivy-operator) + get/list/watch on trivy-operator report CRDs, and lets an admin trigger a scan. On by default so the Security tab works out of the box — reading reports and detecting the operator never writes to your cluster. Set false to turn scanning off entirely: the reader role isn't broadened and POST /security/scan is refused with a 403. Running the built-in self-scan is a separate Pro feature that also requires expertMode.enabled=true.
security.scanning.mode auto Scan-source seed: auto · operator (BYO, hard-disables self-scan) · self. Overridden at runtime by the admin scanner_source setting.
security.scanning.retentionDays 90 How long scan history is kept — scan_runs, vuln_findings and posture_findings, pruned by age on the insert path.
security.scanning.selfScan.image aquasec/trivy:0.74.0 Trivy image for the self-scan Job.
security.scanning.selfScan.cache.enabled true Reuse a PVC for Trivy's CVE database between scans. Off, every scan re-downloads ~103 MB (measured 73s cold vs 33s warm).
security.scanning.selfScan.cache.size 2Gi Size of that cache PVC.
security.scanning.selfScan.resources 250m/256Mi req, 1/1Gi limit Self-scan Job resources.

selfScan.waitSecs was removed

POST /security/scan no longer waits for the scan. It launches the Job and returns {"status": "running", "job_name": ...} immediately; results are collected by a background sweep and by GET /security/scan/{id}. The old bounded wait defaulted below the time a real cold scan takes, so timed_out was the common outcome for a Job that succeeded moments later. Setting selfScan.waitSecs now has no effect and can be dropped from your values.

Self-scan additionally requires expertMode.enabled=true (the Job is created via expert-exec). See Container Scanning.


Metrics

Value Default Description
metrics.kubeletScrape.enabled true Pod network bandwidth, scraped from each kubelet's built-in cadvisor. metrics-server exposes no network metrics at all, so cadvisor — already running inside every kubelet, nothing to deploy — is the only in-cluster source. On by default, because the grant it needs is narrow: the agent dials each kubelet directly and the kubelet authorizes that against nodes/metrics, which covers the metrics endpoints and nothing else. CPU/memory always come from metrics-server and are unaffected either way; only bandwidth stops when it's off. Exposed to the agent as METRICS_KUBELET_SCRAPE.
metrics.kubeletScrape.viaProxy false Fallback for clusters that firewall port 10250 from pods: routes the scrape through the API server instead. This is the only setting that puts nodes/proxy in the ClusterRole.

nodes/metrics is the kubelet's metrics endpoints and nothing else — no exec, no logs, no arbitrary proxying — which is why the scrape is on by default. nodes/proxy is the broad verb that reaches every kubelet handler, and it is granted only by metrics.kubeletScrape.viaProxy=true. Prefer your own Prometheus instead? Set metrics.kubeletScrape.enabled=false and point the metrics source at prometheus (PUT /metrics/source) — Admin → Observability → Generate scrape config emits the RBAC + prometheus.yml your Prometheus needs. See Metrics.


Agent

Value Default Description
agent.prometheusUrl "" Prometheus API URL (e.g. http://prometheus-server.monitoring.svc:9090). Enables the query_metrics PromQL tool. Seed only — a Prometheus source saved in Admin → Observability takes precedence at runtime.
agent.alertInvestigation false Auto-investigate critical alerts with the AI agent and post results to Slack.
agent.alertMinSeverity critical Minimum severity to trigger autonomous investigation: critical · high · medium.
agent.agentApiKey "" Anthropic API key for autonomous alert investigations. Stored in a Secret.
agent.anthropicApiKey "" Server-side default Anthropic key for the agent's AI loop (stored in a Secret). Never exposed to PTY terminal sessions — the terminal is BYO-LLM (ANTHROPIC_API_KEY is stripped from the PTY env; Claude Code authenticates via its own claude OAuth login).
agent.blastRadiusLimit 5 Max write operations per agent session. Sessions that hit this limit block further write tools.
agent.circuitBreakerThreshold 3 Number of consecutive write-tool failures before the circuit breaker trips.
agent.circuitBreakerResetSecs 300 Seconds before the circuit breaker auto-resets.

Expert Mode

Value Default Description
expertMode.enabled false Provision the separate kubemanta-expert-exec pod holding the cluster-admin token (used by the terminal and Helm/agent write ops). Default off — the agent pod never mounts this token.
expertMode.image / expertMode.tag "" Override image/tag for the expert-exec pod (defaults to image.repository/tag).
expertMode.resources 500m/256Mi limit, 100m/128Mi req expert-exec pod resources.

Terminal

Value Default Description
terminal.image / terminal.tag "" Override image/tag for the terminal sidecar (defaults to agent image).
terminal.readOnlyRootFilesystem true Read-only root filesystem on the terminal sidecar (hardened). Relax knob for the one container where users run arbitrary commands: set false if a user's tooling insists on writing outside $HOME and /tmp (both stay writable regardless). Every other container's root filesystem is read-only unconditionally.
terminal.idleTimeoutSecs 0 Terminate a terminal session with no PTY I/O for this many seconds and reclaim its slot/RAM. 0 (the default) never reaps an idle terminal, because watching k9s or tailing logs produces no input — so an input-based timeout kills the session being watched most attentively. Set a positive number to enable the reaper.
terminal.resources.limits.cpu 2 CPU limit for the terminal sidecar.
terminal.resources.limits.memory 8Gi Memory limit for the terminal sidecar — the container limit is what actually bounds a terminal's memory. Sized so an SRE can run memory-hungry tooling without thinking about it.

Enterprise SSO

Value Default Description
sso.publicUrl "" Optional seed for the SSO wizard's external_base_url (ACS/EntityID base). Only pre-fills the wizard; the admin-entered config is authoritative. See Enterprise SSO.

Persistence

Value Default Description
persistence.enabled true Create a PVC for agent data (SQLite DB, terminal home, Helm cache).
persistence.size 1Gi PVC size.
persistence.storageClass "" StorageClass name. Empty = cluster default.
persistence.mountPath /data/kubemanta Mount path inside the agent container.

A+ SQLite → S3 replication (Litestream)

Optional continuous replication of the SQLite DB to object storage, so the pod survives node/PVC loss. Default off — a default install is unchanged. See Disaster Recovery.

Value Default Description
persistence.replication.enabled false Enable Litestream WAL replication. With persistence.enabled=false the DB dir becomes an emptyDir, a restore init-container rebuilds the DB on boot, and a sidecar ships the WAL continuously.
persistence.replication.bucket "" Required when enabled. Target bucket.
persistence.replication.path kubemanta-db Key prefix within the bucket.
persistence.replication.region us-east-1 Bucket region.
persistence.replication.endpoint "" Set for MinIO / other S3-compatible stores.
persistence.replication.forcePathStyle false Set true for MinIO / path-style endpoints.
persistence.replication.credentialsSecret "" Secret with AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY. Empty = use IRSA / workload identity.
persistence.replication.image litestream/litestream:0.3.13 Litestream image.

Warning

Run an attended kill-pod failover test against your real object store once, before you depend on this. Never host the bucket in the cluster you are observing.


Alerting

Value Default Description
alerting.webhookUrl "" Webhook URL for alert delivery.
alerting.slackWebhookUrl "" Slack incoming webhook URL.
alerting.pagerdutyRoutingKey "" PagerDuty Events API v2 routing key.
alerting.watchIntervalSecs 60 Alert rule evaluation interval.
alerting.dedupeWindowSecs 300 Cooldown window per rule+resource to suppress repeated firings.

Audit

Value Default Description
audit.webhookUrl "" Forward every audited request to an HTTP collector (SIEM / Splunk). Disabled when empty.
audit.webhookToken "" Optional Bearer token for the audit webhook. Stored in the agent Secret.
audit.worm.enabled false Tamper-evident off-box WORM export: write every audit row as one object into an Object-Lock S3 bucket (closes the trim-newest-rows gap the in-DB hash-chain can't). See Activity & Audit.
audit.worm.bucket "" Target bucket (Object Lock + default retention required).
audit.worm.prefix audit Key prefix.
audit.worm.region us-east-1 Bucket region.
audit.worm.endpoint "" Set for MinIO / S3-compatible; empty = real AWS S3.
audit.worm.credentialsSecret "" Secret holding S3 credentials. Empty = IRSA / workload identity.

The in-pod audit_log is always hash-chained regardless of this block — verify it with GET /audit/verify-chain.


Cloud provider

Value Default Description
aws.region "" AWS region override (auto-discovered from topology.kubernetes.io/region node label when empty).
gcp.region "" GCP region override (auto-discovered).
azure.location "" Azure location override (auto-discovered).

Namespace control

Value Default Description
tenantNamespaces [] Restrict KubeManta to these namespaces. Empty = auto-discover all non-system namespaces.
blocklist see values.yaml Namespaces always hidden. Includes kube-system, kube-public, kubemanta-system, istio-system, cert-manager, argo, argocd, and others.

Image and resources

Value Default Description
replicaCount 1 Agent replicas. The agent is stateful (RWO PVC) — keep at 1 unless your storage is RWX.
image.repository registry.kubemanta.com/kubemanta/kubemanta-agent Agent image.
image.tag "" Agent image tag. Empty means "use the chart's appVersion" — so the version you run is the version the chart you installed was built for. It was latest until 2026-07-30, which decoupled the two and let the running version change under you with no change on your side. Set this (or better, image.digest) to pin explicitly.
image.pullPolicy Always Image pull policy.
resources.requests.cpu 250m Agent CPU request (for scheduling).
resources.requests.memory 1Gi Agent memory request.
resources.limits.memory 2Gi Agent memory limit (== request, so the working set is reserved and bounded). No CPU limit by default — a hard CPU cap throttles the async event loop (a 250m cap caused /healthz >1s + overview timeouts). Use priorityClassName for eviction protection instead.
ui.image.repository registry.kubemanta.com/kubemanta/kubemanta-ui UI image.
ui.image.tag "" UI image tag. Empty means "use the chart's appVersion", as with image.tag above.
ui.resources.limits.cpu 1 UI CPU limit.
ui.resources.limits.memory 256Mi UI memory limit.

Sizing presets

The defaults are the Medium tier (≤ ~1,000 pods). Apply a preset with a second -f: -f helm/values-small.yaml (≤200 pods, mem 256Mi) or -f helm/values-large.yaml (≤5,000 pods, mem 1Gi). All-cluster list calls are paginated, so memory doesn't scale with cluster size.


Scheduling & availability

Value Default Description
priorityClassName "" Makes the agent harder to evict under node pressure. For production set an existing high-priority class (e.g. system-cluster-critical). Pair with Guaranteed/reserved memory.
updateStrategy {} Empty = auto: Recreate while the agent holds a ReadWriteOnce PVC (a rolling update would deadlock on Multi-Attach), RollingUpdate once persistence is off. Override only if your storage is ReadWriteMany.
podDisruptionBudget.enabled false Off by default: at replicaCount: 1 a PDB cannot provide availability and maxUnavailable: 0 will block node drains. Enable once you run replicas > 1, or to deliberately make the single replica un-evictable by the autoscaler.
podDisruptionBudget.maxUnavailable 0 Used when the PDB is enabled.
podDisruptionBudget.minAvailable "" Set (e.g. 1) to use minAvailable instead of maxUnavailable.

Exposure

Value Default Description
ingress.enabled true false = service-only mode: render only the agent + UI Services (no Ingress/BackendConfig/ManagedCertificate) so you can front KubeManta with your own edge/LB/Gateway/WAF. See Access Control.
service.type ClusterIP Agent Service type: ClusterIP · NodePort · LoadBalancer.
service.port 8080 Agent Service port.
service.annotations {} Pass-through annotations (e.g. internal-LB).
ui.service.type ClusterIP UI Service type.
ui.service.nodePort "" Pin the NodePort (30000–32767) when type=NodePort.
ui.service.annotations {} Pass-through annotations for the UI Service.

Service-only mode requires security.trustedProxyCidrs

When you front KubeManta yourself, you must set security.trustedProxyCidrs to your edge's egress CIDR(s) — otherwise every request is attributed to the proxy IP, breaking audit attribution and applying your allowlist/denylist to the edge rather than to the real client. The terminal WebSocket path /api/agent/terminal/ws must reach the agent Service directly; all other traffic goes to the UI Service.