Skip to content

Security: KongFangXun/sofagent

Security

SECURITY.md

安全策略

v1.4.4 · 2026-09-03(UTC)· 孔放勋

按安全主题组织,企业 IT 可按主题快速定位。各能力的引入版本在小节正文首句注明。

目录


已知风险(明文存储)

sofagent 是一套 FDE 能力——底层引擎是纯本地 Harness 中间件(约束中间层),数据不出本机(除安装时 npm 拉包外运行时不联网;例外:用户主动配置云同步时数据会离开本机,见 多设备同步指南——该配置等于将 knowledge/ 与 think.md 托管给云盘服务商,属用户自主取舍,与本地数据主权承诺互斥)——但以下数据以明文 Markdown 存储,请评估风险:

🏠 当前定位:单机单用户——sofagent 当前为单机单用户设计,多 Agent 共享同一知识库/审计历史;多人/多部门共用需等租户隔离(ROADMAP v1.4.7 G7 多租户抽象层 v0)。企业 IT 若规划多人共用同一 ~/.sofagent/,部署前务必评估此边界(详见 LIMITATIONS「知识库同样全局共享」)。

安装后数据目录结构~/.sofagent/):

~/.sofagent/
├── data/          ← 用户可见运行时数据(审计/知识库/反思/任务日志)
├── internal/      ← 引擎内部状态(checkpoint / .git-shadow / watch.yml)
├── keys/          ← 静态加密密钥(0600,v1.3.8 能力 · 激活排期 v1.4.7)
├── bin/           ← CLI 入口
└── skill/         ← Skill 文件
文件 位置 可能含
task/logs/ data/task/logs/YYYY-MM/YYYY-MM-DD.md 任务摘要、代码片段、API 响应摘要、对话摘要
think.md data/think.md 反思记录,可能含踩坑细节、失败模式、决策推理
knowledge/ data/knowledge/ 知识库 / 评估反馈(eval 体系;旧 scoring/ 已废弃)
orchestrator/ data/orchestrator/ 编排决策历史

