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

# Private network deployment

> Run OpenWork when laptops have internet and VPN access while Den stays inside a private network.

Most enterprise OpenWork installs are not fully air-gapped. The common shape is:

* Employee laptops have normal internet access and VPN access.
* Den web and Den API run inside the customer's private network.
* The desktop is configured with one customer Den URL over the VPN.

This page is for IT and platform teams approving those two network paths. For full isolation terminology and checklist items, see [Air-gapped deployment](/docs/start-here/air-gapped-deployment).

## What the desktop must reach

Point the desktop at one Den web origin. The signed-in desktop reads `${DEN_BASE_URL}/api/runtime-config` and uses its `denApiUrl` value as the source of truth for Den API and MCP traffic. Den Web returns `DEN_API_PUBLIC_URL` when it is configured; otherwise it derives the API origin as `api.${DEN_BASE_URL}`:

* API default: `https://api.<den-web-host>/v1/...`
* MCP default: `https://api.<den-web-host>/mcp/...`

Set `DEN_BASE_URL` to the Den web origin. `DEN_API_BASE` is the server-only URL Den Web uses to reach Den API, such as an in-cluster service URL; it is never advertised to browsers or desktops. If browsers, desktops, or external MCP clients require a separate externally reachable API origin, set `DEN_API_PUBLIC_URL`, for example `https://api.openwork.example.internal`. Use an origin without a path because the current web client normalizes this value to its origin.

If you publish a separate Den API origin, the one-time install-link exchange and external MCP clients must be able to reach that origin too.

External MCP clients such as Cursor, Claude Code, VS Code, ChatGPT, and OpenCode are separate from the desktop. They must reach the MCP endpoint you configure for them, usually `<DEN_API_PUBLIC_URL>/mcp/agent`. See [OpenWork Connect MCP](/docs/cloud/run-in-the-cloud/cloud-mcp) for the external-client flow.

Unless you mirror or replace public dependencies internally, laptops may also need outbound access for installers, release assets, npm packages used by `npx`, and the OpenCode model catalog. Keep that allowlist in [Outbound network access](/docs/start-here/outbound-network-access), and use [Installer delivery](/docs/start-here/installer-delivery) when installer downloads must stay inside Den.

## What Den must reach

The hard requirements are small:

* The MySQL-compatible database endpoint configured for Den.
* The OpenWork chart and images at deploy or image-pull time, unless you mirror the Helm chart and enabled images into an internal registry.

Everything else is feature-specific and can be blocked until that feature is approved: Google Workspace, Microsoft 365, GitHub plugin import, transactional email, model providers, MCP presets, custom MCP servers, and OAuth/token endpoints. Keep the customer IT hostname inventory in [Outbound network access](/docs/start-here/outbound-network-access).

If the private network uses TLS inspection, private roots, or an outbound proxy, configure the correct trust surface instead of setting browser-only values. See [Certificate trust and proxies](/docs/start-here/certificate-trust-and-proxies).

## Three surprises for operators

### Internal MCP servers are refused

**Symptom:** adding or testing an MCP server on a private address fails with `MCP_URL_BLOCKED` and the operator action says: "Use a public HTTPS MCP URL or change the deployment's private-network policy through security review."

**Why:** Den fetches MCP URLs server-side. By default, it blocks private and reserved addresses as SSRF protection for multi-tenant deployments.

**Fix:** set `DEN_ALLOW_PRIVATE_MCP_URLS=1` on Den, or the matching Helm public config value. This disables that SSRF protection, so use it only when Den's network position is trusted and the people allowed to add MCP connections are trusted.

### The Cloud MCP diagnostic is skipped

**Symptom:** `Settings → Debug` reports that the live cloud catalog was not observed, and the detail says the endpoint is outside the diagnostics trust policy.

**Why:** the diagnostic only sends a credentialed probe to trusted origins. By default, it trusts the hosted OpenWork origins, not your self-hosted Den origin.

**Fix:** trust your Den origin before OpenWork launches. This affects the diagnostic only; Cloud MCP itself can still work in real chats without this variable, so do not treat a skipped probe as proof that the deployment is broken. See [Network diagnostics](/docs/start-here/network-diagnostics) for exact syntax and launch-surface guidance.

### Den's outbound self-check points at a public host

**Symptom:** an admin-triggered Den outbound diagnostic cannot reach the default public diagnostic host from a VPN-isolated Den deployment.

**Why:** `DEN_DIAGNOSTICS_ORIGIN` defaults to the public OpenWork diagnostic service.

**Fix:** deploy the diagnostics app at an internally reachable supported runtime/origin, then point Den at it with `DEN_DIAGNOSTICS_ORIGIN` and `DEN_DIAGNOSTICS_BEARER_TOKEN`. Do not assume a generic Kubernetes package unless your deployment path has been validated. The check is optional and admin-triggered; it is not a background dependency for Den. See [Network diagnostics](/docs/start-here/network-diagnostics).

## Verification checklist

| Chain                                          | Success looks like                                                                                                                                                           | First place to look if it fails                                                                                                                                                                      |
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Installer activates against internal Den       | The Den install page opens over VPN, the installer download completes, and **Open OpenWork** shows the expected organization and server before changing local configuration. | If the app opens, use `Settings → Debug` to confirm the Den web and API endpoints. If it never opens, return to the Den install page and check [Installer delivery](/docs/start-here/installer-delivery). |
| Desktop signs in and reaches a ready workspace | The user signs in through the internal Den URL, sees the correct organization, and can open a ready workspace or start a chat.                                               | `Settings → Debug` for server endpoints, sign-in state, proxy, and TLS/certificate clues. Use [Network diagnostics](/docs/start-here/network-diagnostics) for desktop DNS/TLS/proxy evidence.             |
| Cloud MCP works in a real chat                 | In a chat, the agent can search available OpenWork capabilities and execute one that the user is allowed to run.                                                             | `Settings → Connect` for provider sign-in or admin setup. Use `Settings → Debug` to interpret diagnostics, especially a skipped catalog probe.                                                       |
