安全模型
本文档说明 devkit-pi 当前安全边界。它不是形式化安全证明;当前 public API 与配置细节以 Configuration reference、Subagents reference、Agent definition reference、Web tools reference、Web tools error codes 和 LSP tools reference 为准。
默认策略
- 默认 readonly
- 默认
subagents.maxDepth = 1 - 子代理不继承
subagent工具 - 子代理只处理被委托的 task
- 子代理不应扩大任务范围
- LSP privileged actions 默认禁用
- 子代理只能使用
subagents.allowedLspActions中的 readonly LSP actions - LSP hook 仅在主代理进程注册,不在子代理进程注册
输出清理
结果中不应暴露:
- API key
- npm token
- Authorization header
- 环境变量值
- 完整 stack trace
- 完整系统 prompt
Web tools 安全边界
内置 web_search、fetch_content、get_search_content 保持 readonly。工具参数、返回结构和错误语义见 Web tools reference 与 Web tools error codes:
- 仅允许
http:/https: - 禁止
localhost、loopback、link-local、private IP - 禁止
file:等本地协议 - 设置请求 timeout
- 设置最大响应体大小与最大输出字符数
web_searchprovider endpoint 请求与其他 web URL 请求使用相同的私网拦截和 pinned-connection 流程- 不写项目文件;responseId storage 随 session lifecycle restore/clear,并受配置限制
DNS rebinding / TOCTOU 边界
URL 安全检查会在每个 fetch/download hop 前校验 protocol、hostname/IP、DNS 解析结果和 redirect 目标。除此之外,web/convert 的 URL 请求现已接入 connection-stage DNS pinning:会把已解析且已校验的地址集合绑定到请求 dispatcher 的实际连接 lookup 路径。
与仅做前置校验相比,这显著降低了 DNS rebinding / TOCTOU 窗口。redirect 仍使用 manual 模式处理,并且每一跳都会重新校验并重新 pin。
边界说明:
- 这是安全加固措施,不是覆盖所有网络层攻击的形式化证明。
- 不承诺防御所有上游 DNS 污染场景、恶意 CA 证书链或透明代理行为。
allowPrivateNetwork=true会放宽私网拦截,但请求仍走同一套 pinned-connection 流程。- pinned fetch helper 的内部调用方必须完整读取或显式取消 response body,以便关闭每次请求创建的 dispatcher;内置 web 与 convert 工具已在内部完成该处理。
当前 provider、Jina fallback、storage 和 URL 安全边界以 Web tools reference、Web providers reference 与 Configuration reference 为准。历史设计背景保存在 internal-docs/adr/0004-bundled-readonly-web-tools.md。
Convert content 安全边界
convert_content 可以通过已配置的 MarkItDown CLI provider 转换本地文件,或先安全下载远程 HTTP(S) 文件再转换。Public 行为以 Convert content 工具参考 和 配置参考 为准。
当前边界:
- 本地
path转换限制在工具执行上下文 active workspace(ctx.cwd)内。 - 远程
url转换只支持http:和https:。 - 默认通过
convertContent.allowPrivateNetwork=false阻止私网目标。 - 每个 redirect hop 都会使用相同 private-network policy 重新校验,并在 follow 前重新 pin。
- 下载受
convertContent.maxResponseBytes限制。 - 返回 Markdown 受
convertContent.maxContentChars限制。 - Provider 执行受
convertContent.timeoutMs和 shared external-command stdout/stderr hard limits 限制。 - 非零退出的 stderr 摘要进入用户可见错误或日志前会先 redaction。
- MarkItDown 是外部可选 CLI 依赖;devkit-pi 核心包不捆绑重型 PDF/Office/OCR/browser/Tika/Pandoc 转换栈。
- 已配置 CLI 通过 shared external-command 基础设施以结构化参数执行,不使用 shell interpolation。
Guards 边界
Guards 提供轻量 workflow reminders,不是安全 enforcement:
- Guards 只在主代理进程注册,不在子代理进程注册。
- 不阻止 tool calls,不改写 turn,也不强制触发后续 agent turn。
- 当 git、cwd context 或 UI 能力不可用时,git context、first-write 和 verification reminders 会静默降级。
- Guard notices 只是 soft guidance,不应视为权限模型、审计日志或策略引擎。
LSP 安全边界
LSP tool/action、hook 和 failure semantics 见 LSP tools reference。
Readonly-safe actions:
definition, references, hover, signature, symbols, diagnostics, workspace-diagnostics, serversPrivileged actions:
rename, codeAction, restartlsp.tool.allowMutatingActions 默认为 false。即使显式开启,子代理进程中仍禁止 privileged actions。
LSP hook 默认启用 agent_end 模式,仅对主代理进程中本轮修改过的文件自动诊断;可通过 lsp.hook.enabled: false 或 lsp.hook.mode: "disabled" 关闭。hook 输出会限制文件数量和最大字符数。
子代理 LSP 由 subagents namespace 控制:
{
"subagents": {
"allowLspTools": true,
"allowedLspActions": ["definition", "references", "hover", "signature", "symbols", "diagnostics", "workspace-diagnostics", "servers"]
}
}写入能力
Subagents 的 readonly/write 行为见 Subagents reference 与 Agent definition reference。子代理写能力默认关闭:
{
"subagents": {
"allowWrite": false
}
}可写自定义 subagents 目前属于实验性能力。默认且推荐的模式是 readonly。subagents.allowWrite=true 只表示放宽委派策略,不代表已经具备完整权限沙箱、审计日志、自动回滚机制或稳定的写入能力契约。仅建议在可信仓库中使用,并且必须人工 review 所有变更。
当前边界:
- 内置 agents 仍按 readonly-first 设计。
- 子代理的实际工具可用性取决于 child pi runtime、当前工具注册、执行环境和配置。
- 主代理进程注册
subagent和/toolkit;子代理进程不注册subagent,也不注册/toolkit。 - LSP privileged actions 在子代理中始终禁用。
- Web tools 可用于研究和读取信息。
- 文件写入、命令执行、修改项目等 write-like 行为不应被视为默认安全能力。
allowWrite=true只是放宽策略入口,不代表完整安全沙箱。
当前没有稳定的自动回滚保证。如果用户启用可写行为,应使用 Git 工作区、提交前 diff、人工 review 和测试命令兜底。
如后续要正式支持可写自定义 subagents,应单独进行 "Writable Subagents Safety Hardening",至少补充:权限模型、工具 allowlist/denylist、readonly 与 write-like action 分类、write action logging、modified files summary、before/after diff guidance、rollback recommendation、failure recovery notes、测试覆盖和 release note 中的 experimental/breaking 状态说明。