Skip to main content
This page lists settings to review before you run the Onyx Helm chart in production. Test each change in a staging environment before you enforce it.

Pin the Onyx version

The chart default is global.version: "latest". Set it to a release tag:
values.yaml
A floating latest tag is risky:
  • A new pod can pull a newer image than the pods that already run. This occurs on scale-up, node drain, or reschedule.
  • The API server runs database migrations when it starts. One new pod can change the schema under older pods.
  • A Helm rollback does not revert the database schema.
With a pinned tag, an upgrade occurs only when you change global.version. For release notes, see the Changelog.

Credentials

Every section under auth accepts existingSecret. The chart then reads from your Secret and does not create one.
Set the bundled service passwords before the first install. The bundled OpenSearch reads its admin password only when it first starts, so a later change does not rotate it.
Create a Secret, then point the chart at it:
values.yaml

External Secrets Operator

If you use External Secrets Operator, the chart can create one ExternalSecret. You must install the operator and a SecretStore or ClusterSecretStore first.
values.yaml
The upstream secret must contain every key that the auth.*.secretKeys maps expect.

Security contexts

These settings do not change the user, so they apply with the default root user:
values.yaml
Apply the same settings to the other components in the table.

Run as non-root

The backend image (onyx-backend) contains an onyx user with UID 1001, but the image does not select it. Without an override, the API server, Celery workers, bots, and MCP server run as root. To run as non-root, set the user in the pod and container security contexts:
values.yaml
Non-root is not the chart default. Test it before you enforce it:
  • customCACerts and api.runUpdateCaCertificates need root in the API server and Celery workers.
  • Volumes that you add must be writable by UID 1001.

Service accounts

Onyx pods use the default ServiceAccount of the namespace. To change this, set serviceAccount.create to true, or set serviceAccount.name.
  • With Craft, the API server and the Scheduled Task worker use their ServiceAccount token to manage sandbox pods. Keep serviceAccount.automount: true.
  • Without Craft, Onyx pods do not call the Kubernetes API. You can create a dedicated ServiceAccount without a token:
values.yaml
Code Interpreter has its own ServiceAccount. It needs its token to create executor pods.

Other defaults to keep

  • /metrics returns 401 until you set auth.metricsAuth. Do not set configMap.DISABLE_METRICS_AUTH on a network that users can reach.
  • The API docs (/docs, /openapi.json) are off. Do not set configMap.ENABLE_PUBLIC_DOCS unless you need them.

Network policies

The chart does not create NetworkPolicies for Onyx pods. It creates policies only for sandboxes:
  • Code Interpreter executor pods get a policy that denies all egress.
  • Craft sandbox pods can reach only DNS and the sandbox proxy.
The example below applies default deny to the Onyx namespace and then allows the traffic that Onyx needs.
This is an example, not a tested policy. Change it for your cluster before you apply it:
  • Your CNI must enforce NetworkPolicies.
  • Change namespace names, the ingress controller namespace, and the Kubernetes API address.
  • If you use external services, allow their ports (for example, 5432 and 6379).
  • The example does not cover Craft. Craft needs more rules.
Each allow policy excludes Code Interpreter executor pods with the component selector. NetworkPolicies add together, so an allow rule that selects executor pods gives user code network access.
onyx-network-policies.yaml
To find the Kubernetes API address, run kubectl get endpoints kubernetes -n default. Some clusters use port 6443. Policy 3 assumes an ingress controller in the ingress-nginx namespace. The bundled NGINX (nginx.enabled is true) runs in the Onyx namespace and receives traffic from the load balancer. In that case, change policy 3 to allow the load balancer or node addresses.