OpenWork 开源桌面应用怎么在没有外网的环境活下来:三份文档合起来才是一套离网方案

2026-08-04

本文基于 openwork 仓库 commit 3b41381(2026-08-03)梳理,该项目仍在高频迭代,具体行为以仓库 https://github.com/different-ai/openwork 最新代码与文档为准。

如果你只记一句话:在 OpenWork 里,「断网」不是一个开关,而是一份逐项确认的依赖清单——出网清单告诉你要开哪些口子,离网部署清单告诉你不开这些口子要拿什么替代,企业出网说明告诉你这份清单归谁维护、改哪里才算数。三份文档任何一份单独拿去做方案,都会在某个环节卡死。

先说清楚本文说的是哪个 OpenWork:仓库地址 https://github.com/different-ai/openwork ,版权署名是 Different AI, Inc.。仓库 README 这样定位自己——一个用于共享 AI 工作流的免费开源桌面应用,把技能、MCP 与已连接的服务在多个工具、同事和机器之间复用;README 同时说桌面端并非必需,也可以只从你已经在用的 agent 里挂一个 OpenWork MCP 来调用,那个 MCP 对外暴露 search_capabilitiesexecute_capability 两个工具。README 另有一节介绍 OpenWork Den,称其为跨团队或组织管理 OpenWork 的控制面。本文讲的就是这个项目,它不是泛指的「开放工作」,也和某个同名的职场点评网站没有任何关系。

站内已经有几篇相邻的文章:Hermes Agent 的出口隔离讲的是常驻 Agent 进程本身怎么被关进出口白名单,AI 数据安全风险讲的是数据流出去之后的风险面,Pi 的容器隔离讲的是运行时沙箱边界。本篇不重复这些,只做一件事:把 OpenWork 这个具体项目的三份网络文档对照着读一遍,告诉你在企业内网里落地时哪一步会卡。

一、先把「离网」这三个字拆开

packages/docs/start-here/air-gapped-deployment.mdx 开篇干的第一件事,就是拒绝让你笼统地说一句「这套要做成 air-gapped」。它列了四个术语,含义严格区分:

  • Private-network / semi-air-gapped:员工桌面能上公网,同时能通过 VPN 或专网访问内部 Den。受限的是 Den 的访问范围,桌面端该走的公网路径一条没少,除非你的终端策略另外拦了。
  • Isolated Den:Den 没有不受限的公网访问,但客户端笔记本可能仍然能上网装安装包、拉模型目录、拉 npm 包、连模型供应商。
  • Fully air-gapped installer delivery:只有安装包字节是从你内网挂载或分发的。文档原文特意加粗说这等于整个 OpenWork 产品离网,它只去掉了安装包走 GitHub release 资产下载这一条路径。
  • Fully isolated OpenWork deployment:所有被启用功能用到的依赖,全部做了镜像、内部化、禁用或替换成内网可达的服务。范围包括部署产物、桌面运行时依赖、模型与供应商目录、OAuth 与供应商端点、MCP 服务器、邮件、诊断、桌面更新和信任锚。

这四个词的分层是整篇文章的地基。真实项目里最常见的翻车姿势,是安全部门批的是第四种,实施方按第三种做了,上线两周后发现桌面端在偷偷连 npm——这不是谁撒谎,是两边说的是同一个词的两个含义。

二、出网清单:最小可用的那 7 个域名

packages/docs/start-here/outbound-network-access.mdx 给了一个「实际可用的 OpenWork Cloud 桌面安装」最小允许列表,放行 TCP 443 到这几个主机:

app.openworklabs.com
api.openworklabs.com
github.com
release-assets.githubusercontent.com
objects.githubusercontent.com
registry.npmjs.org
models.openworklabs.com

这份清单本身不长,但文档紧接着列了「常见漏放」,每一条都值钱:

GitHub 的 release 下载会从 github.com 重定向走,所以要同时放行 release-assets.githubusercontent.com(当前已验证的 release 资产主机)和 objects.githubusercontent.com(保留给老客户端和回滚路径)。只放行 github.com 的后果不是下载失败,而是下载开始了、跑到一半断,这种故障在防火墙日志里最难对上号。

registry.npmjs.org 是打包后的桌面端启动 npx -y openwork-ui-mcp 时用的。挡掉之后桌面端照样能开,只是 UI 控制类 MCP 用不了——又一个「不报错、只是少了个功能」的坑。

