> ## Documentation Index
> Fetch the complete documentation index at: https://docs.genesiscomputing.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Helm Chart Values Reference

> Every setting the Genesis Helm chart accepts in its values file: what it does, its default, and when you need it.

This page lists every setting in the Genesis Helm chart's values file, `values.yaml`. Use it
alongside the install guide for your platform:
[AWS](https://docs.genesiscomputing.com/docs/deployments/AWS/Genesis-On-AWS.md),
[GCP](https://docs.genesiscomputing.com/docs/deployments/GCP/Genesis-On-GCP-GKE-Install.md),
[Azure](https://docs.genesiscomputing.com/docs/deployments/Azure/Genesis-On-Azure.md) or
[local Kubernetes](https://docs.genesiscomputing.com/docs/deployments/Local-Kubernetes/Deploying-Genesis-Local-Kubernetes.md).

Put your settings in your own values file and pass it with `-f`, or set one value at a time with
`--set`. Anything you leave out keeps the default shown here.

```bash theme={null}
helm upgrade --install genesis <chart reference> -f my-values.yaml
```

Pass the same values file on every upgrade. `helm upgrade` with `-f` starts again from the
chart's defaults plus that file, so a setting missing from it goes back to its default.

> [!NOTE]
>
> Settings for the Genesis application itself, such as LLM providers, connections and feature
> limits, are not Helm values. Put them in a Genesis config file passed with
> [`genesisConfig.content`](#genesis-config-file-rbac-and-role-mapping), or set them in
> **Config > Advanced Settings**. The [Configuration Reference](https://docs.genesiscomputing.com/docs/Setup/Configuration-Reference.md)
> lists all of them.

## What a new install must set

A first `helm install` fails unless these are set:

* `identity.clientName` and `identity.instanceName`: the name of this install. See
  [Install identity](#install-identity).
* A master encryption key: `secrets.genesisMasterKey`, `secrets.existingSecretGenesisMasterKey`,
  or `config.extraEnv.GENESIS_MASTER_KEY_REF`. See [Secrets](#secrets).

On `helm upgrade` neither is checked. An install that predates the names gets a reminder in
the upgrade notes instead of an error.

> [!WARNING]
>
> The chart does not keep the master key for you. Give the same master key setting on every
> upgrade. If `secrets.genesisMasterKey` is left out of an upgrade, the chart drops the key from
> the Secret it manages, and Helm deletes that Secret outright when no other credential set
> directly under `secrets.*` keeps it. Either way Genesis starts without your key, so the secrets
> it stored cannot be read. To avoid this, keep the key in a Secret you manage and point
> `secrets.existingSecretGenesisMasterKey` at it, or use `config.extraEnv.GENESIS_MASTER_KEY_REF`.

A minimal values file for a new install:

```yaml theme={null}
identity:
  clientName: "acme"      # your company
  instanceName: "prod2"   # this install among yours

secrets:
  genesisMasterKey: "<64 hex characters>"   # python -c "import secrets; print(secrets.token_hex(32))"

ingress:
  className: "nginx"
  hosts:
    - host: genesis.example.com
      paths:
        - path: /
          pathType: Prefix
          port: 8080
  tls:
    - secretName: genesis-tls
      hosts:
        - genesis.example.com
```

## Install identity

These name the install on everything it reports to Genesis Computing: metrics uploads, support
and enhancement requests, and logs. Genesis shows the install as `<clientName>.<instanceName>`,
for example `acme.prod2`.

| Key | Default | Description |
| - | - | - |
| `identity.clientName` | `""` | Your company's name, for example `acme`. **Required on a new install.** |
| `identity.instanceName` | `""` | This install's name among your installs, for example `prod2` or `dev1`. **Required on a new install.** |
| `identity.environment` | `""` | Genesis Credit billing environment: `prod` or `non-prod` (`dev`, `test` and `staging` also mean non-prod). Empty means `prod`. Spellings Genesis does not recognise, such as `non-produ`, fail the render. Non-prod is billed at a lower price per credit and must not serve production users or production data. A licence that names an environment wins. |

* Names are lowercased, any run of characters other than `a`–`z`, `0`–`9` and `-` becomes `-`,
  leading and trailing `-` are dropped, and each name is cut to 63 characters.
* They render as `GENESIS__SERVER__CLIENT_NAME`, `GENESIS__SERVER__INSTANCE_NAME` and
  `GENESIS__SERVER__BILLING_ENVIRONMENT`. Setting one of those keys in `config.extraEnv` instead
  also works, and an explicit `config.extraEnv` entry wins over `identity.*`, even an empty one.
* They can also be set in **Config > Advanced Settings > Server**, but a value set through the
  chart wins over one set there. If your licence carries a client name, the licence's name wins.

## Chart naming and namespace

| Key | Default | Description |
| - | - | - |
| `namespace` | `genesis` | Namespace the chart's objects go in. Empty uses the release namespace (`helm --namespace`). The chart creates this Namespace and marks it `helm.sh/resource-policy: keep`, so `helm uninstall` does not delete it or the data volume inside it. |
| `nameOverride` | not set | Replaces the chart name (`genesis`) in object names and labels. Not listed in `values.yaml`; set it only when you need it. |
| `fullnameOverride` | not set | Replaces the full object name prefix (normally `<release>-genesis`, or the release name when it already contains `genesis`). Not listed in `values.yaml`. Changing it on an existing install creates a new StatefulSet and a new, empty data volume. |

## Container image

| Key | Default | Description |
| - | - | - |
| `image.repository` | `ghcr.io/genesis-computing-ai/genesis` | Image repository. Ignored when `ecr.enabled` is true, which pulls `<ecr.registry>/genesis` instead. |
| `image.tag` | the chart's `appVersion` | Image tag, for example `v1.19.100`. Not listed in `values.yaml`; leave it unset to run the version the chart was released with. |
| `image.pullPolicy` | `IfNotPresent` | Kubernetes image pull policy for the Genesis container and its init containers. |
| `imagePullSecrets` | `[]` | Pull secrets for a private registry other than ECR, as a list of `name:` entries. Not needed when `ecr.enabled` is true. |

### Private Amazon ECR registry

| Key | Default | Description |
| - | - | - |
| `ecr.enabled` | `false` | Pull the Genesis image from your own ECR registry. The chart creates a `genesis-ecr-pull` pull secret and pulls `<ecr.registry>/genesis:<tag>`. |
| `ecr.registry` | `""` | Registry host, for example `123456789.dkr.ecr.us-east-1.amazonaws.com`. |
| `ecr.token` | not set | ECR password for the pull secret. Not listed in `values.yaml`; write it to a file only you can read, `(umask 077; printf %s "$(aws ecr get-login-password)" > ecr-token)`, and pass it with `--set-file ecr.token=ecr-token`, which keeps the token out of the process list. ECR tokens expire after 12 hours, so refresh the secret before the pod next needs to pull. |

## Secrets

Each credential can be given directly, in which case the chart stores it in a Kubernetes Secret it
creates, or by naming a Secret you already manage. Use one or the other for each credential.

| Key | Default | Description |
| - | - | - |
| `secrets.genesisMasterKey` | `""` | Master key that encrypts the secrets Genesis stores. Generate one with `python -c "import secrets; print(secrets.token_hex(32))"`. Required on a new install unless one of the two alternatives below is set, and must be passed again on every upgrade (see the warning above). Keep a copy: without it, stored secrets and state snapshots cannot be decrypted. |
| `secrets.existingSecretGenesisMasterKey.secretName` | `""` | Name of an existing Secret holding the master key. Set this or `secrets.genesisMasterKey`, not both: with both set, the pod can fail to start. The safest choice for production, because the Secret does not depend on what each upgrade passes. |
| `secrets.existingSecretGenesisMasterKey.secretKey` | `GENESIS_MASTER_KEY` | Key inside that Secret. |
| `secrets.existingSecretMintlifyJwtPrivateKey.secretName` | `""` | Existing Secret holding the Ed25519 private key for signing in to the hosted Genesis documentation. Only a Secret reference is accepted: never put this key in values, `config.extraEnv` or the Genesis config file. |
| `secrets.existingSecretMintlifyJwtPrivateKey.secretKey` | `MINTLIFY_JWT_PRIVATE_KEY` | Key inside that Secret. |
| `secrets.openaiApiKey` | `""` | OpenAI API key. With `config.azureOpenaiEndpoint` set it is also used as the Azure OpenAI key. Setting it selects OpenAI (or Azure OpenAI) as the starting LLM provider. |
| `secrets.existingSecretOpenaiApiKey.secretName` | `""` | Existing Secret holding the OpenAI API key, instead of `secrets.openaiApiKey`. |
| `secrets.existingSecretOpenaiApiKey.secretKey` | `OPENAI_API_KEY` | Key inside that Secret. |
| `secrets.databricksApiKey` | `""` | Databricks token for model serving. The chart sets both `DATABRICKS_API_KEY` and `DATABRICKS_TOKEN` from it. Setting it selects Databricks as the starting LLM provider. |
| `secrets.existingSecretDatabricksApiKey.secretName` | `""` | Existing Secret holding the Databricks token, instead of `secrets.databricksApiKey`. |
| `secrets.existingSecretDatabricksApiKey.secretKey` | `DATABRICKS_API_KEY` | Key inside that Secret. |
| `secrets.databricksDbPat` | `""` | Databricks personal access token for the SQL warehouse connection created by `config.databricksDb`. Separate from the model-serving token. |
| `secrets.existingSecretDatabricksDbPat.secretName` | `""` | Existing Secret holding that token, instead of `secrets.databricksDbPat`. |
| `secrets.existingSecretDatabricksDbPat.secretKey` | `DATABRICKS_DB_PAT` | Key inside that Secret. |
| `secrets.tsnetAuthKey` | `""` | Tailscale auth key. When set, the container starts an embedded Tailscale client and routes outbound HTTP through it, so Genesis can reach private gateways on your tailnet. Use an ephemeral, tagged, non-reusable key whose ACLs reach only the gateway it needs. |
| `secrets.existingSecretTsnetAuthKey.secretName` | `""` | Existing Secret holding the Tailscale auth key, instead of `secrets.tsnetAuthKey`. |
| `secrets.existingSecretTsnetAuthKey.secretKey` | `GENESIS_TSNET_AUTH_KEY` | Key inside that Secret. |

To fetch the master key from AWS Secrets Manager or Google Secret Manager at startup instead,
leave both master key settings empty and set `config.extraEnv.GENESIS_MASTER_KEY_REF` to a
reference such as `aws_prod/genesis-keys#master_key`. The pod needs cloud credentials (IRSA or
Workload Identity) for this. See [External Secrets](https://docs.genesiscomputing.com/docs/Setup/External-Secrets.md).

## Server settings

These render into the Genesis ConfigMap as environment variables.

| Key | Default | Description |
| - | - | - |
| `config.sqliteDbPath` | `/app/.genesis/db/genesis.db` | Path of the Genesis database inside the data volume. |
| `config.logLevel` | `INFO` | Log level: `DEBUG`, `INFO`, `WARNING` or `ERROR`. |
| `config.logsFormat` | `json` | Log line format: `json` or `text`. |
| `config.authEnabled` | `"true"` | Whether Genesis requires sign-in. Keep it `"true"` for any install people reach over a network. |
| `config.authProvider` | `proxy` | How users sign in. `proxy` trusts an authenticating proxy in front of Genesis, such as oauth2-proxy on the ingress. `auth0` or `oidc` signs users in with Auth0 or any other OIDC provider, such as Entra ID, Okta or Keycloak, configured with `AUTH_ISSUER`, `AUTH_AUDIENCE`, `AUTH_JWKS_URL` and `AUTH_CLIENT_ID` in `config.extraEnv`. `none`, with `authEnabled: "false"`, turns sign-in off. See your platform's install guide and [Additional Sign-In Options](https://docs.genesiscomputing.com/docs/Setup/Additional-Sign-In-Options.md). |
| `config.extraEnv` | `{}` | Any other environment variables for the Genesis container, as a map of name to value. Values are stored in a ConfigMap, so put credentials in `secrets.*` or a Secret instead. A `GENESIS__<SECTION>__<FIELD>` name pins that [configuration setting](https://docs.genesiscomputing.com/docs/Setup/Configuration-Reference.md) and locks it in Advanced Settings. An entry here replaces a value the chart puts in the same ConfigMap, such as the install identity or `GENESIS_PUBLIC_BASE_URL`. It does not replace variables the chart sets directly on the container (the `cliTerminal`, `codingSandbox` and `customCACerts` settings, `GENESIS_CONFIG_FILE`) or credentials from `secrets.*`. |

### Starting LLM provider and models

The chart chooses a starting LLM provider from the credentials you give it: Databricks when a
Databricks token or `config.databricksBaseUrl` is set, otherwise OpenAI (or Azure OpenAI when
`config.azureOpenaiEndpoint` is set) when an OpenAI key is set. These settings only seed the
provider: a provider chosen later in **Config > AI Providers** or in the Genesis config file wins.
For Anthropic, Bedrock, Vertex AI or a LiteLLM proxy, configure the provider in the
[Genesis config file](#genesis-config-file-rbac-and-role-mapping) instead.

| Key | Default | Description |
| - | - | - |
| `config.modelName` | `""` | Main and premier chat model for the chosen provider, for example `gpt-5.5` or `databricks-claude-opus-5-5`. |
| `config.fastModelName` | `""` | Fast model for quick operations. Defaults to `config.modelName`. |
| `config.harvesterModel` | `""` | Model used to extract metadata during harvesting. Optional. |
| `config.embeddingModel` | `""` | Embedding model. Used only with the Databricks provider; other providers ignore it. To choose another embedding provider, set `EMBEDDING_PROVIDER` and `EMBEDDING_MODEL` in `config.extraEnv`, or `embedding.active_provider` and `embedding.active_model` in the Genesis config file. |
| `config.maxTokens` | `""` | Maximum completion tokens. Empty uses the model's default. |
| `config.azureOpenaiEndpoint` | `""` | Azure OpenAI endpoint URL. Empty uses the OpenAI API directly. |
| `config.databricksBaseUrl` | `""` | Databricks model serving URL, for example `https://<workspace>.cloud.databricks.com/serving-endpoints`. |
| `config.databricksHost` | `""` | Databricks workspace URL, for example `https://<workspace>.cloud.databricks.com`, used for SDK sign-in. |

### Databricks SQL warehouse connection

Creates a Databricks database connection when Genesis starts. Its token comes from
`secrets.databricksDbPat` or `secrets.existingSecretDatabricksDbPat`.

| Key | Default | Description |
| - | - | - |
| `config.databricksDb.enabled` | `false` | Create the connection on startup. |
| `config.databricksDb.connectionId` | `databricks` | ID the connection is saved under. |
| `config.databricksDb.serverHostname` | `""` | Server hostname, for example `dbc-abc123.cloud.databricks.com`. |
| `config.databricksDb.httpPath` | `""` | SQL warehouse HTTP path, for example `/sql/1.0/warehouses/abc123def456`. |
| `config.databricksDb.description` | `Databricks SQL Warehouse` | Description shown for the connection. |
| `config.databricksDb.authType` | `pat` | `pat` uses the personal access token. `user_oauth` signs each user in with their own Databricks account. |

## Genesis config file, RBAC and role mapping

| Key | Default | Description |
| - | - | - |
| `genesisConfig.content` | `""` | Contents of a Genesis config file (YAML), loaded at startup. The recommended way to configure LLM providers, secret references and application settings as code. Pass it with `--set-file genesisConfig.content=genesis-config.yaml`. Every setting it accepts is in the [Configuration Reference](https://docs.genesiscomputing.com/docs/Setup/Configuration-Reference.md). |
| `genesisConfig.existingConfigMap` | `""` | Name of an existing ConfigMap holding the config file, instead of `genesisConfig.content`. The file must be under the key `genesis-config.yaml`. |
| `groupRoleMapping.content` | `""` | YAML map of identity provider group IDs (for example Entra ID group GUIDs) to Genesis roles. On each sign-in Genesis sets the user's roles from their groups. Pass it with `--set-file groupRoleMapping.content=group-role-mapping.yaml`. See [Users and Roles](https://docs.genesiscomputing.com/docs/Setup/Users-And-Roles.md). |
| `rbacSeedPolicy.content` | `""` | Custom roles and permissions to create on startup, in Casbin CSV form (`p, core_user, apps, view` and `g, core_user, viewer` lines). Pass it with `--set-file rbacSeedPolicy.content=rbac-policies.csv`. |

Precedence for a configuration setting, highest first: a `GENESIS__*` environment variable (for
example from `config.extraEnv`), then a value stored in Genesis (from the config file, the UI or
Advanced Settings), then a legacy environment variable the setting reads by default, then the
built-in default.

## Agent sandboxes

Lets agents run long-running jobs, shell commands and scripts in their own Kubernetes pods. When
enabled, the chart creates a sandbox namespace, the RBAC that lets Genesis manage pods in it, and
per-install bindings for the service account the Genesis pod runs as (`default` unless you set one; on EKS, create one so it can carry an IRSA role).

| Key | Default | Description |
| - | - | - |
| `sandbox.enabled` | `false` | Create the sandbox namespace and RBAC. Setting it back to `false` does not revoke access: the per-install bindings are kept. Run `cluster/scripts/cleanup-retained-rbac.sh <genesis-namespace>` to remove them. |
| `sandbox.namespace` | `genesis-sandbox` | Namespace for sandbox pods. Renaming it leaves the old namespace's bindings behind; run the cleanup script, then apply the release again. |
| `sandbox.defaultBackend` | `local` | Where sandboxes run by default: `local` (Docker), `eks`, `k8s`, `ecs_ec2`, `fargate` or `railway`. Use `eks` or `k8s` on Kubernetes. Applied only when `sandbox.enabled` is true, as a `GENESIS__SANDBOX__DEFAULT_BACKEND` override, so it cannot be changed in Advanced Settings while set. |
| `sandbox.createSharedResources` | `true` | Create the shared Namespace, Role and ClusterRole. Set `false` when another process manages them, for example several Genesis installs on one cluster. |
| `sandbox.podServiceAccount.create` | `false` | Create a separate service account for sandbox pods. Only takes effect when `sandbox.createSharedResources` is true. |
| `sandbox.podServiceAccount.name` | `genesis` | Name of the sandbox pods' service account. |
| `sandbox.podServiceAccount.annotations` | `{}` | Annotations for that service account, for example `eks.amazonaws.com/role-arn` so sandbox pods get AWS credentials. `helm.sh/resource-policy` is reserved and rejected. |

## In-pod coding agent workspaces

One workspace pod per user, running Claude Code, that the user attaches a terminal to.
`cliTerminal.enabled` is the single switch: it creates the cluster objects and turns the feature
on in Genesis.

> [!WARNING]
>
> Each active user's workspace reserves 500m CPU and 4Gi of memory (bursting to 8Gi), and every
> user who has ever attached keeps two 10Gi volumes that are never reclaimed automatically. At the
> default caps that is up to 12.5 CPU and 100Gi of memory reserved, and up to 1000Gi of disk, on
> top of Genesis's own request. Lower `cliTerminal.maxWorkspaces` to what your cluster can hold:
> if it cannot schedule a workspace, attaching fails.

| Key | Default | Description |
| - | - | - |
| `cliTerminal.enabled` | `false` | Create the workspace namespace, RBAC, quota and optional network policy, and enable the feature. While true, Advanced Settings cannot change `cli_terminal.enabled`, `.runtime` or `.k8s_namespace`. `false` creates nothing and leaves those settings alone. Turning it off does not stop running workspaces; drain them first with `cluster/scripts/drain-workspaces.sh <release>`. |
| `cliTerminal.createNamespace` | `true` | Create the workspace namespace. Set `false` when it already exists. The namespace is kept on uninstall because it holds users' saved work. |
| `cliTerminal.image` | `""` | Workspace image. Empty leaves the image to `config.extraEnv` or Advanced Settings; on Kubernetes it must be a fully qualified image name. With `ecr.enabled` it is resolved against `ecr.registry` and defaults to `genesis-sandbox-claude:latest`. |
| `cliTerminal.namespace` | `genesis-cli` | Namespace for workspace pods. Use one namespace per Genesis release. |
| `cliTerminal.maxWorkspaces` | `25` | Most workspaces that can exist at once. Sets both the namespace pod quota and Genesis's own cap. Raising the cap in Advanced Settings alone does not raise the quota, so raise it here. |
| `cliTerminal.maxLifetimeUsers` | `50` | Most distinct users who can ever have a workspace; the volume quota is twice this. Must be greater than `cliTerminal.maxWorkspaces`. Retiring a departed user's volumes is a manual step. |
| `cliTerminal.networkPolicy.enabled` | `false` | Limit workspace egress to DNS and the Genesis backend. Installing packages and cloning repositories then fails. Only effective if your CNI enforces NetworkPolicy; verify it does. |

`cliTerminal.quota` was replaced by `cliTerminal.maxWorkspaces` and
`cliTerminal.maxLifetimeUsers`. With `cliTerminal.enabled` true, a values file that still sets it
fails to render.

## Software Factory coding sandbox

Optional development tooling for Genesis Software Factory. Not needed for a standard install;
leave it off unless you are configuring Software Factory. One release owns one coding namespace.

| Key | Default | Description |
| - | - | - |
| `codingSandbox.enabled` | `false` | Create the coding namespace, quota and network policy, and configure the Kubernetes coding sandbox in Genesis. It does not change which backend Software Factory uses by default (`genesis_enhancements.coding_agent.backend`). |
| `codingSandbox.createNamespace` | `true` | Create the coding namespace. Set `false` to use one you manage. |
| `codingSandbox.namespace` | `genesis-coding` | Namespace for coding pods. |
| `codingSandbox.image` | `""` | Coding image, as a fully qualified tag or digest. Required when enabled. |
| `codingSandbox.imagePullSecrets` | `[]` | Pull secrets for the coding image. They must already exist in the coding namespace. |
| `codingSandbox.serviceAccount` | `""` | Service account for coding pods. |
| `codingSandbox.runtimeClass` | `""` | RuntimeClass for coding pods, for example a gVisor class. Empty uses `sandbox_runner.k8s_runtime_class`, then the cluster default. |
| `codingSandbox.storageClass` | `""` | StorageClass for coding volumes. Empty uses `sandbox_runner.k8s_storage_class`, then the cluster default. |
| `codingSandbox.storageSize` | `20Gi` | Size of each coding session's volume. |
| `codingSandbox.maxConcurrentRuns` | `1` | Coding runs at once. Fixed at 1: Genesis runs accepted coding runs one after another. |
| `codingSandbox.maxSessions` | `10` | Most coding sessions whose volumes are kept for follow-up work. Sets the volume quota; must be at least `maxConcurrentRuns`. |
| `codingSandbox.sessionRetentionSeconds` | `86400` | How long a finished session's volume is kept. |
| `codingSandbox.cpuRequest` | `"1"` | CPU request for a coding pod. |
| `codingSandbox.cpuLimit` | `"4"` | CPU limit for a coding pod. |
| `codingSandbox.memoryRequest` | `2Gi` | Memory request for a coding pod. |
| `codingSandbox.memoryLimit` | `8Gi` | Memory limit for a coding pod. |
| `codingSandbox.proxyBaseUrl` | `""` | LLM proxy URL coding pods call. Empty uses this release's own service. |
| `codingSandbox.mcpUrl` | `""` | MCP URL coding pods call. Empty uses this release's own service. |
| `codingSandbox.networkPolicy.enabled` | `true` | Limit coding pod egress to DNS, Genesis and TCP port 443. This is not a domain filter. |
| `codingSandbox.networkPolicy.extraEgress` | `[]` | Additional NetworkPolicy egress rules, for example for a private registry on another port. |

## Service account and scheduling

| Key | Default | Description |
| - | - | - |
| `serviceAccount.create` | `false` | Create a service account for the Genesis pod. Needed for IRSA on EKS, Workload Identity on GKE, and agent sandboxes. |
| `serviceAccount.name` | `""` | Service account name. Defaults to `genesis` when `create` is true. |
| `serviceAccount.annotations` | `{}` | Service account annotations, for example `eks.amazonaws.com/role-arn` (IRSA) or `iam.gke.io/gcp-service-account` (Workload Identity). `helm.sh/resource-policy` is reserved and rejected. |
| `priorityClass.create` | `false` | Create a PriorityClass so the Genesis pod is scheduled ahead of the sandbox and workspace pods it starts. Use it on a cluster dedicated to Genesis, not a shared one. |
| `priorityClass.name` | `""` | Name of the class. Set it with `create: false` to use a class your cluster already defines. |
| `priorityClass.value` | `1000000` | Priority of a class the chart creates. Far below the Kubernetes system tiers. |
| `priorityClass.preemptionPolicy` | `Never` | `Never` lets Genesis schedule first without evicting anything. `PreemptLowerPriority` lets it evict lower-priority pods, including other teams' workloads on a shared cluster. |
| `nodeSelector` | `{}` | Node selector for the Genesis pod. |
| `tolerations` | `[]` | Tolerations for the Genesis pod. |
| `affinity` | `{}` | Affinity rules for the Genesis pod. |
| `podAnnotations` | `{}` | Annotations added to the Genesis pod. |

## Resources and storage

| Key | Default | Description |
| - | - | - |
| `resources.requests.cpu` | `4000m` | CPU request for the Genesis container. |
| `resources.requests.memory` | `16Gi` | Memory request for the Genesis container. |
| `resources.limits` | `{}` | CPU and memory limits. None by default, so Genesis is not killed for exceeding a memory limit; set them if your cluster policy requires limits. |
| `persistence.storageClassName` | `""` | StorageClass for the data volume. Empty uses the cluster default. |
| `persistence.size` | `50Gi` | Size of the data volume, which holds the database, files and Git repositories. |
| `persistence.accessMode` | `ReadWriteOnce` | Access mode of the data volume. |

### Vertical Pod Autoscaler

Genesis runs as a single pod, so it cannot scale horizontally. A Vertical Pod Autoscaler can
right-size its requests instead. It needs the VPA controller installed in the cluster.

| Key | Default | Description |
| - | - | - |
| `vpa.enabled` | `false` | Create a VerticalPodAutoscaler for Genesis. |
| `vpa.updateMode` | `"Off"` | `Off` only recommends. `Initial` applies recommendations when the pod is next created. `Auto` restarts the pod to apply them, with a brief outage. |
| `vpa.controlledResources` | `[cpu, memory]` | Resources the VPA manages. |
| `vpa.minAllowed.cpu` | `500m` | Lowest CPU request the VPA may set. |
| `vpa.minAllowed.memory` | `2Gi` | Lowest memory request the VPA may set. |
| `vpa.maxAllowed.cpu` | `8000m` | Highest CPU request the VPA may set. |
| `vpa.maxAllowed.memory` | `32Gi` | Highest memory request the VPA may set. |

## Service and ingress

| Key | Default | Description |
| - | - | - |
| `service.type` | `ClusterIP` | Kubernetes Service type. |
| `service.ports.fastapi` | `8080` | Service port for the Genesis web UI and API. The container always listens on 8080. If you change this, change each `ingress.hosts` path `port` to match; the health Ingress follows it, and the probes are not affected. |
| `service.ports.flask` | `8082` | Port for the legacy integration server (UDF proxy and some OAuth callbacks). |
| `service.ports.streamlit` | `8501` | Port for the retired Streamlit UI. |
| `ingress.enabled` | `true` | Create an Ingress for Genesis. When enabled, the first host also becomes Genesis's public address (`GENESIS_PUBLIC_BASE_URL`), used for links, Slack and MCP, unless `config.extraEnv` sets it. |
| `ingress.className` | `""` | Ingress class, for example `nginx`, `alb`, `traefik` or `webapprouting.kubernetes.azure.com`. |
| `ingress.annotations` | `{}` | Annotations for your ingress controller. For nginx, raise `proxy-read-timeout` and `proxy-send-timeout` to `3600` for long-lived WebSocket and streaming connections, and `proxy-body-size` for file uploads. |
| `ingress.hosts` | `genesis.127.0.0.1.nip.io` | Hosts and paths. Each host has `host` and a list of `paths`, each with `path`, `pathType` and `port`. The default only works for local testing; set your own domain. |
| `ingress.tls` | `[]` | TLS settings: a list of `secretName` and `hosts`. A host listed here makes the public address `https://`. |
| `ingress.authExemptHealth.enabled` | `false` | With `ingress.enabled` also true, create a second Ingress named after the release with a `-health` suffix (for example `genesis-health`) that serves only the health paths below without the sign-in annotations. Use it when your ingress controller authenticates every request (nginx `auth-url`), so external health checks reach Genesis instead of a sign-in redirect. |
| `ingress.authExemptHealth.paths` | the health paths | Paths on that Ingress: `/api/health`, `/api/health/startup`, `/api/health/live` and `/api/healthcheck`, each with and without a trailing slash. Keep it to exact probe paths. |
| `ingress.authExemptHealth.pathType` | `Exact` | Path match type for those paths. |
| `ingress.authExemptHealth.port` | `""` | Service port for those paths. Defaults to `service.ports.fastapi`. |
| `ingress.authExemptHealth.annotations` | `{}` | Annotations for the health Ingress only. `ingress.annotations` is not copied to it. |

## Health probes and shutdown

Each probe takes the standard Kubernetes probe fields, so you can replace any of them.

| Key | Default | Description |
| - | - | - |
| `startupProbe.httpGet.path` | `/api/health` | Startup check. Holds the other probes until Genesis has finished starting. |
| `startupProbe.httpGet.port` | `8080` | Port for the startup check. |
| `startupProbe.periodSeconds` | `10` | Seconds between startup checks. |
| `startupProbe.timeoutSeconds` | `5` | Timeout of each startup check. |
| `startupProbe.failureThreshold` | `60` | Failed startup checks before the pod is restarted. With the period, Genesis gets 10 minutes to start. Raise it if a large install needs longer. |
| `livenessProbe.httpGet.path` | `/api/health/live` | Liveness check. Passes whenever the process is running. |
| `livenessProbe.httpGet.port` | `8080` | Port for the liveness check. |
| `livenessProbe.periodSeconds` | `30` | Seconds between liveness checks. |
| `livenessProbe.timeoutSeconds` | `5` | Timeout of each liveness check. |
| `livenessProbe.failureThreshold` | `7` | Failed liveness checks before a restart: at least 180 seconds, long enough for a state snapshot to hand over. |
| `readinessProbe.httpGet.path` | `/api/health` | Readiness check. Fails while Genesis is starting, so no traffic reaches it early. |
| `readinessProbe.httpGet.port` | `8080` | Port for the readiness check. |
| `readinessProbe.periodSeconds` | `10` | Seconds between readiness checks. |
| `readinessProbe.timeoutSeconds` | `5` | Timeout of each readiness check. |
| `readinessProbe.failureThreshold` | `3` | Failed readiness checks before traffic stops. |
| `podLifecycle.preStopSleepSeconds` | `30` | Seconds the container waits before it is told to stop, so the load balancer can drain connections. |
| `podLifecycle.terminationGracePeriodSeconds` | `90` | Total seconds allowed for shutdown before the container is killed. Must be greater than `preStopSleepSeconds`. |

## Restoring a state snapshot

Restores a state snapshot into the data volume before Genesis first starts: the way to move an
install from Snowflake, another cluster or a backup. See
[State Snapshots and Migration](https://docs.genesiscomputing.com/docs/deployments/State-Snapshots-And-Migration.md).

| Key | Default | Description |
| - | - | - |
| `restore.from` | `""` | Snapshot location: `s3://bucket/prefix/<instance>/<snapshot_id>`, `s3://bucket/prefix/<instance>` for its newest complete snapshot, or `gs://bucket/...`. Empty turns the restore off. A volume that already holds data is never overwritten. The snapshot must have been written with this release's master key, and the pod reads it with its own cloud identity. Needs an image newer than v1.19.93. |
| `restore.region` | `""` | AWS region of an `s3://` bucket. Not used for `gs://`. |
| `restore.resources` | `{}` | Resources for the restore init container, which downloads and checks the whole snapshot. |

## Corporate CA certificates

Fetches CA certificates from AWS Secrets Manager or Google Secret Manager when the pod starts and
adds them to the container's trust store, so Python, curl, Git and Node.js all trust them. The pod
needs IRSA or Workload Identity credentials.

| Key | Default | Description |
| - | - | - |
| `customCACerts.enabled` | `false` | Fetch and install the certificates. Rendering fails if it is true and `secrets` is empty. |
| `customCACerts.secrets` | `[]` | Certificates to fetch. Each entry has `ref`, an `aws_...`, `gcp_...` or full ARN reference, and `fileName`, for example `corporate-root-ca.crt`. |

## Extending the pod and the release

| Key | Default | Description |
| - | - | - |
| `extraContainers` | `[]` | Sidecar containers for the Genesis pod, for example a log shipper. |
| `extraInitContainers` | `[]` | Init containers that run before Genesis starts, for example to wait for a dependency. |
| `extraVolumes` | `[]` | Extra volumes for the Genesis pod. |
| `extraVolumeMounts` | `[]` | Mounts of those volumes in the Genesis container. |
| `extraManifests` | `[]` | Any other Kubernetes objects to install with the release, each a complete manifest: a PodDisruptionBudget, a NetworkPolicy or a PodMonitor, for example. |
