ee/apps/gateway, normally on port 8791.
It is not den-gateway, the separate OpenWork Web proxy, and it is not the OpenWork MCP gateway. OpenWork Models is still the managed model catalog and subscription product. Its billing, keys, and legacy API contracts are separate.
Two independent controls
Neither organization mode, a running legacy inference service, nor the presence of billing/provider credentials opts a deployment in. With
GATEWAY_ENABLED absent, the new capability is false and existing OpenWork Models behavior is preserved. Hosted operators explicitly set GATEWAY_ENABLED=true through their existing hosting environment mechanism on Den API and Gateway; hosted deployments are not assumed to use Helm.
The organization flag is dashboard exposure, not runtime authorization. Do not create another flag, put deployment capabilities in organization metadata, or use ordinary organization metadata updates to grant dashboard access. Management APIs still enforce organization-admin permissions and fresh authentication for privileged writes independently of dashboard exposure.
Prepare the deployment
- Select matching, immutable release image tags for Den API, Den Web, and Gateway. Remove or reconcile component-specific image tags that would override the shared
image.tag. - Initialize or migrate the database with a reviewed procedure, and verify the release schema before starting application traffic. A new empty database can use this release’s current-schema bootstrap; an existing database requires the upgrade procedure.
- Precreate the database/authentication Secret in the release namespace using your secret manager. Den API and Gateway must use the same database and the same existing
DEN_DB_ENCRYPTION_KEY; do not generate a new encryption key during an upgrade. - Configure the internal Gateway origin and a separate desktop-reachable Gateway origin, DNS, trusted certificates, and network access.
- Render and inspect the values, deploy the matching images, verify the authenticated contract, then request the organization dashboard grant.
Helm values
This fragment is for the Gateway-capable chart0.2.0 or later with the matching release images. Merge it with the normal Den deployment values. Replace the image tag and precreated Secret name with your approved references, not secret values.
openwork-ee-inference. Gateway continues to use the *-inference Deployment, Service, container name, selectors, and default ghcr.io/different-ai/openwork-inference image repository. No resource rename is required.
The chart does not create a Gateway ingress automatically. Provision its desktop-reachable HTTPS endpoint through your ingress, service mesh, or gateway.service load balancer configuration. Existing web/API ingress settings do not publish Gateway for you.
Database and encryption references
The default key names match the runtime variables. Key remapping is supported: set each
secret.keys entry to the corresponding data key in your precreated Secret. When explicitly enabled, Den API and Gateway receive required secretKeyRef entries; Helm cannot read or validate the contents of an existing Secret. Keep the normal Den authentication keys as well, including the key selected by secret.keys.betterAuthSecret.
The encryption key must contain at least 32 characters after trimming. MySQL mode requires a valid mysql:// URL with username, host, database name, and valid port. PlanetScale mode requires a valid database hostname and nonempty username/password. Production must not use loopback database hosts. Require verified database TLS and use custom CA support where needed.
Migration connectivity is separate from runtime mode. Whenever migrations.enabled: true, the chart always supplies the Job’s DATABASE_URL from the existing secret.keys.databaseUrl mapping, plus DEN_DB_ENCRYPTION_KEY from secret.keys.denDbEncryptionKey. This also applies with config.databaseMode: planetscale: runtime host/user/password credentials do not replace bootstrap’s TCP MySQL connection. The mapped key in the precreated Secret must contain a TCP mysql:// URL for the same database, including its database name, port, and approved TLS options. No new migration values are needed; the chart does not expose bootstrap’s alternative DATABASE_NAME/DATABASE_PORT configuration. Verify TCP reachability, TLS trust, and migration privileges separately. With migrations.enabled: false, the chart skips this migration-specific validation, but the external upgrade procedure still needs its reviewed migration connection.
Use secret.create: false for these examples. Chart-created Secrets use secret.values, and the current pre-install hook inlines their credentials into the Job. Do not place literal credentials in values, commands, documentation, or diagnostic output.
Internal and public origins
GATEWAY_PROXY_BASE_URLis the internal/service-to-service destination. Set it on Den API and Gateway. Internal HTTP is permitted across a trusted private boundary.GATEWAY_PUBLIC_BASE_URLis the desktop-reachable destination, not the internal Service address. Den API uses it in member Gateway provider configurations. Configure it on both services for shared startup validation.- Models clients retain an explicit, valid desktop origin from
INFERENCE_PROXY_BASE_URL; otherwise they use a validGATEWAY_PUBLIC_BASE_URL. This selection is independent ofGATEWAY_ENABLED: changing only management enablement does not replace a known public destination with the internal proxy. Preserve your existing Models HTTPS hostname, including for organizations without Gateway dashboard opt-in. No subscription, key, or upstream-routing changes are required. - Both must be explicit origins without credentials, non-root paths, queries, or fragments. A trailing
/is allowed. Do not append/api/v1to either value. - Production public origins require HTTPS and a non-local qualified hostname or valid non-loopback IP address. Private DNS is possible, but member devices must resolve it, route to it, and trust its certificate. Internal
.svcor.internalnames are not valid production public origins. - Helm validates production-style origins statically; startup validation does not check DNS, TLS, network reachability, or schema readiness. Local development exceptions require
OPENWORK_DEV_MODE=1and a non-productionNODE_ENV, not a production workaround.
config.internal.gatewayProxyBaseUrl wins over config.internal.inferenceProxyBaseUrl by presence. An explicitly empty canonical URL clears the legacy value and fails enabled-Gateway validation. If the canonical key is absent, an explicitly configured legacy URL can satisfy the internal requirement. The automatically generated legacy Service URL alone does not satisfy new opt-in. There is no inferred public fallback for enabled deployments.
Helm preserves nonempty config.internal.inferenceProxyBaseUrl in INFERENCE_PROXY_BASE_URL when a canonical proxy or public destination is configured, and uses the configured public Gateway origin when the legacy value is unset/empty. Despite its legacy internal name, keep the existing Models client endpoint in this setting. Shared public configuration is retained when management is disabled. Internal proxy resolution still follows canonical presence, including an explicit empty clear. With no usable public destination, disabled deployments retain historical Models fallback behavior; invalid optional Gateway settings do not add new startup requirements. That compatibility fallback can be private or loopback, so configure a valid public destination for desktop clients. A URL change does not repair previously stored client configurations automatically.
Canonical environment reference
These are native runtime variables, not values to inject indiscriminately through Helm per-appenv. Helm owns shared enablement, URLs, database references, ports, and optional tokens; conflicting per-app overrides are rejected. Den Web consumes the authenticated API capability, not a separate Web environment toggle.
Canonical alias precedence is based on whether the variable is set, including an empty string. Empty token values disable that credential; an empty egress allowlist removes inherited exceptions rather than merging them. Invalid or empty canonical numeric values fail startup instead of falling back. An empty canonical proxy URL fails validation when enabled; legacy disabled behavior is not a supported opt-in shortcut. Keep
OPENWORK_INFERENCE_BASE_URL, STRIPE_INFERENCE_PRICE_ID, and config.inference.* Models contracts unchanged.
The timeout names describe different handlers, not interchangeable products. In gateway.ts, /api/v1/providers/:inferenceProviderId/* uses env.upstreamTimeoutMs for the upstream lifetime, including response relay. In proxy.ts, the retained /api/v1/chat/completions API uses env.managedUpstreamTimeoutMs for managed OpenWork Models: response headers and non-streaming bodies have separate timers, while successful streaming uses env.streamIdleMs. The shared timeout override sets both timeout fields, but does not make their timing behavior identical.
Egress exceptions can permit private destinations or HTTP, so they require a security review of exact operator-owned origins. Do not use wildcards or confuse upstream egress exceptions with the internal/public Gateway URLs. Default egress checks reject private/reserved addresses and redirects.
Optional admin, webhook, and retention
Canonical Helm enablement does not implicitly enable admin or webhook credentials. To opt in, reference keys in the same precreated shared Secret:secret.keys.inferenceAdminToken and secret.keys.inferenceWebhookSecret by presence. Without canonical settings, the default Secret data keys remain INFERENCE_ADMIN_TOKEN and INFERENCE_WEBHOOK_SECRET. Disabled features explicitly clear both runtime token aliases, preventing envFrom from enabling them accidentally. Do not set token values in gateway.env or inference.env.
Enable retention only after verifying the accounting migrations and policy. It is a product maintenance CronJob, not a member Automation:
GATEWAY_ADMIN_TOKEN and INFERENCE_ADMIN_TOKEN on the Gateway and CronJob, even if the shared Secret has different tokens. It enables admin access without gateway.admin.enabled. The inherited schedule is 0 3 * * *, timezone Etc/UTC; the job calls the retained internal Service’s /internal/rollups/run. Service enablement is also required. Non-Helm deployments must supply their own authorized maintenance caller.
Sparse Helm compatibility
The defaultgateway: {} deliberately has no canonical defaults. An absent gateway root, including an older release upgraded with --reuse-values, is supported and treated as {}; an explicitly supplied non-map is rejected. The root empty map means no canonical overrides, not deletion of the legacy component. Legacy inference.* values still configure the component, but only explicit gateway.enabled: true opts in to capability version 1.
Structural settings such as image, replicas, service, env, probes, resources, pod metadata, and retention inherit from
inference.* unless the canonical key is present. Nonempty maps merge recursively; explicit {}, [], false, 0, and "" replace inherited values. These rules apply to the canonical-over-legacy merge after Helm coalesces values. For example, a new gateway.env: {} clears inherited inference.env, gateway.probes: {} removes inherited probes, and gateway.replicaCount: 0 scales down without clearing capability intent. Clearing required fields fails validation when the component is enabled.
An empty component image tag clears an inherited tag and falls back to shared image.tag, then Chart.appVersion. It does not select a compatible release for you.
Clearing saved canonical maps is different. Helm can refill an empty map before templates run: after saving gateway.env.SAVED, --reuse-values --set-json 'gateway.env={}' retains that entry. Earlier values files can refill nested maps too. To clear previously canonical entries, use --reset-values with a complete, reviewed values file that omits the old entries and explicitly includes the desired empty maps. Preserve all other deployment settings and Secret references. A final empty override file or --reset-then-reuse-values does not reliably discard saved maps. Inspect the resulting render; null is Helm’s deletion operator, not a supported chart clear value.
Grant dashboard access
After deployment verification, an allowlisted platform administrator opens Den/admin, selects the organization, and enables Gateway dashboard. The existing platform API is PUT /v1/admin/organizations/:organizationId/capabilities with this partial body:
Verify and troubleshoot
Sign in to Den as an organization admin, select the intended organization, and inspect its authenticatedGET /v1/org response using the browser’s Network panel or your approved authenticated API client. Check the Den API response, not a health endpoint, organization metadata field, or Web runtime-config response. The relevant top-level fields are:
true is unsupported and fails closed in the UI. Verify all API replicas serve the matching release; one response is not proof of a consistent rollout.
The deployment-unavailable UI message is exactly:
This feature is not part of your deployment system, please ask an instance admin to configure deploymentAn authenticated, authorized management API request on a disabled deployment returns HTTP
403, error gateway_not_enabled, and:
Gateway management is not enabled on this deployment. Ask your administrator to configure GATEWAY_ENABLED=true.Authentication, role, and fresh-session failures remain distinct. Member usable/connect/sign-in/revoke paths and OAuth callbacks are not governed by the dashboard flag or management gate.
/health proves process liveness. Gateway /ready executes select 1 to check database connectivity; it does not prove the Gateway schema or migrations exist. The capability response also does not prove schema health. Verify migration receipts and actual schema separately, then test an authorized provider path with approved non-sensitive data before reopening traffic.
For eligible hosted organization admins, OpenWork Models and Gateway coexist in navigation and the command palette when both deployment support and the organization dashboard grant are effective. The OpenWork Models page remains available directly without redirecting to Gateway. Gateway retains its deployment, organization-grant, and admin guards; loading temporarily defers access decisions. Existing single-org behavior still routes Models to custom providers. This coexistence does not change subscriptions, billing, Models keys, or provider data. See disable and recovery choices before turning anything off.