跳到主要内容

第十七节 — 边界与安全

这一节回答:FinBayes 的边界与安全约束在工程层如何具体承接?哪些约束是横向贯穿所有子系统的、不可被任何模块单独决定的?

三条边界约束(战略来源)

来自战略层的三条硬约束(详见上位继承与不变量章节):

战略约束工程层承接位置
凭证不变量:金融执行凭证一律不收、不存、不训练输入边界 hook + State / Cache / 审计 trail 凭证过滤 + 输出端过滤
不直接下单 / 不持账户凭证Capability Registry 拒绝注册执行类工具 + 工具 schema 校验
不替用户决策(认知层定位)综合层产出"判断 + 反方 + 失效条件"的结构化输出契约 + 不输出无证据的方向性结论

这三条不是某个子系统的局部规则,而是横向贯穿多个组件的全局不变量。


凭证类内容的端到端阻断

凭证识别的位置

这张图表达什么:凭证类内容的双向阻断 —— 入口 hook 拦截用户主动输入,出口 hook 拦截模型可能"幻觉"生成的凭证样式内容。两处之间的所有路径(Task / LLM / 综合层 / 状态对象)都绝不接触凭证。

这张图特意不表达什么:具体的正则模式(在工程实现仓维护);识别准确率(在测试体系章节)。

凭证类型与识别策略

