在团队中运行 DeepSeek Harness
如何在团队中运行 DeepSeek Harness:权限预设、沙箱后端、遥测环境变量、共享配置层,以及一套插件审批策略。
DeepSeek Harness(dsh)没有提供多租户服务器模式或管理控制台——在团队里运行它,意味着运行多个各自独立的本地(或按人分配的云端)实例,每个实例都朝着一套共享策略去配置,而不是共用一套统一部署。本文覆盖值得在团队内统一的具体设置:网络暴露面、沙箱与权限默认值、遥测、配置分层,以及插件审批。
不要试图把它变成一个共享服务器
Web UI 明确拒绝 --host 0.0.0.0。dsh 官方文档对原因说得很直白:这是"出于安全考虑暂时有意不支持"——一个能被网络访问到的 Web UI,等同于把远程代码执行能力暴露给任何能连到它的人。社区尝试用端口转发或 socat 绕过这个限制,依然会在工作区加载和文件选择上碰到后续问题,所以没有干净的绕过方式,只有带着毛边的变通方案。
实际的含义是:dsh 是一个按人配置的本地工具,不是那种你搭一次、然后指给整个团队用的东西。团队里每个人都在自己的 127.0.0.1 上跑自己的实例。如果你确实需要中心化的多用户基础设施,更贴合的路径是 dsh 的 headless 模式或它的 SDK(TypeScript 和 Python),由你自己的服务层去驱动,而不是想办法把 Web UI 复用给多人用。
用机器级 patch 层统一配置
dsh 按固定顺序叠加配置层,其中和团队最相关的一层是 $DSH_HOME/cordis.patch.yml——这份 patch 文件适用于该机器上每一个 profile,而且在优先级上位于每个 profile 自己的 cordis.patch.yml 之上:
- 每个 bundle 自己的 patch,按 profile 的
dsh.profile.bundles里列出的顺序 - profile 自己的
cordis.patch.yml $DSH_HOME/cordis.patch.yml——机器级,所有 profile 共享- 命令行传入的任何
--patch <path>参数
团队可以提供一份标准的 cordis.patch.yml,让工程师自己放到各自机器的 $DSH_HOME 下——把统一的 MCP server 列表、禁用某个危险权限预设,或者组织范围内的默认值烘进去——而不需要去改每个 profile 各自的配置。因为一个 patch 会对匹配到的 id 整体覆盖 config 块,而不是深度合并,所以要把你的标准层具体覆盖了什么写清楚文档,免得工程师自己在 profile 层做的定制被替换而不是合并时感到意外。
有意识地设定权限默认值
dsh 的权限模型把一个沙箱模式和一个审批策略打包成一个有名字的预设。默认存在两档:
| 预设 | 沙箱模式 | 审批策略 |
|---|---|---|
workspace-write(新会话默认) | 写操作被限制在会话工作区和平台临时目录内;网络访问和进程可见性不受限制 | ask |
danger-full-access | 完全不沙箱化 | never(不弹任何提示) |
对团队来说,真正要做的决策是:danger-full-access 在你的标准配置里到底该不该可达,还是应该被限制在特定的、有意为之的场景里(比如一个用完即弃的 CI 容器)。你可以在这两个默认档之外定义额外的自定义预设(custom 这个名字本身被保留,得另起名字),这正是编码出一个组织专属"中间档"的机制——比如一个保留 ask 审批、但放宽了可写范围的预设。这些预设背后的沙箱后端在各平台上有什么差异,见我们的权限与沙箱指南。
让沙箱预期匹配你的平台组合
一个预设选中的沙箱模式,在不同操作系统上的强制方式不一样:
- Linux:bwrap 或 Landlock
- macOS:Seatbelt
- Windows:受限令牌 ACL 方案
- E2B:一种云沙箱后端,作为完全不在本机执行隔离的替代方案
较老的 Landlock 内核 ABI 版本和 Windows ACL 后端,只能做到"partial"(部分)强制力,而不是"full"(完全)——官方文档明确指出,沙箱子系统的使用方需要区分这两个等级。在一个 Linux/macOS/Windows 混部的团队里,这意味着同一个权限预设的名字,并不保证在每台机器上都有完全一致的实际强制效果。如果这个差距对你的威胁模型很重要,E2B 云沙箱后端值得评估——它能提供不依赖每位工程师本地操作系统的一致强制力。
要么有意打开遥测,要么明确关掉它
默认情况下,dsh 不会把任何会话数据上报到任何地方。三个环境变量控制这件事:
DSH_TELEMETRY_MODE=FULL # 或 FEEDBACK_ONLY
DSH_TELEMETRY_OTLP_URL=https://your-collector.example/v1/traces
DSH_TELEMETRY_DISABLED=1 # 硬性覆盖,优先级高于上面两个
FULL 会把每一个会话事件都以 OTLP/HTTP 日志的形式上报到你的 collector;FEEDBACK_ONLY 只在用户明确提交反馈时上报一段会话日志。DSH_TELEMETRY_DISABLED 会覆盖上面两者,且不能被另外两个变量重新启用——如果你的团队有排除任何数据传输的数据处理要求,应该显式设置它,而不是依赖默认的"未设置"状态。
私有发布内部插件
因为 dsh plugin add 只是 pnpm add 的一层薄封装,标准的 pnpm/npm registry 配置同样适用——团队可以通过一份 scoped 的 .npmrc,把安装指向一个私有 registry,像分发任何其他内部包一样分发内部插件,而这些插件完全不需要碰公共 npm registry,也不需要一个公开的 GitHub 仓库。这样能把打包成插件的专有工具、提示词或业务逻辑,完全挡在公开的 dsh-plugin GitHub 话题和任何 awesome 列表收录之外。
定一套插件审批策略
因为安装一个插件会在安装它的机器上执行其代码——如果是 GitHub 来源,构建期通过 allowBuilds 执行一次,之后每次 apply() 运行时再执行一次——团队与其"看着有用就装",不如定一套轻量、明确的策略。以我们的插件安全清单为基础,一个合理的基线是:
- 维护一份内部审核过的插件白名单(可以直接放在你上面说的共享私有 registry 里),而不是让每个工程师各自独立地重新评估同一个公开的 GitHub 插件。
- 对任何来自白名单之外来源安装的插件,要求锁定 commit(
github:owner/repo#<sha>),这样上游后续的一次推送就无法悄悄改变实际运行的代码。 - 默认把新的/实验性的插件试用放在一个用完即弃的 profile 里、用
workspace-write,而不是放在某人日常工作用的 profile 里。 - 把在一个未审查的包上放行
allowBuilds: true这件事,当作和任何"在公司机器上跑这段代码"的请求一样需要走审批的事,而不是随手点过去的提示。
FAQ
多个人能共用一个 dsh 实例吗?
没有任何官方支持的方式可以——Web UI 明确只能本机访问(127.0.0.1),也没有多租户或多用户模式。每个人要么在本地跑自己的实例,要么在你自己的云环境里跑一个按人分配的实例。
在不违反 0.0.0.0 限制的前提下,给 dsh Web UI 提供远程访问最安全的方式是什么?
让 dsh 继续绑定在 127.0.0.1 上,在它前面加一层你自己的、带鉴权的访问入口(VPN、SSH 隧道,或者带自己访问控制的反向代理),而不要直接想办法绕开这个限制——社区尝试用端口转发绕过时,依然会碰到工作区和文件选择器方面的错误。
组织范围的配置该放在哪里,才能让每个工程师自动拿到?
$DSH_HOME/cordis.patch.yml 是优先级最高、且依然适用于某台机器上每一个 profile 的层。它必须分别存在于每位工程师自己的机器上——没有从中心服务器统一推送的机制。
dsh 支持 SSO 或中心化的用户管理吗?
作为核心项目的一部分,没有任何这方面的文档说明——dsh 的模型是按机器、按 profile 的配置,而不是中心化的账号管理。模型 provider 的凭据是按机器通过 $DSH_HOME/.credentials.yaml 或环境变量来配置的。
我们该不该把所有人默认设成 danger-full-access,来减少审批带来的摩擦?
这是在拿安全性换便利,而且事后很难逆转——danger-full-access 会彻底移除沙箱化和审批提示,包括对插件自身代码可能执行的动作。可以考虑用一个保留 ask 审批、但放宽可写范围的自定义权限预设,而不是直接跳到完全不沙箱化。
下一步
在详细制定团队的插件审批策略之前,先读一遍插件安全清单。想更深入了解这里提到的沙箱后端和权限预设,见DeepSeek Harness 中的权限与沙箱。如果插件是从 GitHub 而不是私有 registry 安装的,从 GitHub 安装插件讲了你的策略需要考虑到的 allowBuilds 决策。