# OpenWork Deployment Strategy: Self-Hosted Kubernetes and Helm Guide

> Learn the OpenWork deployment strategy with our self-hosted Kubernetes and Helm guide. Deploy Den control plane for private networks and multi-tenant configurations.

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: how-to-guide
- Published: 2026-08-14

---

**OpenWork is deployed as a self-hosted, Kubernetes-based Den control plane that uses a Helm chart to support private-network, air-gapped, and single- or multi-tenant configurations.**

The `different-ai/openwork` repository delivers the OpenWork platform as a containerized control plane designed for Kubernetes clusters. The deployment strategy for OpenWork centers on the Helm chart documented in [`packaging/helm/openwork-ee/README.md`](https://github.com/different-ai/openwork/blob/main/packaging/helm/openwork-ee/README.md), which defines the required components, default configurations, and optional enterprise features. As described in [`dev/AGENTS.md`](https://github.com/different-ai/openwork/blob/main/dev/AGENTS.md), every deployment must account for three surfaces: the desktop application, the MCP gateway, and the Den control plane itself.

## Deployment Shapes and Network Patterns

OpenWork supports two primary network patterns that determine how the desktop client reaches the Den control plane and whether the cluster requires outbound internet access.

### Private-Network Deployment

A **private-network deployment** is the most common enterprise pattern. Laptops retain normal internet access while connecting over VPN to the private network where **Den API** and **Den Web** run. The desktop points to a single Den-Web URL—such as `https://openwork.example.internal`—which proxies both API and MCP traffic.

Key configuration knobs in [`packaging/helm/openwork-ee/README.md`](https://github.com/different-ai/openwork/blob/main/packaging/helm/openwork-ee/README.md) include setting `DEN_API_PUBLIC_URL` to the proxied API base, enabling `DEN_ALLOW_PRIVATE_MCP_URLS=1` for internal MCP servers, and choosing `config.tenancy.mode` as `single_org` or `multi_org`. Detailed desktop-to-Den reachability guidance is available in `dev/docs/start-here/private-network-deployment.mdx`. Use this shape when the organization needs internal protection for the control plane but still requires internet access for installers, model catalogs, and external providers.

### Air-Gapped Deployment

An **air-gapped deployment** runs fully isolated from the public internet. All external dependencies—including the Helm chart, container images, installer binaries, model catalogs, npm packages, and provider APIs—are mirrored into an internal registry or PVC. The deployment disables outbound internet calls such as password-breach screening.

To configure this shape, mirror the OCI chart from `ghcr.io` to an internal registry, set `imagePullSecrets` to that registry, enable `installerArtifacts.enabled=true` with an existing claim, and point `OPENCODE_MODELS_URL` to an internal mirror. You can also set `DEN_ALLOW_PRIVATE_MCP_URLS` and `customCa.enabled` as needed. The full isolation checklist is documented in `dev/docs/start-here/air-gapped-deployment.mdx`, and `dev/packaging/docker/Dockerfile.den-web` provides the image build context used when mirroring for offline installs. Choose this shape for highly regulated environments that require zero-internet-access for both the control plane and the installer.

## Tenancy, Observability, and Security Options

Beyond network topology, the Helm chart controls organizational boundaries, telemetry backends, and TLS trust.

### Single-Org vs. Multi-Org Tenancy

A Helm value determines whether the deployment hosts a single organization or operates as a multi-tenant cloud-style service. The chart defaults to **single-org** for private installations.

Set `config.tenancy.mode` to `single_org` or `multi_org` as required. For single-org mode, also configure `DEN_SINGLE_ORG_NAME`, `DEN_SINGLE_ORG_OWNER_EMAILS`, and `DEN_SINGLE_ORG_ALLOW_PUBLIC_SIGNUP`. Use **single-org** for on-prem installations where one customer owns the entire stack, and **multi-org** for SaaS-style deployments that must isolate separate organizations.

### Observability Backends and Custom CA Trust

Production deployments can stream telemetry to either **OpenTelemetry** (`otel`) or **Sentry**. Set `observability.backend` to the desired provider and supply `observability.otel.endpoint` or `observability.sentry.dsnSecret` accordingly.

For environments that use internal certificate authorities or TLS inspection, provide a private CA to the pods via `customCa.enabled`. Reference an existing Secret or ConfigMap with `customCa.existingSecret` or `customCa.existingConfigMap` so the deployment trusts internal MySQL TLS certificates or internal proxies.

## Step-by-Step Deployment Workflow

The installation workflow documented in [`packaging/helm/openwork-ee/README.md`](https://github.com/different-ai/openwork/blob/main/packaging/helm/openwork-ee/README.md) follows four phases: values preparation, chart installation, rollout verification, and desktop configuration.

### Prepare the Helm Values File

Create a [`values.prod.yaml`](https://github.com/different-ai/openwork/blob/main/values.prod.yaml) file that sets tenancy mode, external URLs, secret references, and optional features.

```yaml
config:
  tenancy:
    mode: "single_org"
    singleOrgName: "Acme"
    ownerEmails: "admin@acme.com"
  public:
    webOrigin: "https://openwork.acme.internal"
    apiOrigin: "https://openwork.acme.internal/api/den"
secret:
  create: false
  existingSecret: openwork-ee-secrets

```

This example pins the deployment to a single organization and references an externally managed secret instead of creating one via Helm.

### Install the Chart

Run `helm upgrade --install` with the prepared values file.

```bash
helm upgrade --install openwork-ee ./packaging/helm/openwork-ee \
  --namespace openwork \
  --create-namespace \
  -f values.prod.yaml

```

This command targets the `openwork` namespace and applies the custom values defined in the previous step.

### Verify the Kubernetes Rollout

Confirm that the three core deployments reach a ready state.

```bash
kubectl rollout status deployment/openwork-ee-den-api   --namespace openwork
kubectl rollout status deployment/openwork-ee-den-web   --namespace openwork
kubectl rollout status deployment/openwork-ee-inference --namespace openwork

```

You can also inspect running pods and environment variables directly.

```bash
kubectl get pods -n openwork
kubectl describe deployment/openwork-ee-den-api -n openwork | grep DEN_
kubectl describe deployment/openwork-ee-den-web -n openwork | grep DEN_

```

### Configure the Desktop Client

Point the OpenWork desktop application at the Den-Web URL, or at the combined API URL when running in single-origin mode. The desktop discovers the API and MCP endpoints automatically after the connection is established.

## Configuration Examples for Common Scenarios

The following values files illustrate complete configurations for two typical enterprise shapes.

### Private-Network, Single-Org Deployment

```yaml
config:
  tenancy:
    mode: "single_org"
    singleOrgName: "Acme Corp"
    ownerEmails: "admin@acme.com"
  public:
    webOrigin: "https://openwork.acme.internal"
    apiOrigin: "https://openwork.acme.internal/api/den"
    allowPrivateMcpUrls: "1"
secret:
  create: false
  existingSecret: openwork-secrets

```

This configuration enables internal MCP servers by setting `allowPrivateMcpUrls: "1"` and delegates secret management to an existing Kubernetes secret named `openwork-secrets`.

### Fully Air-Gapped Deployment

```yaml
config:
  tenancy:
    mode: "single_org"
    singleOrgName: "Acme"
    ownerEmails: "admin@acme.com"
  public:
    webOrigin: "https://openwork.acme.internal"
    apiOrigin: "https://openwork.acme.internal/api/den"
    installerReleaseTag: "v0.17.9"
    installerReleaseRepo: "myorg/openwork"
    installerArtifacts:
      enabled: true
      existingClaim: openwork-installer-pvc
customCa:
  enabled: true
  existingSecret: acme-ca-secret
secret:
  create: false
  existingSecret: openwork-secrets

```

In this air-gapped shape, the chart pulls installer artifacts from an internal PVC, references a custom CA for TLS trust, and avoids creating new secrets through Helm.

## Summary

- OpenWork is a **self-hosted, Kubernetes-based service** delivered through the Helm chart in [`packaging/helm/openwork-ee/README.md`](https://github.com/different-ai/openwork/blob/main/packaging/helm/openwork-ee/README.md).
- The two primary network patterns are **private-network** (internet + VPN) and **air-gapped** (zero external access).
- **Tenancy mode** is controlled by `config.tenancy.mode`, defaulting to `single_org` for private installations.
- Production telemetry is configurable for **OpenTelemetry** or **Sentry**, and internal CAs are supported via `customCa.enabled`.
- The standard workflow requires preparing a values file, installing the chart, verifying the rollout, and pointing the desktop client to the Den-Web URL.

## Frequently Asked Questions

### What is the core deployment method for OpenWork?

OpenWork is deployed as a self-hosted **Kubernetes** service using a Helm chart. The chart packages the Den API, Den Web, and inference components, and it is documented in [`packaging/helm/openwork-ee/README.md`](https://github.com/different-ai/openwork/blob/main/packaging/helm/openwork-ee/README.md) within the `different-ai/openwork` repository.

### How does air-gapped deployment work in OpenWork?

In an air-gapped deployment, administrators mirror all external dependencies—including container images, Helm charts, installer binaries, and model catalogs—into an internal registry or PVC. They then disable outbound internet calls and configure values such as `installerArtifacts.enabled=true` and `customCa.enabled=true` to run entirely inside the isolated network.

### Can OpenWork run in multi-tenant mode?

Yes. By setting `config.tenancy.mode` to `multi_org`, the Helm chart configures the control plane for a SaaS-style deployment that hosts multiple isolated organizations. The default value is `single_org`, which is recommended for standard on-premises installations owned by a single customer.

### How do you verify a successful OpenWork deployment?

After installing the Helm chart, run `kubectl rollout status` against the three core deployments: `openwork-ee-den-api`, `openwork-ee-den-web`, and `openwork-ee-inference`. You can also inspect pods and grep the `DEN_` environment variables in the Den API and Den Web deployments to confirm correct configuration.