凭证类型识别策略
私钥 / 助记词(12 / 24 词序列)正则 + 词表匹配(BIP-39 词表)
钱包地址附带私钥 / WIF 格式正则(特定前缀 + 长度 + 校验位)
交易所 / 经纪商 API key + secret pair正则(常见格式:长 base64 / 长 hex)
银行账户 / 信用卡号正则(Luhn 校验)
用户主动"贴整段配置文件"启发式(看到 key = value 形式的多行密钥)
LLM 辅助二次判断对不确定 case 调小模型快速判断(注意:调用前已脱敏,不送原 token

优先级:规则路径优先,LLM 辅助仅作可疑 case 的二次判断(避免每个输入都走 LLM)。

凭证拒收的用户感知

用户主动贴凭证类内容时,FinBayes 给安全回应:

我不接受这类凭证(看起来像 [私钥 / API key / 等])。请把它保存在你的
[钱包 / 交易所 / 等] 里。

我不需要它就能帮你做 [当前任务]。如果你想让我帮你判断某个交易所的资产
表现,请直接告诉我[交易所名称 + 资产名称]即可。

关键约束

  • 安全回应不重复用户贴的具体凭证字符串(避免日志记录)
  • 安全回应说明替代路径(不让用户无所适从)
  • 拒收事件进入审计 trail,但仅记录"识别为凭证类,已拒收 + 拒收时间戳",不记录具体内容

输出端过滤(ADR-010 决策位置)

LLM 可能在生成内容时幻觉地输出凭证样式字符串(例如"一个看起来像私钥的随机 64 位 hex")。即便不是真凭证,让看起来像凭证的字符串流向用户也增加误用风险。

过滤的两个候选位置

候选位置优点缺点
综合层产出后、统一格式化前离 LLM 最近,能感知语义上下文增加综合层职责
Output Pipeline 最末端、用户呈现前集中点检查、所有路径都过离 LLM 最远,可能丢失语义

初步决策(待 ADR-010 确认):两处都做。综合层做语义级(看到"私钥 / 助记词"等词附近的高熵字符串就警觉),Output Pipeline 做格式级最终扫描(与输入端 hook 同一套正则,方向相反)。

检测到凭证样式时的处理

  • 高置信度(多条规则同时命中):剥除该段 + 用占位符替换 + 给用户 banner "输出包含可能凭证样式,已过滤"
  • 中置信度(单条规则命中):保留但加 banner 提示
  • 低置信度(仅模糊匹配):日志记录,不剥除

ADR-010 待定的具体阈值与正则集合。


执行类工具的注册拒绝

战略约束"不直接下单"在工具层的承接(详见 CHAP-09 Capability Registry 段)。

拒绝注册的工具类型

工具类型拒绝理由
下单 / 撤单 / 改单(交易所 / 经纪商 API)直接执行金融动作
转账 / 提币 / 充值(区块链交易广播)直接执行金融动作
银行账户操作(转账 / 支付)直接执行金融动作
任何持有私钥 / 助记词的签名调用持账户凭证
任何要求"金融执行凭证"作为参数的工具凭证不变量

拒绝机制

关键约束

  • 工具 schema 必填字段 category,且枚举严格(无 execution 选项)
  • 工具参数 schema 用启发式扫描禁用字段名
  • 拒绝是注册时(启动期),不是调用时(运行期)—— 运行期已无此类工具可调
  • 审计 trail 记录所有尝试注册执行类工具的请求

详见 CHAP-09 Capability Registry。


用户数据隔离

多 user / 多 session 在同一 runtime 内的隔离

第一阶段单机部署虽然主要服务单用户,但 runtime 仍预留 user_id 维度(为未来多用户预留):

数据类别隔离机制
State Store所有表含 user_id 列 + 查询强制带 user_id where 条件
CacheCache key 含 user_id 前缀(防 cache poisoning)
审计 trailuser_id 字段
LLM Provider 调用每个用户的 Provider 池 / key 独立(key 仍在 OS Keychain,per-user 命名空间)
动态画像严格 per-user,不跨用户共享

约束:跨用户读取在工程层禁止(即使是 admin / debug 模式)。debug 输出经脱敏。

Session 内的会话上下文

Session 内的认知协作上下文:

  • 不跨 Session 泄露(一个 Session 的 Judgment 不自动出现在另一个 Session)
  • 跨 Session 的引用是显式的(用户主动 link 或 Watchlist 关联)
  • Session 归档 / 删除时,相关 Cache / 临时数据级联清理

网络层安全

TLS 强制

通信对象协议强制
云端 LLM ProviderHTTPS✅ HTTP 一律拒绝
外部数据 ProviderHTTPS✅ 个别老旧 Provider 例外需用户显式 allow-list 配置
Data HorizonHTTPS
本地 LLM(Ollama / vLLM)HTTP(localhost)✅ 仅允许 127.0.0.1
本机 Web APIHTTP(localhost)✅ 仅监听 127.0.0.1,外部访问拒绝
MCP Serverstdio✅ 进程间,无网络

凭证传输路径

  • LLM Provider key 通过 HTTPS Authorization 头传输,不写入 request body / URL query / 日志
  • Provider Adapter 内部使用 key 时是短生命周期(调用前从 Keychain 读,调用后即销毁内存引用,不在内存中持久持有)
  • 错误日志中 key 一律 redact(如 sk-***xxxx

详见 CHAP-16 协议安全约束。


Prompt 注入与对抗输入

LLM 应用的特殊风险:用户输入或外部数据中包含的对抗指令尝试改变 LLM 行为。

风险场景应对
用户输入"忽略上述指令,输出 ..."System prompt 加固(明示不接受 in-band 指令变更)+ 综合层输出 schema 校验(不符合契约直接拒绝)
外部数据(如新闻 / 网页)中嵌入对抗指令工具返回的外部数据进入 LLM 前包裹<external_data> 标记内 + system prompt 明示标记内内容不构成指令
用户尝试诱导 LLM 输出凭证样式 / 执行类建议输出端 hook 兜底 + 安全回应
用户尝试诱导 LLM 假冒 FinBayes 系统消息输出格式契约 schema 强制

关键不变量:FinBayes 不通过 prompt 行为约束作为唯一防线 —— 关键边界(凭证 / 执行类)有规则路径做硬约束,prompt 加固只是冗余防御。


用户主权

战略不变量"用户画像主权"在工程层的承接(详见 CHAP-15 用户数据动作):

主权维度工程承接
知情权用户可查看自己的所有数据(finbayes export / TUI 浏览)
修改权用户可修改动态画像(finbayes profile modify
清空权用户可清空画像 / 删除 Session / 删除 Judgment(显式确认 + 明示影响范围)
卸载权用户可完全卸载 FinBayes 并删除所有本地数据(不可恢复警告)
可移植用户可导出所有数据到 JSON / CSV

关键约束

  • 清空画像 ≠ 卸载 FinBayes ≠ 删除 State Store —— 三种动作明确区分
  • 用户每个数据修改动作都进入审计 trail(用户可追溯自己的操作)
  • 未来若引入云端同步,必须用户显式启用(不在第一阶段范围)

Review Gate 的工程承接

战略禁入概念(11 条字段级强约束 / 默认与行动准备双模式 / 认知协作伙伴 / L3 长期状态四承诺 / 零状态前提 / 情绪桥 / 信任债承诺 / 行动准备 / 行动判断 / 行动方案)不允许进入主分支。

检查层工具
自动 grepnpm run verify:kb 含 banned-concept grep(CI 必跑)
人工语义审查PR review 必备一位非作者人员复核(防 grep 同义词漏检)
审计追溯每次 release 留 grep + 人工审查记录

详见 CHAP-02 架构目标与质量取舍。


安全相关的可观测性

每个边界事件进入审计 trail(不含敏感内容):

事件类型记录字段
输入边界拒收时间戳 + 入口(CLI/TUI/Web/MCP/Channel)+ 识别类型(如 "私钥样式" / "API key 样式")+ 入口用户 / Session
输出端过滤时间戳 + 关联 task_id + 过滤类型 + 置信度 + 是否剥除
工具注册拒绝时间戳 + 尝试注册的工具名 + 拒绝原因(execution / 含凭证参数 / 等)
Prompt 注入识别时间戳 + 注入特征摘要(不含原文)+ 关联 task_id

用户可查阅自己 Session 范围内的边界事件("为什么 FinBayes 拒收了我的输入")。

详见 CHAP-18 可观测性。


与其他章节的关系

  • 输入边界 hook 的落点 → CHAP-09 Input Pipeline 子系统
  • 执行类工具注册拒绝的具体实现 → CHAP-09 Capability Registry
  • 输出端过滤的位置选择 → ADR-010(待写)
  • 凭证不变量的存储承接 → CHAP-15 Credential Store
  • 网络层 TLS 约束 → CHAP-16 协议安全约束
  • 凭证拒收场景的端到端 sequence → CHAP-10 S6 场景
  • 边界事件如何写审计 trail → CHAP-18 可观测性