ADR 0005:管理后台在 Agent 上运行脚本
ADR 0005:管理后台在 Agent 上运行脚本
- 状态:已接受
- 日期:2026-11-02
- 取代:AGENTS.md 中“不实现任意远程命令执行”的禁止条款(该条款在本 ADR 生效后改为受限脚本执行的约束)
- 相关:ADR 0003 受限自更新、实施计划
背景
管理员需要在指定 Agent 所在主机上执行一段 shell 脚本,并在管理后台查看输出。现有 WebSSH 依赖远程服务器与凭据,Agent 本身无法执行命令。
决策
- Agent 通过
os/exec在本机运行脚本,新增能力agent_exec.v1,经能力协商宣告;不增加新的帧类型,复用OpenStream的exec协议与数据帧。 - 仅管理员可创建脚本执行会话;服务端与前端同时校验。
- 只有实际宣告
agent_exec.v1的在线 Agent 才显示入口,依据是握手时的能力协商结果,而不是管理员手填的字段。 - 默认开启。
agent.exec.enabled=false时 Agent 不宣告能力、拒绝 exec 流;server.exec.enabled=false时服务端拒绝创建会话。 - 脚本经数据帧传输,不出现在命令行参数或进程列表中。
威胁模型与控制
| 威胁 | 控制 |
|---|---|
| 非管理员执行 | 服务端 isAdmin 校验,前端隐藏入口 |
| 令牌或管理员账号被盗 | 仍然是全部在线 Agent 的代码执行,这是本决策的主要残余风险;通过审计、短会话和可关闭开关缩小影响 |
| 脚本窃取 Agent 凭据 | 子进程不继承 Agent 环境变量;Agent 令牌不写入子进程环境 |
| 失控脚本占满资源 | 超时终止整个进程组;输出上限;并发上限;脚本大小上限 |
| 票据重放 | 一次性票据,30 秒有效,只存哈希 |
| 无法追溯 | 开始与结束双审计;记录脚本 SHA-256 与长度;默认不记录正文与输出 |
| 跨站调用 | WebSocket 校验 Origin |
备选方案
- 通过 SSH exec 在目标主机执行:不改 Agent,但依赖目标主机的 sshd 与凭据,且无法覆盖没有 SSH 的 Agent 主机。
- 仅允许预定义命令白名单:安全性更高,但不满足通用脚本需求,故本次不采用;它可以作为后续的收紧选项。
已知限制(实现时确认)
- Windows 不终止子进程:超时只结束 shell 进程,其子进程保留。在 Windows 上默认开启前,需要以 Job Object 实现进程树终止;在此之前应在文档中如实说明(已写入配置说明)。
- 票据只在签发节点有效:票据保存在内存中。多节点部署下,签发与连接必须落到同一 Server 节点;跨节点的票据共享需要持久化,留待后续。
- 列表按钮只看本节点会话:
execCapable依据本节点在线会话计算。Agent 连接在其他节点时,按钮不显示,接口也会拒绝,直到连接回到本节点。 - 审计不含正文:只有脚本 SHA-256、长度、退出码和耗时。复盘脚本内容需要另行设计受控存储。
- Agent 可执行的内容取决于其系统账户:systemd 的沙箱加固会限制脚本能做的事,但不能替代对账户权限的最小化配置。
影响
- 推翻 AGENTS.md 原有的禁止条款。
- 默认开启意味着升级后的 Agent 默认具备该能力。已在文档与配置中明示关闭方式。
- 审计只保存摘要,事后无法查看脚本正文;如需复盘,应另行设计受控存储。
回滚
设置 agent.exec.enabled=false 与 server.exec.enabled=false 并重启,或升级到不包含该能力的版本。协议未改动已有帧,回滚不需要数据迁移。