当前状态

  • ✅ 脱敏:sanitize() 管道扫描 API Key / 密码 / 手机号,写入前自动打码
  • ✅ 数据保留:cleanup.sh 支持 --purge --before 定时清理 + tar.gz 归档
  • ✅ 审计日志:task-record.sh 独立审计日志 + task/logs 追溯双通道
  • ⏳ 静态加密(能力已实现,接线未启用):加密能力已在 crypto-init.ts 实现(纯 TS AES-256-GCM,SOFAGENT-AGE-V1 格式,密钥设计存 ~/.sofagent/keys/ 0600 + 指纹强制备份),但激活入口 initDataEncryption() 尚未接入 daemon 启动路径——当前审计历史落盘为明文 JSONL(脱敏管道仍生效,见 enterprise-deploy.md)。接线排期 v1.4.7(见 ROADMAP
  • ⚠️ 当前限制:LLM 自评无外部基准。GDPR / 等保 / SOC2 场景仍需额外措施(静态加密接线未启用——审计历史主链与 forge-runs/checkpoint/model-registry 三目录当前均为明文,全量接线已移排 v1.4.7)。合规审查员请注意:当前版本强合规场景仍建议配合外部加密卷(gpg / disk encryption)

纵深防御(静态加密之外的额外措施,持续建议)

在静态加密(当前未启用,见上方 ⏳ 项)之外,仍建议:

  1. 设置 ~/.sofagent/data/ 目录权限为 700chmod 700 ~/.sofagent/data/(用户可见运行时数据;~/.sofagent/internal/ 引擎内部状态同样 700)
  2. ~/.sofagent/ 父目录放在加密文件系统上(如 macOS APFS 加密卷)
  3. 定期轮换 ~/.sofagent/data/ 中的历史审计数据

📌 config.yml 的权限加固(chmod 400)见 LIMITATIONS.md "config.yml 可被篡改"段。

企业环境建议

  • data/ 目录做 gpg 加密或放在加密卷上
  • 脱敏/保留/审计能力已落地,详见 企业部署指南

一、传输安全

联邦查询四层防线

引入版本:v1.1.8。

做什么 谁负责 被攻破的后果 攻击者需要
1 MCP server 只绑 localhost sofagent 无法从网络直接访问 MCP 先攻破本机
2 OpenClaw channel 路由 OpenClaw 无法接入联邦 channel OpenClaw device token
3 AES-256-GCM 加密 payload(core/src/crypto/aes-gcm.ts sofagent channel 被窃听但内容不可读 256-bit 密钥(2^256 暴力不可行)
4 sensitivity frontmatter 过滤(联邦链路:peer 端 + 本地端双重校验) sofagent 联邦查询中 restricted entity 不可读 伪造设备 identity + 突破加密

⚠️ sensitivity 的作用域边界:上表第 4 层的 sensitivity 过滤只作用于联邦链路本地注入链当前无 sensitivity 门禁——sensitivity 是可见性分级(knowledge status 聚合时 restricted 只计数不返回内容),不是访问门禁;Agent 直接读 knowledge/ 文件时无 sensitivity 拦截(同机多 Agent 数据隔离见 LIMITATIONS「知识库同样全局共享」段)。

🔴 OpenClaw channel 审计结论(v1.1.8 开发前置核实):OpenClaw 本地回环 ws:// 明文传输、无 TLS——第 3 层 sofagent 应用加密是唯一保密防线。因此 federation channel 只搬运密文帧(iv‖tag‖ciphertext),绝不触碰明文 payload;即使 channel 被中间人劫持,内容仍不可读(纵深防御原则,不依赖 channel 自身安全性)。

配对与密钥管理

引入版本:v1.1.8。

语义
三条配对路径 A:6 位码 + 公钥指纹 y/N 人工确认(防中间人)· B:~/.sofagent/federation.token 文件带外交换(权限 600,v1.2.3 起,原环境变量方式已废弃)+ token-HMAC 公钥认证(CI/无人值守)· C:复用 v1.1.5 federation.json + HMAC .sig sidecar 验签(timingSafeEqual 恒定时间比较,缺失/篡改拒绝)
key 存储 ECDH(prime256v1) + HKDF-SHA256 派生的 32 字节 AES key 只存内存,不落盘明文;持久化(OS keychain / age)留 v1.1.9
IV/nonce 管理 每条消息随机 12 字节 IV,绝不复用;GCM 16 字节认证标签校验失败即拒绝
密钥轮换 24h 过渡窗口内旧 key 只解不加,过窗口销毁强制重新协商

🔴 SOFAGENT_FEDERATION_TOKEN 进程可见(高危)— ✅ 已修复 v1.2.3

风险(已修复):联邦配对使用的 SOFAGENT_FEDERATION_TOKEN 曾通过环境变量传递, 在进程列表(ps e/proc/*/environ)中明文可见。

修复:v1.2.3 已将 token 从环境变量迁移至 ~/.sofagent/federation.token 文件读取(权限 600),

v1.2.8 轮换提醒:联邦 token 建议 90 天轮换一次。--doctor 不自动检查 token 年龄。手动检查:

# 查看 token 文件创建/修改时间
stat -f '%Sm' ~/.sofagent/federation.token 2>/dev/null || stat -c '%y' ~/.sofagent/federation.token 2>/dev/null
# 如超过 90 天,重新执行联邦配对流程生成新 token

不再在进程列表中暴露。详见 engine/core/src/crypto/pairing.tsreadTokenFromFile()

影响范围:v1.1.0 - v1.2.2(已修复于 v1.2.3)

⚠️ HMAC key 分发安全:路径 C 的 HMAC 签名密钥如与 federation.json 同放在 USB 等可移动介质上,攻击者获取介质即可伪造 .sig 文件。建议 HMAC key 通过独立渠道(如密码管理器 / 加密邮件)分发,不与 federation.json 同介质存储。

USB federation 安全模型

引入版本:v1.1.4。

⚠️ 企业环境警告:v1.1.4 的 USB federation 曾是基础检测模式无签名校验自 v1.1.5 起已加入 HMAC 签名校验

维度 v1.1.4(基础检测,无签名) v1.1.5+(HMAC 签名,当前)
检测条件 USB 卷标 = SOFAGENT + 存在 federation.json 同左 + HMAC 签名校验(.sig sidecar)
配置应用 写入 ~/.sofagent/federation.json不自动分发到各目录(applyFederation 未实现) 自动 nodes → orchestrator/nodes/、policies → audit/policies/(✅ v1.1.5 已落地,applyFederation()
注入风险 🔴 任何人制作的 SOFAGENT 卷标 U 盘可注入任意 federation 配置 ✅ 签名不匹配则拒绝导入
Schema 校验 ❌ JSON.parse 后直接序列化写入,不校验字段 ✅ 按 FederationConfig schema 校验(✅ v1.1.5 已落地,validateFederationSchema()

企业部署建议

  • 不要在共享/公共设备上启用 USB federation 自动检测
  • 如需使用,插入 U 盘前先在隔离设备上检查 federation.json 内容
  • 生产环境等 v1.1.5 的签名校验上线后再启用

detectSofagentUsb() 源码见 engine/daemon/src/usb-detect.ts,错误处理完善(设备不存在/文件不存在/JSON 解析失败都 try-catch 返回明确错误)。内容安全校验自 v1.1.5 起由 HMAC 签名校验覆盖(.sig sidecar + timingSafeEqual),v1.1.9 升级为全量签名(usb-signature.ts:HMAC-SHA256 路径 POSIX 归一化 + 字典序 + SHA-256 内容哈希串联,详见上方「USB 完整运行时攻防表」)。

摘要推送安全

引入版本:v1.1.8。

通过 openclaw:im 推送的知识摘要不含 restricted 内容(sensitivity 双重过滤),但 internal 内容可能含项目内部信息。openclaw:im 通道的安全性由 OpenClaw 保证(本地回环 ws://,摘要内容不含结构化密钥格式,redactForPrompt 管道同样适用于通知内容)。

USB 完整运行时攻防表

引入版本:v1.1.9。

「Node 便携版 + 启动脚本」方案——IT 用 sofagent-daemon create-usb-key 写入 U 盘(Node 便携版 + sofagent dist + 三平台启动脚本 + federation.json + 空 knowledge/),员工双击 start 3 秒联邦在线,拔盘零残留。两道防线:HMAC-SHA256 全量签名防篡改daemon/src/usb-signature.ts,路径 POSIX 归一化 + 字典序 + 内容哈希串联,不含 mtime,确定性可复算)+ knowledge/ AES-256-GCM 磁盘加密防失窃(复用 v1.1.8 core/crypto/aes-gcm.ts,密钥 32 字节存 U 盘 federation.jsonkey 字段——U 盘本身即信任根,防的是「丢盘后 knowledge/ 被读」)。

攻击场景 防线 结果
偷 U 盘插自己电脑看文件 knowledge/ 全盘 AES-256-GCM 密文(knowledge/*.enc,iv‖tag‖ciphertext 帧);明文只在 daemon 内存 Map<string, Buffer>,退出 Buffer.fill(0) 清零 无密钥不可读;文件系统上永远只有密文
删掉 federation.json 试图重置身份 HMAC 全量签名:federation.json 在受保护文件清单内,删除即签名不匹配 daemon 验签失败 → 写 security-events.jsonlprocess.exit(1)(fail-closed 拒绝启动)
往 U 盘拖入恶意文件 verifyUsbSignature() 双向校验:签名内文件被改/被删 → mismatch;签名外新增文件 → file-added 验签失败拒绝启动并记录安全事件
整盘格式化重写 .sofagent-signature 签名文件随盘消失 → signature-missing daemon 检测不到签名 → fail-closed 拒绝启动

⚠️ 密钥模型边界(U2 决策):AES key 明文存 U 盘 federation.json——拿到 U 盘的人可读出 key 再解密 knowledge/。「拿到盘也解不开」需 PBKDF2/Argon2 密码派生(启动时输入密码),与「双击 start 3 秒联邦在线」体验冲突,v1.1.9 保持简单模型,v1.2.x 再评估密码保护。

⚠️ 签名排除项runtime/(Node 便携版二进制,各平台不同)不纳入 HMAC 签名——被替换的 runtime 二进制在签名保护之外,企业 IT 应通过官方渠道制作 U 盘并核对 Node 版本。.sofagent-signature 自身亦排除。

⚠️ HMAC 密钥双轨制(U3 决策):本机场景复用 ~/.sofagent/usb-secret.key;U 盘运行时从 U 盘 federation.jsonhmacKey 字段读取(便携化要求)。两个密钥源按 startUsbRuntime vs 本机 daemon 场景切换,v1.2.x 再评估统一。


二、知识安全

sensitivity 敏感度分级

引入版本:v1.1.7。

core/memory-contract.ts 定义 Sensitivity(public/internal/restricted),DEFAULT_SENSITIVITY='internal' 为 safe-by-default,restricted 绝不默认。语义是可见性分级而非加密——restricted 内容在 knowledge status 聚合时只计数不返回内容,但明文存储不变。

trust 可信分级

引入版本:v1.1.8。

core/src/security/trust-grading.tsresolveTrust 缺省 internal;TRUST_ORDER official>internal>user>web;web+restricted 组合直接丢弃;RAG 召回 sortByTrust。

Dream Cycle LLM 安全边界

引入版本:v1.1.7。

6 阶段流水线经 LLMProvider 接口抽象;v1.1.7 默认使用 MockLLM(确定性、无外部调用),RealLLM 在 v1.1.8 才接入。LLM 仅读取 think.md/知识库内容并产出结构化事实/概念,不回写代码、不执行命令、不访问网络。注入隔离见 daemon/src/dream-cycle/ 的 system-role 声明与返回 schema 校验。

知识摘要主动通知

引入版本:v1.1.8。

素材仅 log.md + health-report.md(restricted 在生产侧已被 sensitivity 过滤,不进通知);通道复用 push-target(daemon:notice + openclaw:im outbox),仅本机/联邦内通知,非 v1.2.1 规划的对外 Webhook/飞书推送;失败静默不阻塞 dream-cycle / health 主流程。

知识库与工具网关安全边界

知识库作为 Agent 可信调用载体,sofagent 的对应机制:

  • 权限核验:审计 A14 检测知识库越权访问——当前为事后审计而非运行时阻断(见 LIMITATIONS §五);运行时阻断列入 v2.x(ROADMAP.md)。
  • 受控 Action + 全链路审计:「模型提建议、审计模块控执行」——Action 经权限·副作用·审计后才落地(见 DEVELOPMENT §八)。
  • 权限隔离(Entity Resolution):多源知识先解析实体归属再授权,避免越权拼接——对应 knowledge/ 实体归属与 A15 约束验证。

三、编排安全

Prompt 注入 8 层防护映射表

引入版本:v1.1.8(补齐层 1/4/5)。

防护内容 sofagent 落点 状态
1 指令分层隔离——外部内容 <untrusted> 标签包裹 core/src/security/prompt-sanitizer.ts wrapUntrusted()(闭合标签转义防逃逸;harness 加载链联邦知识强制包裹) ✅ v1.1.8 补齐
2 工具动态最小权限 Sub Agent 工具集零重叠设计 ✅ 已有
3 工具参数后端强制校验 审计模块 git diff 硬证据 ✅ 已有
4 敏感数据不进 prompt——脱敏 prompt-sanitizer.ts redactForPrompt()(sk-***/AKIA***/手机号/邮箱/GitHub token/PEM 私钥;restricted 占位兜底,与 v1.1.6 isSensitivityVisible 过滤双保险) ✅ v1.1.8 补齐
5 RAG 召回可信分级 core/src/security/trust-grading.tsresolveTrust 缺省 internal;official>internal>user>web;web+restricted 丢弃;sortByTrust) ✅ v1.1.8 补齐
6 输出结构化 + 执行前审核 entry-gate 风险分级 + HITL ✅ 已有
7 高危动作强制人工确认 entry-gate 🔴 高风险审批 ✅ 已有
8 全链路日志 + 红队测试 审计 history.jsonl + daemon WARN 累积;联邦查询 federation_query 审计条目 ✅ 已有

⚠️ A9 注入检测局限——编码绕过:A9 正则检测覆盖常见中文"忽略类"指令、英文"ignore 类"指令,以及 leet speak 变体(1gn0r3ignore,通过 normalizeLine() 反转 + ×0.8 降权匹配)。但不覆盖:① Unicode 同形字替换(西里尔字母 а 替换拉丁 a);② Base64/hex 编码后的注入 payload。这些绕过手法依赖语义分析(非纯正则可覆盖),LLM 辅助检测暂未排期(跟踪于 ROADMAP)。在 LLM 辅助检测落地前,建议对外部输入做归一化(Unicode NFC + 解码后再送检)。

Sub Agent 工具集零重叠

引入版本:v1.1.0。

每个 Sub Agent 的工具集按职责域划分,无重叠。详见各 Sub Agent 配置。

编排模块 Sub Agent 委派

引入版本:v1.1.8。

每个 Sub Agent 的 systemPrompt 前置四层约束加载链(SKILL.md 宪法层不可被 workflow YAML 覆盖);同文件冲突检测 WARN(filesValue 文件级 LWW 合并的提醒,不阻塞);SubAgent 继承 LangGraph createReactAgent 默认工具集(read_file/write_file/edit_file/glob/grep/execute),主 Agent 仅保留 task 委派工具(tools: [])。

联邦查询离线降级

引入版本:v1.1.8。

单 peer 5s 超时按离线跳过不阻塞;全部 peer 离线 / federation 整块失败 → 退化纯本地查,不影响 MCP server 运行(best-effort)。


四、审计与存储安全

🔒 运行时审计日志按 git 仓库隔离(FORGE 自托管路径已交付 · 引擎侧移排 v1.4.7):运行时审计日志(runtime-audit.jsonl)在 FORGE 自托管 SubAgent 路径已按 data/audit/runtime/<repo-hash>/ 隔离存储(git rev-parse --show-toplevel hash;非 git 回退 nogit-<cwd-hash>,见 FORGE/src/audit-middleware.mjs)。引擎侧 data-sovereignty 审计日志(data/audit/data-sovereignty/{年}/{月}/)仍为全局单文件存储,与 commit 级审计历史 history.jsonl(全局)一致,多项目场景下记录混合——原声称排 v1.3.9 未兑现,已移排 v1.4.7 复用 FORGE 方案补齐引擎侧 repo-hash 隔离。

~/.sofagent/
├── data/          ← 用户可见运行时数据(审计/知识库/反思/任务日志)
├── internal/      ← 引擎内部状态(checkpoint / .git-shadow / watch.yml)
├── keys/          ← 静态加密密钥(0600,v1.3.8 能力 · 激活排期 v1.4.7)
├── bin/           ← CLI 入口
└── skill/         ← Skill 文件

ActionGovernance 审计溯源

引入版本:v1.1.7。

审计记录升级为可问责的动作凭证:ActionGovernance(actor/timestamp/targetEntity/context)+ DecisionProvenance 决策溯源组,写入 history.jsonl。提供事后可追溯性,但不在运行时阻断——Agent 仍可伪造 actor 字段(信任模型同 §审计模块信任模型)。防篡改 HMAC 签名详见下方「HMAC 签名(v1.1.8+ 已落地)」。

HMAC 签名

引入版本:v1.1.8(已落地)。

history.jsonl 自 v1.1.8 起支持 HMAC-SHA256 签名(密钥来自 ~/.sofagent-key)。有密钥时每条记录签名,Agent 无法在无密钥情况下伪造签名;无密钥时降级为 SHA-256 hash chain(Agent 可重算整链,仅事后可追溯非强防篡改)。--doctor(v1.2.0 起)会实际调用 checkHistoryChainDetailed() 校验链完整性。建议高安全场景配置 ~/.sofagent-key 启用强校验。

⚠️ 无密钥时篡改检测是「弱校验」:npm 直装等未配置 ~/.sofagent-key 的路径,篡改检测退化为 hash chain——手改 history.jsonl 后重算整链即可让校验通过(FAIL 抹成 PASS 在结构上可能)。企业 SOP 应强制配置 HMAC 密钥并周期性 --doctor 体检,不要依赖无密钥路径的篡改检测结论。

⚠️ HMAC 威胁模型边界:HMAC 防的是「无密钥方伪造/篡改签名」。同机同用户场景下,密钥文件 ~/.sofagent-key(权限 0600)可被同用户进程读取——与用户同身份运行的 Agent 可读取密钥后重签整条链,HMAC 无法阻止(同 LIMITATIONS「文件权限不防同用户进程」的既有披露)。因此 HMAC 的实际防御面是异地/跨用户攻击;对同用户重签,防线只剩事后 --doctor 体检 + CI 侧独立审计(CI 凭据与开发机隔离,不可被开发机进程重签)。

审计模块安全性(sofagent-audit)

sofagent-audit(v0.92+)是 TypeScript CLI,执行 execFileSync('git', ...) 读取 git diff 和文件系统。不使用 eval、不 spawn shell、不执行外部脚本。命令参数使用数组传入(['diff', '--unified=3', range]),range 参数经过正则校验 [a-zA-Z0-9~^.\-],无命令注入风险。

数据访问:审计模块核心不发起网络请求(webhook 为可选功能,需显式配置 URL 后才启用);写入仅限 ~/.sofagent/data/ 目录(审计历史、session 报告、快照等)。

信任边界:审计模块本身是确定性的——给定相同的 git diff 和日志,输出相同。但审计 A7/A8 的结果依赖 Agent 日志的真实性(Agent 可以伪造日志)。这不是审计模块的安全漏洞,是架构级别的信任模型选择。详见 LIMITATIONS.md(「审计模块信任模型:Agent 自我报告」节)。

⚠️ A14/A15 是 commit 时审计,不是运行时阻断。 Agent 在 commit 前仍可能访问受限数据——审计只能事后发现。这不是运行时沙箱。

24 条审计规则完整清单(文档级 SSOT)

本表是全部 24 条规则的文档级单一事实源(v1.3.8 口径,复核规则未变;代码注册表 engine/audit/src/rules/index.ts,逐条行为表见 engine/audit/README.mdtools/check/check-docs.sh 第 7/8 节做三方对账)。A12/A13 已于 v0.99.4 合并入 A11、E3 已于 v1.2.5 并入 A11,编号不再使用。

默认规则 17 条(始终生效;A18 自 v1.1.5 提升、A20-A23 自 v1.2.5 新增)

编号 名称 检测什么 判定
A1 不碰敏感 .env / *.pem / id_rsa 等敏感文件被修改 FAIL
A2 不泄密钥 API Key(AWS、OpenAI、Anthropic、DeepSeek、GitHub、Stripe、Google、Slack)/ Token / JWT / 私钥模式泄漏 FAIL
A3 不改越界 修改文件路径与任务描述不匹配 WARN
A4 不删配置 配置文件被删除 FAIL
A5 不瞒真相 commit message 为空或纯占位符 WARN
A6 不坏构建 构建配置文件异常改动 WARN
A7 不存盲改 被修改文件无读取记录(依赖 task/logs) FAIL/WARN
A8 不逃验证 构建文件变更后无测试记录 FAIL/WARN
A9 不纳注入 忽略指令/prompt 注入风险模式 FAIL
A10 不引毒源 依赖包黑名单 + typosquatting + postinstall 注入 WARN
A11 不滥资源 资源滥用(超大文件、大行数删除等) WARN
A18 垃圾文件 临时文件名模式的垃圾文件 WARN
A19 msg 质量 commit message 命中黑名单词或过短 FAIL
A20 不泄外联 数据外传(curl/wget POST、WebSocket、DNS 隧道) FAIL
A21 不植后门 持久化后门(LaunchAgent/systemd/crontab/注册表自启) FAIL
A22 不越权限 权限提升(全权限 chmod、sudoers、setuid) FAIL
A23 不逃路径 路径穿越 / symlink 逃逸 FAIL

扩展规则 7 条(默认关闭,extendedRulesEnabled: true 启用)

编号 名称 检测什么 判定
A14 知识库越权 访问超出业务流声明范围的知识库页面(事后审计) WARN
A15 不盲动 workflow 节点未声明 actions FAIL
A16 非授权文件变更 非声明范围文件被修改(行为级) FAIL
A17 异常批量变更 单次提交变更文件数超阈值(filesystem 模式) WARN
E1 不落测试 测试文件被提交到生产目录 WARN
E2 TODO 未声明 新增 TODO 未在任务中声明 WARN
E4 低注释率 新增 >200 行且注释率 <5% WARN

AST 规则引擎 SSOT(8+2)

官方 AST 规则引擎(sofagent-ruleset-ast,v1.3.9 交付)——10 条示范规则(8 条代码 AST + 2 条 OWASP 语义),与上面 24 条 git-diff 规则同管线。规则代码在 engine/rules/src/ast/rules/(注册表 engine/rules/src/ast/rules/index.tsbuiltinAstRules),触发条件以各文件 description 字段为准。

编号 名称 触发条件 代码位置
no-eval 禁止动态代码执行 eval() / new Function() 执行任意字符串代码(prompt 注入 / 供应链攻击放大器) ast/rules/no-eval.ts
no-hardcoded-secret 禁止硬编码密钥(AST 语义级) secret/token/apiKey 等密钥类变量赋长字符串字面量(比正则扫行误报率低) ast/rules/no-hardcoded-secret.ts
no-dynamic-require 禁止动态 require require(非字面量) 模块来源静态不可见(供应链投毒隐藏通道,ASI04 关联) ast/rules/no-dynamic-require.ts
no-debugger 禁止 debugger 语句 debugger 语句遗留在生产代码会冻结 Node 进程 ast/rules/no-debugger.ts
no-child-process-shell child_process shell 执行管控 exec/execSync 走 shell——字面量含元字符或动态拼接参数(动态参数 FAIL / 静态参数 WARN) ast/rules/no-child-process-shell.ts
no-sql-string-concat 禁止 SQL 字符串拼接 query 类调用的参数含「字符串 + 非字面量」拼接(SQL 注入入口) ast/rules/no-sql-string-concat.ts
no-insecure-url 禁止 http:// 明文端点 字符串字面量里的 http:// 端点(本地/示例域名除外,明文传输可被中间人替换) ast/rules/no-insecure-url.ts
no-empty-catch 禁止空 catch 块 空 catch 吞异常且无注释说明(错误静默扩散) ast/rules/no-empty-catch.ts
asi01-prompt-injection OWASP ASI01 目标劫持检测 system prompt 类文件的对抗性注入模式(指令覆盖/角色劫持/结构伪装,含编码变体归一化) ast/rules/asi01-prompt-injection.ts
asi04-sbom OWASP ASI04 供应链 SBOM 检测 扫描依赖清单(lockfile 优先精确版本、manifest 兜底)生成 SBOM 查离线样例漏洞库 ast/rules/asi04-sbom.ts

history.jsonl 访问控制

引入版本:v1.1.3。

history.jsonl 存储审计拦截记录(含被拦截的 diff 摘要)。以下为当前访问模型:

操作 Agent 能否? 说明
读取 ✅ 能(以当前用户身份) Agent 和审计模块共享同一文件系统权限
写入 ✅ 能 Agent 可以追加/删除/篡改 history.jsonl
检测篡改 ⚠️ --doctor 第 8 项检查 通过 hash chain 验证——但 Agent 可以在篡改后重新计算整条链

缓解:sanitize() 管道在写入前对密钥/密码/手机号打码。但这不是加密——Agent 可以从原始 git diff 中直接读到敏感内容。根治方案:age 加密(v1.3.8 落地,参见 ROADMAP.md)+ 独立审计存储(更后期规划)。

审计日志脱敏与访问控制

sanitize() 管道在写入 history.jsonl、think.md、task/logs 等文件前自动执行:

  • 密钥打码:匹配 sk-/Bearer/api_key/password= 等模式 → 替换为 ***REDACTED***
  • 手机号打码:匹配 11 位手机号格式 → 138****1234
  • 密码字段打码:匹配 password[:=]\s*\S+password=***
  • v1.2.8 自定义业务机密脱敏:config.yml 配置 sanitizePatterns 字段可添加企业业务机密正则(如合同名称/客户名单/工资表),审计记录和 webhook 推送前均过自定义脱敏管道。示例:
    sanitizePatterns:
      - pattern: "合同编号[::]\\s*\\d{6,}"
        replacement: "[合同编号:REDACTED]"
      - pattern: "[\\u4e00-\\u9fa5]{2,4}的工资单"
        replacement: "[工资单:REDACTED]"

以上为掩码(masking)非加密——原始数据仍在 git diff 中可读。sanitize() 只保护写入 data/ 的副本,不保护源头。

文件权限data/ 目录权限建议 700(用户可见运行时数据);~/.sofagent/internal/ 目录权限 700(引擎内部状态)。install.sh--init 自动设置。同一服务器其他非 root 用户无法读取。root 用户可读——如需防 root,建议将 data/ 放在加密卷上。

history.jsonl 存储

引入版本:v1.1.3。

审计拦截记录以 JSONL 明文存储在 data/audit/history.jsonl,目录权限 0o700、文件权限 0o600(v1.1.3 起收紧)。仅追加写入(appendFileSync),不覆盖、不删除。历史记录供编排模块和进化模块本地读取。

HMAC 密钥轮换:HMAC 签名密钥存储在 ~/.sofagent-key(权限 0600)。如需轮换(如安全审计要求或疑似泄露):

# 1. 备份旧密钥(旧 hash chain 仍需此密钥验证)
cp ~/.sofagent-key ~/.sofagent-key.old.$(date +%Y%m%d)

# 2. 生成新密钥(openssl 32 字节随机)
openssl rand -base64 32 > ~/.sofagent-key
chmod 600 ~/.sofagent-key

# 3. 注意:轮换后旧 history.jsonl 的 HMAC 签名将无法用新密钥验证
#    --verify-chain 会报告旧条目签名不匹配(这是预期行为)
#    新条目将使用新密钥建立新的 hash chain

审计备份说明:sofagent 审计模块当前不自动生成 history.jsonl.bak-* 备份文件(SECURITY.md 早期版本描述的"达到大小阈值时生成备份"机制在代码中不存在)。history.jsonl 为 append-only 单文件,不覆盖、不轮换。如需备份,建议用外部 cron + cp 定期归档:

# 手动备份(建议加入 crontab)
cp ~/.sofagent/data/audit/history.jsonl ~/.sofagent/data/audit/history.jsonl.bak-$(date +%Y%m%d)
chmod 600 ~/.sofagent/data/audit/history.jsonl.bak-*

威胁模型:SOFAGENT_DATA 环境变量的信任边界(本版声明为已知风险)

getHistoryFilePath()engine/core/src/audit-history.ts)解析审计历史路径时优先级为:显式 dataDir 参数 > SOFAGENT_DATA 环境变量 > 默认 data/audit/history.jsonl。写入侧(appendHistory)与校验侧(checkHistoryChainDetailed)均走此函数。

