ADR 0005:管理后台在 Agent 上运行脚本

  • 状态:已接受
  • 日期:2026-11-02
  • 取代:AGENTS.md 中“不实现任意远程命令执行”的禁止条款(该条款在本 ADR 生效后改为受限脚本执行的约束)
  • 相关:ADR 0003 受限自更新、实施计划

背景

管理员需要在指定 Agent 所在主机上执行一段 shell 脚本,并在管理后台查看输出。现有 WebSSH 依赖远程服务器与凭据,Agent 本身无法执行命令。

决策

  1. Agent 通过 os/exec 在本机运行脚本,新增能力 agent_exec.v1,经能力协商宣告;不增加新的帧类型,复用 OpenStream 的 exec 协议与数据帧。
  2. 仅管理员可创建脚本执行会话;服务端与前端同时校验。
  3. 只有实际宣告 agent_exec.v1 的在线 Agent 才显示入口,依据是握手时的能力协商结果,而不是管理员手填的字段。
  4. 默认开启。agent.exec.enabled=false 时 Agent 不宣告能力、拒绝 exec 流;server.exec.enabled=false 时服务端拒绝创建会话。
  5. 脚本经数据帧传输,不出现在命令行参数或进程列表中。

威胁模型与控制

威胁 控制
非管理员执行 服务端 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 并重启,或升级到不包含该能力的版本。协议未改动已有帧,回滚不需要数据迁移。