models.openworklabs.com 是默认的 OpenCode 模型目录。公网目录被挡时,文档给的是把 OPENCODE_MODELS_URL 指向一个经批准的内部镜像,而不是让你忍着。

还有一条容易被过度紧张的团队误伤的信息:文档明确写了 code.claude.comschemas.agentskills.io 只出现在源码或 schema 元数据里,正常运行时 OpenWork 不去请求它们。也就是说,你在清单里搜到某个域名,不代表它会被真的访问。

三、要出的网出给谁、关掉会怎样

下表按仓库文档整理,位置列写的都是仓库里的真实路径:

要出的网出给谁关掉会怎样对应文档位置
app.openworklabs.com托管版 Cloud 的 Web 源站,桌面端从这一个 base URL 派生 /api/den/... 调用Cloud 登录、组织设置、市场、远程工作区流程全部加载不了packages/docs/start-here/outbound-network-access.mdx
api.openworklabs.com托管公共 API 与 OpenWork Connect 的 MCP 端点托管安装检查和公共 OpenWork Connect 失败同上
你自建的 Den Web 源站自托管桌面端登录后的全部流量,取代 app.openworklabs.com桌面端无法登录、无法访问 Denpackages/docs/start-here/private-network-deployment.mdx
github.com + 两个 githubusercontent.com 资产主机安装器与更新器的 release 下载、GitHub 插件源下载起不来,或起来了中途失败packages/docs/start-here/installer-delivery.mdx
registry.npmjs.orgnpx 解析 openwork-ui-mcpUI 控制 MCP 不可用,应用本身能开packages/docs/start-here/outbound-network-access.mdx
models.openworklabs.com默认 OpenCode 模型目录模型选择可能过期、不全或不可用同上
ghcr.ioHelm chart 与 openwork-den-apiopenwork-den-web、可选 openwork-inference 镜像Kubernetes 拉不到 chart 和镜像packages/docs/start-here/air-gapped-deployment.mdx
你的 MySQL 兼容数据库Den 控制面状态Den 起不来、迁移不了、用户登录不了、组织状态存不下packages/docs/start-here/outbound-network-access.mdx
api.github.comraw.githubusercontent.com按需启用的 GitHub 插件导入与同步插件导入无法检查仓库、下载清单/技能/命令/agent/MCP 配置同上
MCP 预设主机(如 mcp.notion.commcp.linear.appmcp.sentry.devmcp.stripe.commcp.context7.commcp.slack.com各自对应的内置 MCP 预设只有那一个预设连不上,其他不受影响同上
cdn.simpleicons.orgwww.google.comus.i.posthog.com图标、favicon 与新标签页、开启后的产品分析图标缺失、浏览器面板新标签页加载不出、分析静默丢弃同上

这里有个工程习惯值得学:文档说清了机器可读的权威来源docs/enterprise/outbound-access.json,CI 用 node scripts/check-outbound-access.mjs 守着它。而 docs/enterprise/outbound-access.md 这份「企业出网说明」全文只有十行,内容是一句维护者指针——新增主机、阻断后果、覆盖变量名、组件归属,一律先改 JSON;面向客户的措辞改发布页;不要在仓库里维护第二份完整的人读清单

一份人读页面、一份机器读清单、一份说明谁是权威的指针,加上 CI 校验。这个结构比清单本身更有参考价值——你自己团队的出网清单如果散在三个 Confluence 页面里,那它迟早会互相矛盾。

四、真要做全隔离,清单长这样

air-gapped-deployment.mdx 的全隔离清单分四块,我按落地顺序复述关键项:

部署产物。把 GHCR 上的 Helm chart 镜像到内部 OCI registry;把启用的镜像(openwork-den-apiopenwork-den-web,启用推理时还有 openwork-inference)镜像到内部 registry;然后把 Helm 的镜像仓库和 chart 安装路径都指向内部 registry。公网 ghcr.io 只在你不做镜像时才需要。

安装器产物。把标准 release 安装文件挂进 Den,用 OPENWORK_INSTALLER_ARTIFACTS_DIR 指向挂载路径;用 OPENWORK_INSTALLER_RELEASE_TAG 选定期望的标准文件名,文件名里的版本号是 tag 去掉开头的 vOPENWORK_INSTALLER_RELEASE_REPO 只管挂载产物不存在时的 GitHub 重定向路径,它不是内部制品库的覆盖开关。多副本部署时,同一个只读 PVC 要挂到每个 Den API 副本上——Den 是直接流式吐挂载文件的,不抓取、不缓存、不重新打包、不打 ZIP。

桌面运行时依赖OPENCODE_MODELS_URL 指向内部模型目录镜像(默认目录是 https://models.openworklabs.com/);给 npx 准备内部 npm registry 或镜像来提供 openwork-ui-mcp,文档诚实地说明目前没有为这个包单独提供 OpenWork 专用的 registry 覆盖项,请用运行账号的标准 npm 配置;桌面更新和 GitHub release 资产要禁用、镜像或纳入内部发布流程,并且不要假设有内建的更新器镜像设置,除非你在自己要发的那个桌面版本上验证过。

功能依赖与诊断。可选的供应商、MCP 服务器、OAuth 身份源和邮件服务,只要内网不可达就是不可用,没有中间态。私有根证书和代理配置要按信任面分别装(下一节细说)。另外有个细节挺见功力:Helm 默认已经关掉了外部的泄露密码查询,隔离自托管场景下要开需要安全团队批准那条外部接口路径。

这一节结尾有一句话,建议贴到你的实施方案首页:挂载安装器产物只解决安装包分发,它不会顺带镜像 npm、模型目录、供应商 API、GitHub 插件内容、OAuth 元数据、邮件投递、诊断、桌面更新和证书信任。每一个启用的功能都要当成一次独立的依赖评审。

五、边界与代价:断网之后失去什么

直接消失的:托管 Cloud 的登录、组织设置、市场和远程工作区;托管安装检查与公共 OpenWork Connect;未做内网化的 Google Workspace、GitHub 插件导入、各家 MCP 预设、外部邮件投递。这些不是「变慢」,是功能不存在。UI 控制 MCP 在没有 npm 来源时同样属于这一类。

只是退化的:模型目录不可达时,模型选择会变得陈旧、不完整或不可用,但应用能开;图标服务挡掉只是图标缺失;分析上报挡掉是静默丢弃;ollama.comopencode.aidiscord.gg 这类链接型主机挡掉只是链接打不开,核心行为不受影响。Den 的出网自检也是可选、需要管理员手动触发的,默认诊断源站是公网的 https://diagnostic.openworklabs.com,够不着不代表 Den 坏了——想要就把诊断应用部署到内网可达的源站,再配 DEN_DIAGNOSTICS_ORIGINDEN_DIAGNOSTICS_BEARER_TOKEN,诊断令牌要求是合成的、至少 24 个字符,别拿供应商或客户凭据顶上。

断网不等于安全,这几笔代价要记账

其一,证书信任面变宽了。certificate-trust-and-proxies.mdx 把 OpenWork 的信任面拆成四个:桌面应用 HTTPS(走 Electron 的 Chromium 网络栈和系统代理)、桌面派生的本地运行时与 sidecar、Den 容器与 Helm、严格 MySQL TLS。给其中一个装了私有根,另外三个不会自动跟着信任。文档里有条真机验证的记录:某台 Debian 上把私有 CA 装进 /etc/sslcurl 和带 --use-system-ca 的 Node 都认,裸 Node fetchUNABLE_TO_VERIFY_LEAF_SIGNATURE,Electron 的 net.fetchERR_CERT_AUTHORITY_INVALID,因为 Chromium 在那个镜像上走的是 NSS/用户信任库。你为了离网装进去的每一张企业根证书,都是一次实打实的信任面扩张。

其二,凭据落到了本地。桌面端每次启动会从它能读到的所有 OS 信任源(Node 的系统库、Windows 的 LocalMachine 与 CurrentUser 的 Root/CA 库、macOS 由管理员控制的 System 与 SystemRoot 钥匙串)拼一个增量的 system-ca-bundle.pem 放进用户数据目录,再用 NODE_EXTRA_CA_CERTS 传给子进程。如果用户或启动器自己设过 NODE_EXTRA_CA_CERTS,用户的值优先,OpenWork 不覆盖。这套机制很贴心,但它意味着用户数据目录里多了一份需要纳入基线管理的东西。

其三,把 MCP 拉进内网是一个信任决策,不是离网的必要条件。Den 在服务端抓 MCP URL,默认拦私有和保留地址做 SSRF 防护,症状是 MCP_URL_BLOCKED。要放开就得设 DEN_ALLOW_PRIVATE_MCP_URLS=1,而这直接关掉那层防护。文档的措辞很克制:只有在 Den 的网络位置可信、且有权添加 MCP 连接的人可信时才用。想把这条决策想透,可以配合MCP 的安全边界一起看。

其四,网络口子只是暴露面的一半,另一半是授权范围和数据流向,得在同一张表里一起过。这里按仓库里能查到的说:Den 是控制面,README 列的能力包括按成员和团队控制谁能用哪个模型供应商、设置桌面策略、限制本地模型访问、控制组织可用的应用版本,以及通过市场发布技能与插件再指派给组织、团队或具体某人;README 介绍管理界面时还写了连接可以配成共享的或按用户的。共享连接这一项要格外想清楚——它意味着一份凭据会被组织里多个人通过 agent 使用,而 installer-delivery.mdx 里写明连接授权是存在 MySQL 里的,也就是说这份状态落在你自己那台数据库上,Den 起不来、迁移不了、用户登录不了、组织状态存不下,全都挂在它身上。办公套件同理:出网文档把 Google Workspace 的主机列成 accounts.google.comoauth2.googleapis.comwww.googleapis.comgmail.googleapis.comchat.googleapis.com,并写明挡掉时失效的是 OAuth、profile、Calendar、Drive、Gmail、Chat——反过来读,一旦启用,这几个面就都进了授权范围,离网评审要看的不只是「这个域名放不放」,还有「放了之后谁能通过 agent 读到里面什么」。桌面端本身也一样,它装在员工机器上、能被组织策略管到,这件事在做终端基线时得当成一个受管软件来登记,而不是一个普通工具。

其五,许可证边界要单独确认,别一句「MIT 开源」带过。根目录 LICENSE 写的是分层授权:/ee 目录下的所有内容按 ee/LICENSE 授权(根 LICENSE 称其为 Fair Source License,而 ee/LICENSE 自身抬头是 Functional Source License, Version 1.1, MIT Future License,缩写 FSL-1.1-MIT);所有并入的第三方组件各随其原始许可证;其余部分才是 MIT(Copyright 2026 Different AI)。FSL 那份里写了「Permitted Purpose」排除竞争性使用,也写了自软件发布之日起两年后转为 MIT 的未来授权条款。而全仓 ee/apps/ 有 10 个、ee/packages/ 有 3 个,这不是边角料。你要拿它做内部部署还是对外提供服务,能不能商用,一律以许可证原文为准;本文不提供法律意见。

六、上手与避坑清单

只放行 github.com 而漏掉资产主机。为什么会踩:清单是人抄的,抄的时候觉得两个 githubusercontent.com 是「附属域名」。怎么避:把「下载开始了但中途失败」这个症状写进你的验收用例,两个资产主机一起放行,回滚路径要留 objects.githubusercontent.com

把「挂载安装器产物」当成全隔离。为什么会踩:OPENWORK_INSTALLER_ARTIFACTS_DIR 一配,安装体验立刻内网闭环,感觉大功告成。怎么避:拿全隔离清单四块逐项打勾,npm、模型目录、供应商 API、插件内容、OAuth、邮件、诊断、更新、证书信任,一项一项签字。

OPENWORK_INSTALLER_RELEASE_REPO 去指内部制品库。为什么会踩:名字看着像仓库地址覆盖。怎么避:记住它只管找不到挂载产物时的 GitHub 重定向路径,内网分发靠的是挂载目录。

多副本 Den 只在一个副本上挂了产物 PVC。为什么会踩:连接授权存在 MySQL 里,预览和接受落到不同副本都没事,于是容易以为副本之间没有本地状态差异。怎么避:安装器字节必须对每个副本同样可见,同一路径、同一个只读 PVC。

在应用内的环境变量编辑器里配代理。为什么会踩:界面上有地方填,就以为填了生效。怎么避:Den 的代理配置(Node 24.5 及以上用 NODE_USE_ENV_PROXY=1HTTPS_PROXYNO_PROXY)属于进程启动前的设置,在浏览器或应用内环境编辑器里设已经太晚。参考格式:

NODE_USE_ENV_PROXY=1
HTTPS_PROXY=http://proxy.example.internal:8080
NO_PROXY=localhost,127.0.0.1,.svc,.cluster.local,openwork-ee-den-api

同理,OPENWORK_AGENT_DIAGNOSTICS_TRUSTED_ORIGINS 也要在 OpenWork 启动前设在启动器、MDM 配置、服务包装器或 shell 环境里,因为应用内的环境存储会剥掉 OPENWORK_*OPENCODE_* 开头的键。

把「Cloud 目录诊断被跳过」当成部署坏了。为什么会踩:Settings → Debug 里明晃晃一条没观测到线上目录。怎么避:那条诊断默认只对受信源站发带凭据的探测,自托管源站不在默认信任列表里,跳过就是不发请求。文档明说 Cloud MCP 在真实对话里仍可工作,别把跳过当故障。那条诊断探的是托管的 openwork-cloud MCP 条目,校验它是否恰好暴露 search_capabilitiesexecute_capability 这两个工具;跳过之后,你在真实对话里让 agent 搜一次可用能力再执行一个允许执行的能力,等于人工把这次校验补上。想让它自己跑,就按前面那条把 OPENWORK_AGENT_DIAGNOSTICS_TRUSTED_ORIGINS 配上自托管源站——文档要求值是逗号分隔的裸源站(只含协议、主机和可选端口),除环回地址可用 http: 外必须是 https:

信任面装错地方。为什么会踩:装完根证书 curl 通了,就认为全通了。怎么避:桌面 Chromium、派生本地运行时、Den 容器、MySQL 严格 TLS 四个面分别验;Kubernetes 侧用 Helm 的 customCa,它把选定的 Secret 或 ConfigMap key 挂到 /etc/openwork/custom-ca/ca-bundle.pem 并为 den-apiden-web、启用的 inference 和迁移 Job 设 NODE_EXTRA_CA_CERTS;轮换 CA 需要重启工作负载,Node 才会重新读文件。

把 MySQL 的加密当成身份校验。为什么会踩:sslmode=require 里有个 require,读起来很硬。怎么避:sslaccept=accept 只保留 TLS 不校验链,只适合冒烟或过渡;sslmode=require 是加密,不要把它描述成证书身份校验;真正校验的是 sslmode=verify-casslmode=verify-fullsslaccept=strict,且要配对正确的 CA bundle。

没有现场证据就开始猜。为什么会踩:网络问题跨部门,谁都没有对方那侧的数据。怎么避:仓库带了 scripts/support/openwork-doctor.ps1,Windows PowerShell 5.1 兼容、免管理员、只读,检查 DNS、TCP 443、用 SslStream 看实时证书链、有 openssl 时看服务端证书、WinHTTP 与 .NET 代理设置、PowerShell/OS 版本和 NODE_EXTRA_CA_CERTS。它的判定词是可以直接抄进工单模板的:LIKELY TLS INTERCEPTIONLIKELY MISSING INTERMEDIATE OR UNTRUSTED ROOTMISSING INTERMEDIATE CONFIRMED BY OPENSSLLIKELY DNS ISSUEPROXY DETECTED

收束

回头看这三份文档的分工其实很清楚:outbound-network-access.mdx 回答「要开哪些口子、每个口子关掉的具体后果是什么」,air-gapped-deployment.mdx 回答「不开这些口子的话,每一项依赖拿什么替代」,docs/enterprise/outbound-access.md 回答「这份清单归谁维护、改哪里才算数」。少了第一份你不知道要批什么,少了第二份你批完了也跑不起来,少了第三份这份清单三个月后就会和代码对不上。

顺带说一句可迁移的经验:这套「人读页 + 机器读 JSON + CI 校验 + 维护者指针」的写法,本身就是给企业客户交付的一部分。你自己在做内部 Agent 平台时,出网清单值不值得配一个 check-*.mjs 让 CI 守着,答案大概是值得的。至于选型上先算清楚哪些依赖必须内网化,可以顺着AI 基础设施选型那条线继续往下想。

本篇属于一个把开源AI 工作流桌面应用 OpenWork逐层拆开讲的系列,整体地图见 OpenWork 是什么:把技能与 MCP 打包成能力的开源桌面应用;沿着这条线往下,还可以看 自建 OpenWork 这个开源桌面应用:容器与 Helm 两条路,先算清四笔账开源项目 OpenWork 怎么保质量:一条评测正路加一道只问安全的闸门

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。