设计初衷SOFAGENT_DATA 用于测试隔离(如 loader.test.tsvi.stubEnv('SOFAGENT_DATA', '') 切换数据目录),属合理需求。

信任边界与风险分级:能设置目标进程环境变量的攻击者,可将审计历史重定向到任意路径——「写到别处 + 校验读别处」使篡改表面看起来正常。该风险完全取决于部署场景

部署场景 风险等级 说明
本地开发机 🟢 低 攻击者已能在本机设置环境变量 = 已拥有本机用户权限,游戏结束,审计重定向不构成额外提权
CI / 共享服务器 🟡 中 同机其他用户/作业可能注入环境变量,审计历史可被悄悄重定向

本版决策(方案 C · 声明而非改码):本版不修改 audit-history.ts 的路径解析逻辑,仅在此明确声明信任边界。理由:① 本地低风险场景下白名单/固定路径会损害测试隔离与多实例部署的灵活性;② 共享服务器场景的正确防线是环境隔离(每用户独立 ~/.sofagent/、CI 作业独立容器/沙箱、env -i 清洗环境),而非在审计模块内做路径白名单(白名单本身也可被同权限攻击者绕过)。

共享服务器缓解建议:① CI 作业运行在独立容器/沙箱,环境变量不可跨作业注入;② 启动入口用 env -i 或显式白名单透传环境变量;③ 对 history.jsonl 所在卷做完整性监控(文件路径 + mtime 基线告警)。路径白名单校验(方案 A)与审计路径固定(方案 B)作为可选加固,列入 ROADMAP 评估。

