Skip to content

安全

采纳原则:architecture.md。 安全评审与实现项:GitHub Issue #33#46

逸灵风设计为单人本地 / 内网部署:

  • 栖息地 RPC REST(/rpc/v1/*,health 探测 / CORS / echo 除外)需要 Service API TokenAuthorization: Bearer fa_at_…);用 anima token create 创建。绑定 127.0.0.1 可限制网络暴露,但不能替代 token 鉴权——任何能到达端口的本机进程,业务路由仍需有效 token。
  • 默认 bind 为 127.0.0.1;若需局域网访问,请自行评估 CORS 与网络隔离。
  • 禁止在无 TLS、无 token 保护客户端的情况下把服务暴露到公网(见 remote-access.md)。可选 http.tls.mode: acme(Let’s Encrypt HTTP-01,公网 :80 challenge + :2659 HTTPS)仍须 Token;不替代防火墙 / 反向代理加固。
规则说明
唯一权威存储Vault(User + Agent 库中的 ECS vault_item);遗留 pass(~/.password-store)迁移后磁盘只读——运行时不再使用 pass CLI
带版本更新实质性 vault 条目更新最多保留 10 份历史快照(entities.revisions);经壳 /vault 历史恢复。见 entity-revisions
永不提交密钥勿把 API 密钥、token、数据库密码写入 git。引导 config.yaml:用 env()(或把密钥放在文件外)。运行时 LLM/MCP 设置在 PG——在那里用 vault() / env()
运行时目录~/.anima/(可用 FREEANIMA_HOME 覆盖)存放配置、可选 Agent vault 缓存vault/agent-machine.key)、对话、记忆——建议 chmod 700。Agent 根密钥 SSOT 在 User vault(PG),不是家目录持久密钥。
用户主密码仅在壳 /vault、内嵌聊天室解锁,或浏览器形态入口内 Vault 解锁;永不作为聊天消息发送或存入 PG messages
聊天室 User vault 解锁仅 v1 内嵌聊天室packages/frontend/portal/app/web / desktop / mobile);Discord / 微信 Gateway 不能解锁 User 库
浏览器扩展浏览器形态入口(packages/frontend/portal/extension;展示名 FreeAnima;Firefox gecko extension@freeanima.com);Service API Token 存 chrome.storage.local;主密码仅扩展内存(最多 8h 绝对超时;浏览器关闭清 session);RPC 走 background host_permissions。见 portal.mdvault.md

config.yaml 仅作引导(PostgreSQL 起来之前读取)。其中的密钥支持明文或 env("KEY")——不是 vault()(Vault 条目在 PG)。栖息地连通后,PG 中的运行时配置可用 vault("item_id", "field")env("KEY")。需要 CLI 凭证的 Agent 工具在 terminal_run / code_execute 上按次传入 secrets[](仅子进程 env)。浏览器表单字段用 browser_typesecret(键入页面;永不在工具结果中回显)。User 库解析仍要求客户端有已解锁的聊天室会话。

User 库Agent 库
栖息地 PG密文 + verifier;可持有 Agent 根密钥 SSOT 条目仅密文;根密钥不以 PG 明文存储
磁盘解锁后可重建的缓存 vault/agent-machine.keyprovision / lock)
LLM仅元数据;子进程 secrets[] / browser_type secret仅元数据;子进程 secrets[] / browser_type secret
客户端主密钥在内存仅缓存解锁时由栖息地解密
路径内容加密
PostgreSQL对话 / 记忆 / Vault 密文无应用层加密;User vault 在主密码下持有 Agent 根密钥 SSOT
~/.anima/vault/agent-machine.keyAgent vault 缓存(非 SSOT)文件权限(chmod 600);经数据维护解锁重建
~/.anima/weixin/微信同步状态

实例备份集: PostgreSQL(必需)+ FREEANIMA_HOME(引导/config.yaml/TLS/weixin,按需)。Agent 根密钥在主密码解锁后从 User vault 恢复——缓存文件可选。已解锁缓存的磁盘备份 = 数据可达;请保护备份介质。无栖息地缓存解锁时,Agent 注入(cron / 工具 / vault())失败。

能力风险
terminal_run默认 shell: false(argv spawn)。显式 shell: true 启用管道/重定向。可选 secrets[] 把 Vault 解密到仅该子进程 env(非栖息地 process.env)。对灾难性目标常开硬拒绝——不是 OS 沙箱;仍可能经 code_execute / 解释器绕过
file_read / file_write / file_delete / file_search路径拒绝:/etc/proc/sys、危险 /dev~/.ssh 私钥、FREEANIMA_HOME/vault。启发式拒绝 ≠ 可写根沙箱
code_execute无 shell(Bun/Node argv)。可选 secrets[]terminal_run。任意 JS 仍可用 node:fs——不是容器沙箱
browser_type可选 secret 解密一个 Vault 字段并键入页面;工具结果把 typed 打码为 ***(永不明文)
MCP 工具能力完全由外部 Server 决定;默认 stdio,SSE 鉴权方案未完全定义
能力策略硬工具约束:技能 allowed_tools + 调用方(cron/记忆维护/subagent)可选 allow/deny;deny 覆盖 allow;不是 Mask 预设衣橱。数据 allow/deny 预留。见 skills.mdarchitecture.md 能力策略、subagent.md
vault_list / vault_search / vault_get_meta仅 Vault 元数据;无密钥值。仅栖息地(非 MCP)
vault_create / vault_update / vault_delete仅栖息地(非 MCP)。create/update 仅向 Agent 库密封明文;工具结果仅元数据。User 库写入留在 Vault UI

需要栖息地 Agent 缓存已解锁(数据维护 → 解锁 Agent vault;从 User vault SSOT 播种)。否则解密/密封抛 AGENT_VAULT_LOCKED

  1. 发现vault_list / vault_search / vault_get_meta(仅元数据;工具结果永不含明文)。
  2. 写入(Agent 库) — 仅在栖息地聊天中用 vault_create / vault_update / vault_delete。create/update 接受明文 secrets 在栖息地密封;结果仅返回元数据。User 库:Vault UI。(整个 vault ToolSet 不经 MCP 暴露。)
  3. 使用 — 在需要凭证的同一次 terminal_runcode_execute 调用上传入 secrets: [{ id, env_name, field?, subject_kind? }](如 GH_TOKENgh);或在 browser_type 上用 secret: { id, field } 填表单。对 field: "totp",解析值为当前 TOTP 码(RFC 6238),不是存储的 Base32 密钥。
  4. 作用域 — 明文仅为本调用解密(secrets[] → 子进程 envbrowser_type secret → Camofox 键入载荷)。写入栖息地 process.env出现在工具结果。默认 shell=false:用 argv 形式(printenv GH_TOKENgh …),不要 echo $VAR
措施说明
同源 RPCTanStack Start server functions 默认同源,无需 CORS 白名单
配置 API 密钥栖息地 config GET 以明文返回密钥(api_key、MCP env / headers 等)。写回时遗留 "***"restoreMaskedSecrets 恢复
MCP 配置sanitizeConfigForApi 保留 MCP env / headers 明文,便于栖息地 MCP 页来回编辑
文件路径策略file_* 工具共用 path-policy/etc、vault、ssh 私钥、/proc//sys、阻断设备
终端 shell 默认关闭terminal_run 默认 shell=false;仅在需要管道/重定向时传 shell=true(摩擦,非沙箱)
终端命令硬拒绝常开灾难性命令策略(terminal-command-policy);不能用 env 关闭
Slash 命令白名单路由;每条命令须产生用户可见反馈;长命令先立即 ack 再给最终结果
MCP 默认 stdio降低端口暴露
Vault 隔离LLM 只见 vault 条目元数据,不见解密字段
Service API Token栖息地 RPC REST /rpc/v1/* 须 Bearer fa_at_…service_api_tokens.authorization jsonb;full 或 portal/modules/data 细粒度)。health/CORS/echo 豁免。管理 tokens.*full。见 remote-access.md
CI 密钥扫描.github/workflows/security.yml(Gitleaks);GitHub Secret scanning + Push protection(公开仓库免费)
.gitignore.env.*config.yaml、私钥后缀

已知缺口(文档 ≠ 已完全实现)

Section titled “已知缺口(文档 ≠ 已完全实现)”

以下在代码或文档中规划,部署者请勿假设已实现

优先级状态
P0file_* 路径拒绝(/etc/、vault、ssh、…)已实现path-policy
P0terminal_run 默认 shell=false已实现
P0终端灾难性命令硬拒绝已实现(启发式;≠ 沙箱)
P0code_execute 无 shell已实现(JS FS 仍开放)
P1运行时 Unix socket chmod 600 + 握手 token未实现
P1FREEANIMA_WRITE_SAFE_ROOT / READ_SAFE_ROOT未实现
P2(退役)配置 API 字段脱敏维护已放弃——密钥不脱敏(含 MCP env/headers)
P3IPC / LLM 限流
P3会话磁盘加密
代号名称说明
A外部攻击未授权访问、端口暴露
BLLM 层注入提示注入、工具参数操纵、命令注入
CAgent 误操作误发危险操作
D依赖链第三方库 / MCP 被攻陷
E数据安全对话泄漏、密钥泄漏、记忆篡改
模块A 外部B LLM 注入C Agent 误操作D 依赖E 数据
运行时默认 127.0.0.1 bindMaxLoopIterationsExceeded缺口:限流llm 客户端漏洞PG 未加密
GatewayToken 在 Vault / env恶意消息回复含敏感信息SDK 漏洞
CLI / 工具本机 shell 被控路径拒绝 + 终端硬拒绝(可经 code_execute 绕过)降低灾难性 rm日志可能含对话
HTTP / 栖息地service_api_tokens Bearer token(所有来源,含 loopback)BFF 不直接碰 LLM 参数配置展示Vue/axiosSSE 明文
MCPSSE 鉴权未定义恶意参数错误工具调用Server 被攻陷上下文可能含敏感数据
VaultAgent machine key 文件权限仅元数据工具;按次 secrets[] / browser_type secret错误条目 / env_nameWeb Crypto用户主密码永不进 PG messages
  • 读/写/删/搜拒绝:/etc//proc/~/.ssh/ 私钥、FREEANIMA_HOME 下 vault
  • 可选 FREEANIMA_READ_SAFE_ROOT 仍为 P1

P0 — Shell 执行 + 命令硬拒绝(已落地)

Section titled “P0 — Shell 执行 + 命令硬拒绝(已落地)”
  • terminal_run 默认 shell=false;仅在需要管道/重定向时传 shell=true(非沙箱)
  • 常开拒绝:灾难性 rm/rmdirmkfs*dd of=/dev/…、fork bomb、电源命令、对 /$HOME 的递归 chmod/chown、对系统/家目录根的破坏性 find
  • code_execute 仍为仅 argv(无 shell);不是进程沙箱
  • Unix socket chmod 600 + 可选握手 token
  • 写安全根默认 cwd(FREEANIMA_WRITE_SAFE_ROOT
  • 新增密钥字段时,同步平台中的配置消毒逻辑
  1. 复制 config.example.yaml~/.anima/config.yaml;引导密钥用 env()——不要在配置里写明文密钥;vault() 供栖息地起来后的 PG 运行时配置
  2. 打开壳 /vault;设置 User 主密码;按需从遗留 pass 迁移密钥
  3. chmod 700 ~/.anima(含可选 vault/agent-machine.key 缓存)
  4. 仅 bind 127.0.0.1,或确保内网隔离
  5. 在栖息地 UI(/habitat/mcp)审查入站 MCP;对不信任的外部 Server 设 enabled: false
  6. 定期备份 ~/.anima/(若保留则含遗留 ~/.password-store);备份介质加密存储
  7. 勿将 .envconfig.yaml 提交到 git
  8. 除非确需管道/重定向,否则不要在 terminal_run 上传 shell=true