威胁模型:SOFAGENT_KEY_PATH / SOFAGENT_HOME_ALLOWED_PREFIXES 环境变量

SOFAGENT_DATA 同属环境变量信任边界,本节一并声明:

  • SOFAGENT_KEY_PATHengine/core/src/audit-history.ts:82):HMAC 密钥路径覆盖,优先级为 SOFAGENT_KEY_PATH > ~/.sofagent-key。能设置该变量的攻击者可将签名密钥重定向到自控文件——写入侧与校验侧同读该密钥时链校验仍「通过」,但密钥已不在用户掌控。设计初衷同 SOFAGENT_DATA(测试隔离,如 llm-call-trace.test.ts 用其指向临时密钥);风险分级与缓解同上节(本地低 / 共享中,防线是环境隔离非路径白名单)。
  • SOFAGENT_HOME_ALLOWED_PREFIXESengine/core/src/data-paths.ts:43):SOFAGENT_HOME 越界回退白名单的扩展入口(冒号分隔,企业场景显式扩展安装根前缀)。注意双向性:它既可把合法定制路径收进来(预期用途),也可把越界路径放进来——能设置该变量的攻击者可将 SOFAGENT_HOME 重定向到自控前缀下(数据落点与审计主链分家,同 LIMITATIONS 数据目录解析 已披露的双轨风险叠加)。缓解同上节:入口环境清洗 + 部署期前缀清单管控。

已知绕过路径

二级防御总述:commit hook 是第一道防线(事前拦截),daemon 巡检 + --doctor 定期体检是第二道防线(事后发现),CI 侧 --diff 审计是兜底防线(hook 可绕 CI 不可绕)。当前 fail-closed 边界:仅 config 解析失败时走 safeDefaults(全规则启用);config 被定向篡改不触发 fail-closed,需 CI 兜底。

绕过方式 检测手段 缓解
git commit --no-verify ⚠️ post-commit hook 事后对账留痕(不阻断) --init 同时装 pre-commit + commit-msg + post-commit(v1.4.2 三层防线):绕过 commit-msg 的 commit 会被 post-commit 对账——命中拦截记录时输出「疑似绕过」提示并留痕 history.jsonl;未命中输出 INFO 提示可用 --verify-commit <SHA> 复核。定期 --doctor 检查未审计的 commit(git log --grep 匹配审计签名);CI 侧 sofagent-audit --diff HEAD~1..HEAD 兜底
git add -f .sofagent/(审计数据强制入库) ✅ v1.4.2 H-01 三层防线拦截——pre-commit 在 commit 对象生成前将 .sofagent/ 移出暂存区(主防线,对当次 commit 直接生效);commit-msg 阶段再兜一次(护磁盘 index 防后续 commit 卷入);post-commit 扫 HEAD tree 命中即告警 pre-commit reset 失败(index.lock 竞态)时 fail-loud 拒绝 commit(宁可 false-retry 不可静默入库);CI 侧 --diff 仍可发现已入库残留
删除 commit-msg hook 文件 ⚠️ --doctor 可检测 daemon 文件监控(fs-watch,v1.3.6 起)可配置监控 .git/hooks/ 目录变化(watch.yml 自定义路径);hooks 目录监控未内置为默认巡检项(规划中)
伪造 Agent 日志(task/logs) ❌ 无自动检测 人工抽查 + 交叉验证 git log 时间戳
绕过 --init 直接手动修改 config.yml ❌ 无自动检测 config hash 校验(--sign-config 签名 + 验签,篡改时 CLI 拒绝启动 exit 2)
SOFAGENT_CONFIG 环境变量指向恶意 config(v1.2.9 起最高优先级配置入口) ⚠️ --doctor 可检测环境变量 启动入口用 env -i 或显式白名单透传环境变量(见共享服务器缓解建议);CI 侧用受控 config
--verify-chain 场景:追加伪造审计记录(history.jsonl 末尾追加格式合法的假 PASS 行) ⚠️ 结构异常可检出(缺 timestamp/exitCode 必有字段或非 JSON 行 → 判 tampered,exit 2);格式完整但 HMAC 不可复验的 legacy 记录仅 ⚠️ 容忍 审计后立即备份 history.jsonl(--verify-chain 定期校验);HMAC 密钥妥善保管(密钥在手可伪造任意合法签名)
密钥藏进二进制文件(blob 夹带,非文本 diff) ⚠️ A2 对新增二进制扩展(.bin/.exe/.dll/.so/.dylib 等)或 Binary files differ 标记输出 WARN「不扫内容请人工确认」(v1.3.7 起) 二进制 WARN 人工确认;强合规场景对二进制提交走独立密钥扫描(gitleaks --binary 类工具)
密钥编码后放函数参数位:Buffer.from("<b64>", "base64") / atob("<b64>") ✅ v1.4.1 F-15 起拦截——A2 提取函数调用参数里的编码串候选,base64/hex 解码命中密钥正则即 FAIL(红队实锤堵洞,回归测试固化) 已默认拦截,无需额外缓解
密钥 \\xNN hex 转义形态("\\x41\\x4b..." ✅ v1.4.1 F-15 起拦截——A2 对含 \\x 转义的行还原后跑密钥正则 已默认拦截,无需额外缓解
密钥字符串拼接形态(拆两半用 + 相邻摆放) ✅ v1.4.1 F-15 起拦截——A2 合并同行相邻字面量后检测 已默认拦截,无需额外缓解
密钥放环境变量/模板变量(${env.KEY} / process.env.KEY ✅ 不构成泄漏——密钥本体不在 diff 内容中,属合法引用形态,A2 放行是设计行为 无需缓解(这是推荐做法:密钥走 .env + .gitignore)

⚠️ 以上绕过路径均依赖 Agent 的"自觉"——这是 sofagent 架构级别的信任模型选择:审计模块是协助人类监督,不是替代人类监督。已知绕过路径详见 LIMITATIONS 已有信任模型描述。

⚠️ 企业高安全场景config.yml 篡改可绕过审计规则(如关闭规则、放宽阈值)。建议:① CI 侧独立校验 config 完整性(sofagent-audit --diff 兜底,hook 可绕 CI 不可绕);② 文件权限锁(chmod 600 .sofagent/config.yml,仅受信用户可写)。与已有 --no-verify CI 兜底建议呼应。

⚠️ 企业高安全默认:基线规则(A1/A2/A9/A10/A11/A20-A23)有强制保护不可禁用,但非基线规则(A3-A8、A14-A19)可经 rules:{x:false} 关闭。高安全场景建议显式锁定所有规则:extendedRulesEnabled: true + 在 config 中对全部非基线规则显式 rules:{a3:true, a4:true, ...}(禁止依赖默认值),并配合 chmod 444 .sofagent/config.yml 只读锁定。

💡 hardenedMode 配置项尚未实现(代码中不存在此字段)——一键全规则基线化的便捷配置排入 ROADMAP 评估,当前需手动按上述方式逐条锁定。

⚠️ 影子审计器劫持(v1.2.7 已知风险):本地安装的 engine/audit/dist/index.js 无完整性校验(dist 目录不随 git 版本控制),恶意 Agent 可替换 dist 绕过所有审计规则——比 --no-verify 更隐蔽(hook 仍在运行,看不出绕过)。--doctor 已增加 dist 哈希校验(SHA-256 比对 ~/.sofagent/internal/audit-hash.txt),但根治需代码签名 + 运行时验证(暂未排期,跟踪于 ROADMAP)。CI 侧 sofagent-audit --diff 使用独立安装可缓解(CI 环境的 dist 不可被开发机 Agent 篡改)。基线建立指引(v1.4.2):装好后立即执行 sofagent-audit --doctor --baseline 显式建立基线哈希(信任锚 = 你此刻确认 dist 可信的时刻);此后 --doctor 会校验 dist 与基线一致,基线缺失时将显性报错提醒(不再自动记录——防止把已被篡改的 dist 固化为合法基线)。

详细缓解步骤

  1. CI 侧兜底(推荐):在 CI/CD pipeline 中独立运行 sofagent-audit --diff HEAD~1..HEAD(审最近一次 commit;审整个分支区间用 --diff main..HEAD), 使用 CI 环境内受保护的 config.yml 副本,不依赖开发机上的配置文件。 ⚠️ 边界说明--diff HEAD~1..HEAD 依赖「至少 2 个 commit」的仓库——首次提交(单 commit 仓库无 HEAD~1)会 exit 2。首次提交场景请用 --init 装 hook 自动审计,或改用 --diff HEAD(审工作树与 HEAD 的差异)。
  2. 文件权限加固chmod 444 .sofagent/config.yml 将配置设为只读。 注意:此方法不能防止 Agent 以 root/同用户身份强制写入, 但能防止意外修改。
  3. 完整性校验:使用 tools/release/sign-config.mjs 对 config.yml 签名, 定期运行 sofagent-audit --doctor 检查配置完整性。

⚠️ --doctor 退出码语义(CI 场景注意):doctor 默认只在 error 时返回非零,warning(如 hook 缺失)仍 exit 0——CI 只看 exit code 会漏掉 warning 级问题。CI 场景请用 sofagent-audit --doctor --strict(warning 也返回非零),人工日常体检用默认模式即可。

💡 更多本地开发缓解措施详见 LIMITATIONS.md → 本地开发紧急缓解措施(chmod 400、git hooksPath、定期 doctor)。

受影响场景

  • 不上 CI 的小团队或个人项目(风险最高)
  • Agent 具有文件系统写入权限的任何场景
  • sofagent-audit --init 后未额外加固配置权限的场景

Daemon 监控边界

sofagent daemon 是本地文件系统监控守护进程,其行为边界如下:

维度 说明
监控范围 data/ 工作目录 + 用户显式配置的路径(config.yml 中的 daemon.watchPaths)。不扫描用户其他文件。
数据去向 所有数据本地存储(data/ 目录下),不上传云端,不向外发送网络请求——除非用户显式配置 TencentDB Memory 集成(install.sh --with-memory,opt-in)。
权限 只读监听文件事件(hash 变化检测 + cron 定时巡检)。不修改用户文件、不删除文件、不外传数据。审计发现写入 daemon-health.jsonhistory.jsonl
审计结果推送 v1.2.1 已支持 Webhook 推送(飞书/钉钉/企微,engine/audit/src/webhook.ts + engine/daemon/src/notify.ts + push-target.ts)。企业 IT 可配置 webhook 字段实现实时告警推送。

💡 企业集中收集:v1.2.1 已支持 Webhook 推送(飞书/钉钉/企微),企业 IT 可配置 webhook 字段实现实时告警推送。如仍需集中收集审计日志(如用 Filebeat / Logstash / Fluentd 采集),可定时轮询 data/audit/history.jsonl(append-only、JSONL 明文),转发至 SIEM / 企业日志平台。注意 history.jsonl 为明文存储,转发前建议配合外部加密卷或 age 加密,避免敏感 diff 摘要外泄。

daemon 源码见 engine/daemon/src/fs-watch.ts(文件监听)、cron.ts(定时巡检)、snapshot.ts(快照)、usb-detect.ts(USB federation 检测,v1.1.4+)、dream-cycle/(Dream Cycle 6 阶段管道,v1.1.7+)、inspectors/knowledge-health.ts(知识健康巡检,v1.1.7+)、commands/knowledge-status.ts(知识状态聚合命令,v1.1.7+)、federation/(联邦查询,v1.1.8+)、usb-signature.ts(USB HMAC 签名,v1.1.9+)、usb-key.ts(USB key 创建,v1.1.9+)、usb-runtime.ts(USB 运行时启动,v1.1.9+)、notify.ts(统一通知接口,v1.1.3+)。


五、工程安全

install.sh 行为说明

install.sh 是 sofagent 的一键安装脚本。以下是其完整行为清单,供安全审查:

脚本会做的事

操作 路径 说明
创建目录 ~/.openclaw/skills/sofagent/~/.workbuddy/skills/sofagent/ 按平台部署 Skill 文件
创建目录 ${项目目录}/data/task/logs/ 数据目录,权限 700
复制文件 宪法(fde.md) + 6 核心 Skill + 数据模板 + 配套脚本 从仓库 SKILL/harness/engine/scripts/ 复制到目标目录
写入配置 ~/.openclaw/openclaw.json(仅 OpenClaw) 注册加载链 Hook
写入配置 ~/.openclaw/config.json(仅 OpenClaw) 注入 loopDetection 断路器
npm install @langchain/langgraph(编排模块依赖) Sub Agent 编排模块
安装服务 launchd(macOS) / systemd(Linux) daemon 后台进程(交互确认后。daemon 当前为 bash 实现,正常运行中)

脚本不会做的事

  • ⚠️ 不会交互式提权(不弹密码框)——仅当 symlink 目标目录不可写且 sudo NOPASSWD 已配置时,以非交互 sudo -n 注册 CLI 命令(失败则回退 ~/.local/bin),其余操作在用户权限范围内
  • ❌ 不会改系统文件——不碰 /etc/System/usr/local/bin 仅创建一个 symlink)
  • ❌ 除安装时的 npm 依赖拉取(见上表)与 --remote 模式的 git clone 外,运行时不联网——安装后的审计模块、daemon、MCP server 均不发起网络请求(webhook 为可选功能需显式配置)
  • ❌ 不会执行远程脚本(--remote 模式只做 git clone 官方仓库)
  • ❌ 不会收集或上传任何用户数据

远程安装(curl | bash)信任模型(v1.4.3 P2-f 披露)

一行安装(curl ... bootstrap.sh | bash)的行业通用信任链是「HTTPS 传输 + GitHub 账号安全」,无代码签名——若 raw.githubusercontent 通道或仓库账号被劫持,下载的脚本可被替换为任意代码。sofagent 自 v1.4.3 起在此模型上追加一层:bootstrap.sh 内嵌发版时硬编码的 sha256(install.sh + 6 个 lib 文件共 7 个哈希),下载内容与发版时不一致即 fail-closed 拒绝执行——劫持者即使控制传输通道,也无法在不改哈希(哈希在 bootstrap.sh 自身内,用户 curl 到的那份)的情况下替换安装载荷。残余信任面如实披露:① 用户 curl 到的 bootstrap.sh 本身仍无签名(首跳信任,与全行业一致);② 哈希随发版更新,若发版流程被攻破(哈希与载荷同被替换)校验失效——此层防御针对传输劫持,不针对供应链根攻破;③ 高安全场景建议 git clone + 审查后 bash install.sh,绕开首跳信任。

源码审查

install.sh 拆分为以下模块,便于逐模块审查:

模块 职责
install.sh 主入口(组装 + 参数解析)
lib/config.sh 配置加载 + 常量定义
lib/daemon-lib.sh daemon 公共函数库
lib/daemon-register.sh Hook + daemon 注册
lib/file-deploy.sh 文件部署
lib/platform-detect.sh 平台探测 + 参数解析
lib/post-install.sh 安装后检查 + 输出

第三方依赖供应链

@langchain/langgraph 是 sofagent 编排模块的正式依赖(提供 createReactAgent)。v1.2.0 起从 DeepAgents 迁移为正式依赖。

🔴 Breaking Change(v1.0.7):ao(agency-orchestrator)已完全退役。v1.0.6 用户升级到 v1.0.7 后需手动卸载:npm uninstall -g agency-orchestrator。编排模块已全面迁移到 LangGraph createReactAgent,ao 代码路径全部移除。

供应链安全建议

  • 每次 npm install 后运行 npm audit
  • 内网环境建议预装 @langchain/langgraph 并验证安装通过后再部署

@automerge/automerge 现状声明(v1.3.5 迁移后实态)

v1.3.5 交付 4b 起,CRDT 依赖已从旧包 automerge@1.0.1-preview.7(preview 版,精确锁定防意外升级)整体切换为 @automerge/automerge@^3.4.1(Rust WASM 稳定核心,core 与 orchestrator 两包声明)。旧包名已废弃不再使用。

  • 迁移面engine/core/src/federation.ts(init/change/clone/merge)与 orchestrator team 三件(team-state / team-manager / protocol);API 对照见 v1.3.5 开发日志交付 4b 段,回归保险=team-state.regression.test.ts(11 用例)+ 联邦同步测试。
  • uuid 传递依赖已消解:旧 preview 包传递依赖 uuid@3.4.0(2018 弃用,uuid() 默认 RNG 可预测漏洞 GHSA-w5hq-g745-h8pq)——迁移后 lock 中 uuid 已不在依赖树(实测 package-lock 零 uuid 条目),原「可利用性极低」的评估对象已不存在。
  • 升级纪律^3.4.1 语义化范围内可升,跨 major 须先跑联邦合并与 team-state 回归测试(与 releasing/02-dev「禁止自动升」清单联动)。

六、LLM API Key 透明度

引入版本:v1.2.0。

FORGE fresh-eyes-loop 的 A/B sub-agent 需要 LLM API key。 本节说明 key 的存储、使用、边界。

Key 存储位置

仅本地环境变量(用户自行配置):

位置 适用场景
~/.zshrc macOS / Linux 默认 shell
~/.bashrc Linux 备选 shell
系统环境变量面板 Windows
CI/CD secret injection 自动化场景(推荐用 secret 管理服务,不走 .env 文件)

代码库中零硬编码 key——.env 文件被 .gitignore 排除。

Key 加载优先级(三级回退)

SOFAGENT_LLM_{ROLE}_API_KEY  >  SOFAGENT_LLM_API_KEY  >  OPENAI_API_KEY
   角色专用 key(A/B 分账)     通用 key(共用一把)     OpenAI 兼容默认
  • SOFAGENT_LLM_A_API_KEY:A 角色(审查模型,用户自行配置)专用 key
  • SOFAGENT_LLM_B_API_KEY:B 角色(工程模型,用户自行配置)专用 key
  • SOFAGENT_LLM_API_KEY:A/B 共用一把 key(两个 provider 都是 OpenAI 兼容格式时可用)
  • OPENAI_API_KEY:兜底默认(OpenAI SDK 标准环境变量)

Key 使用边界

key 仅用于:

用途 说明
调用用户配置的 LLM API GLM(open.bigmodel.cn)/ DeepSeek(api.deepseek.com)/ OpenAI 兼容 endpoint
请求头鉴权 Authorization: Bearer <key>,标准 HTTPS 请求

Key 不做什么(四条红线)

  • 不上传到任何第三方服务(sofagent 无后端服务器,key 不离开本机)
  • 不写入任何日志文件(usage.jsonl 只记 token 数,不记 key)
  • 不写入 git 历史(.gitignore 排除 .env
  • 不转发给除目标 LLM 厂商以外的任何端点

验证方式

用户可自行扫描代码确认无硬编码 key:

# 扫描代码中的 key 硬编码(不应有结果)
grep -rnE "sk-[a-zA-Z0-9]{20,}" FORGE/src/ engine/
# 确认 .env 在 .gitignore 中
grep -n "\.env" .gitignore
# 确认 usage.jsonl 不含 key(只有 token 计数)
grep -i "api_key\|apikey\|sk-" runs/*/usage.jsonl   # 应无结果

七、FDE 职业道德

📖 方法论来源:范冰《前线部署工程师》后记「FDE 的职业道德」——FDE 手里握着的不是一般的技术,是客户组织最深处的秘密和越来越大的代替人做决定的权力。完整六条底线见 FDE/GUIDE.md「FDE 职业道德六条底线」

本节聚焦与安全策略直接相关的三条:

  1. 数据的主权属于客户——在客户现场看到的数据,一个字节都不应该出现在不该出现的地方:不进 AI 训练数据(除非合同明确授权)、不进案例素材(除非客户书面同意)。sofagent 工程呼应:数据不出本机(§已知风险)+ 联邦查询可选(§一传输安全)+ sensitivity 分级(§二知识安全)+ 最小权限原则。
  2. 诚实报告结果,包括坏消息——按结果收费的模式里最大的道德风险是粉饰结果。sofagent 工程呼应:审计模块 git diff 硬证据(24 条规则零 token 纯静态判定,不靠模型「自评」)+ HMAC 链防篡改(§四审计与存储安全)+ 运行时审计日志按 git 仓库隔离(FORGE 自托管路径已交付 repo-hash 隔离;引擎侧 data-sovereignty 仍全局——已移排 v1.4.7;commit 级 history.jsonl 全局存储,见 §四)。
  3. 不制造依赖,不贩卖恐惧——不故意把系统做成黑箱让客户永远离不开你;不夸大「不用 AI 就会死」的恐慌促成交易。sofagent 工程呼应:MIT 开源(客户可自主审计代码)+ 交付物(ontology/workflow/skills)客户可自主维护 + FDE 离场机制(§五工程安全 install.sh 行为说明:只写入 ~/.sofagent/,不锁死客户环境)。

其余三条(把被替代的人当回事 / 对不该做的事说不 / 记住你代表技术本身)属 FDE 个人职业操守范畴,非安全工程范畴,详见 FDE/GUIDE.md。


八、训练安全

引入版本:v1.4.1(后训模块 · 地基)。

后训模块开放后新增的攻击面(job.json 路径注入 / 超参命令注入 / 跨企业数据串读 / 云凭据经日志泄漏 / 训练产物篡改)由 v1.4.1 安全基线覆盖:路径白名单五重校验、spawn 元字符拒绝(拒绝而非清洗)、enterpriseId 全链路隔离 + 分区作用域读取、键名/值双轴凭据脱敏(先脱敏再签名)、权重 SHA-256 + HMAC manifest 与部署加载验签阻断(artifact_tampered 高危审计事件)。训练数据投毒检测与基座模型后门检测明确不在开源版范围(商业侧职责)。完整攻击面声明、模型层职责边界、系统级部署提示(Time Machine 快照 / SSD 覆写诚实边界)与红队核对清单见 训练安全基线;双栈分层契约(决策面 / 计算面 / 资源面)见 训练双栈契约


九、合规框架映射

引入版本:v1.4.1。

本节把 sofagent 的安全能力映射到 OWASP Agentic Security Top 10(2026,2025-12-09 发布,genai.owasp.org)——Agent 安全领域当前最常被引用的公开分类框架,供安全评审与企业合规读者快速对位。映射原则:只标真实存在的能力,不虚标覆盖——每条注明对策落点与已披露边界,未覆盖面明确列出。

OWASP Agentic Top 10 映射表

ASI 威胁 sofagent 对策 已披露边界
ASI01 目标劫持 注入指令覆盖 Agent 目标(prompt 注入) A9 不纳注入(正则+leet 归一化)+ AST asi01-prompt-injection(system prompt 载体扫描)+ <untrusted> 包裹(§三 8 层防护层 1) A9 不覆盖 Unicode 同形字/Base64 编码注入(§三编码绕过注);语义级检测未排期
ASI02 工具滥用 越权调用工具、参数投毒 Sub Agent 工具集零重叠(§三)+ 工具参数后端强制校验(8 层防护层 3,git diff 硬证据)+ A16 非授权文件变更(扩展) 工具层校验是 commit 时点,非运行时阻断
ASI03 身份与权限滥用 Agent 冒用身份、越权访问资源 A22 不越权限(chmod/sudoers/setuid)+ A23 不逃路径(路径穿越/symlink)+ A14 知识库越权(扩展,事后审计)+ config --sign-config 签名防篡改 A14/A15 是 commit 时审计非运行时阻断(§四);同机多 Agent 无身份隔离(LIMITATIONS)
ASI04 供应链投毒 恶意依赖、typosquatting、postinstall 注入 A10 不引毒源(黑名单+typosquatting+postinstall)+ AST asi04-sbom(lockfile 生成 SBOM 对漏洞库)+ no-dynamic-require + install.sh 只 clone 官方仓 旧 automerge preview 版 uuid 传递依赖风险已随 v1.3.5 迁移 @automerge/automerge@^3.4.1 消解(§五)
ASI05 意外代码执行 RCE——Agent 执行了非预期代码 AST no-eval + no-child-process-shell(动态参数 FAIL)+ A21 不植后门(自启动持久化)+ A5 不瞒真相 + 审计模块自身 execFileSync 数组传参无 shell 审计是事后检测,无运行时沙箱拦截
ASI06 记忆与上下文投毒 篡改知识库/审计历史污染后续决策 HMAC 链(§四:~/.sofagent-key 签名 + --verify-chain/--doctor 校验)+ --sign-config + USB federation HMAC 全量签名 + trust 可信分级(web+restricted 丢弃)+ sensitivity 双重过滤 无密钥时退化 hash chain 弱校验;同用户进程可读密钥重签(§四 HMAC 威胁模型边界)
ASI07 智能体间通信攻击 A2A/联邦链路伪造、窃听 联邦查询四层防线(§一:localhost 绑定 + channel 路由 + AES-256-GCM 加密 payload + sensitivity 双重过滤)+ 三条配对路径(6 位码+指纹人工确认防 MITM)+ 密钥 24h 轮换 OpenClaw channel 自身 ws:// 无 TLS——应用层加密是唯一保密防线(§一审计结论);仅覆盖 sofagent 联邦链路,不覆盖外部 A2A 协议
ASI08 级联失效 一个 Agent 失败拖垮整条链 快照回滚(internal/checkpoint + snapshot)+ 联邦查询离线降级(单 peer 5s 超时跳过,全离线退化本地)+ A11 不滥资源(超大文件/大删除)+ A8 不逃验证 无跨 Agent 编排级熔断器(单 Agent 循环失控熔断依赖 OpenClaw loopDetection)
ASI09 人机信任滥用 Agent 虚假汇报骗取人工批准 24 条规则 git diff 硬证据(不采信模型自评)+ A7 不存盲改(无读取记录的修改 FAIL)+ A5/A19 msg 质量 + entry-gate 🔴 高风险强制人工审批 + daemon 文件监控事后对账 Agent 可伪造 task/logs(§四已知绕过路径);HITL 依赖人真正审阅
ASI10 流氓 Agent Agent 脱离监管自主行动 --doctor 定期体检(hook 完整性/dist 哈希/config 签名/未审计 commit 扫描)+ post-commit 对账(绕过 commit-msg 留痕)+ daemon fs-watch + CI 侧 --diff 独立兜底(hook 可绕 CI 不可绕)+ 基线规则不可禁用 全部是事后检测/体检模型,无运行时进程级监控(如 eBPF);影子审计器劫持见 §四 v1.2.7 风险
未覆盖面 以下三类当前无对应能力,企业强合规场景需外部措施补位:多租户身份隔离(等 ROADMAP v1.4.7 G7)/ 运行时沙箱拦截 / 外部 A2A 协议安全(通信面仅覆盖 sofagent 联邦链路)
NIST AI RMF / EU AI Act / SOC 2 未做正式对照(无认证与审计证据链),不做映射声明;如需上述框架的证据链,需商业层提供,开源版不虚标

📌 阅读提示:表中「§N」指本 SECURITY.md 对应章节;规则 A1-A23 编号见 §四「24 条审计规则完整清单」;AST 规则见 §四「AST 规则引擎 SSOT」。

📌 本表是能力对位表而非认证声明——sofagent 未通过任何第三方安全认证,映射仅表示「对该威胁类别存在已披露的对策与边界」,不构成合规背书。


报告漏洞

如发现安全漏洞,请通过以下方式私下报告(不要在公开 Issue 中披露):

  1. GitHub Security Advisory(推荐主通道):提交私有报告
  2. 响应时间:我们承诺在 72 小时内确认收到报告,7 天内提供初步评估。

📌 漏洞报告仅走 GitHub Security Advisory 单通道(v1.3.6 fresh-eyes 修正:此前列出的 noreply 邮箱无法收信,不能作为安全渠道)。

响应承诺

  • 确认:72 小时内确认收到报告
  • 初步评估:7 天内给出初步评估和影响范围
  • 修复:根据严重程度排期——高危(数据泄露/权限提升)优先修复并发布补丁版本

适用范围

本安全策略适用于 sofagent 项目仓库内的所有文件。第三方依赖(如 @langchain/langgraph、OpenClaw)的安全问题请向对应项目报告。

免责声明

sofagent 基于 MIT 许可证发布,按「现状」(AS IS)提供,不附带任何明示或暗示的担保。作者不对因使用本软件而产生的任何直接、间接、附带或后果性损害承担责任。sofagent 是审计模块而非安全防线——它能检测常见的 Agent 违规模式,但不能保证拦截所有攻击向量。

There aren't any published security advisories