# 规则:安全与可靠性 —— 可信边界、故障路径、可观测 > **类型**:硬约束(rules) · **状态**:生效 2026-06-19 · **门禁**:现有测试/契约/边界门禁 + 代码评审兜底 > **上位**:[`verification-and-anti-false-green.md`](verification-and-anti-false-green.md)、[`engineering-conventions.md`](engineering-conventions.md) > **来源**:蒸馏 `docs/dev-baseline/global/05-安全开发规范.md`、`06-日志与可观测性规范.md`,并吸收项目当前“真实后端/真实 PG/外部依赖 fail-closed”经验。 --- ## 一、可信边界 - 认证、授权、租户隔离、数据归属校验必须在后端可信边界执行;前端隐藏按钮或本地状态不算安全控制。 - `/admin-api/**` 与 `/app-api/**` 必须保持调用身份隔离;管理员能力不得经 app API 暴露,普通用户能力不得依赖 admin 端兜底。 - 查询和写入必须带可信的 `tenant_id` / `user_id` / owner 条件;不得信任前端传来的 owner、tenant 或权限声明。 - AI runtime 不得自授权。授权事实必须来自授权/权限端口或已验证的快照,运行时只能消费;当前由 `AiGrantRuntimeBoundaryArchTest` 守住 runtime/任务执行侧不得直接依赖 `ToolGrant` 写模型,完整 grant/runtime 物理包拆分另行推进。 --- ## 二、输入、文件与数据保护 - 所有外部输入必须校验:HTTP 请求、文件上传、SSE/WebSocket 消息、异步事件、外部回调都算外部输入。 - 优先使用框架校验与结构化解析;禁止用字符串拼接 SQL,禁止用正则/字符串切割代替可靠 parser。 - 文件路径、文件类型、文件大小、内容签名/格式都要校验;只看扩展名不够。写文件必须考虑部分写入、清理和路径穿越。 - 密码、token、API key、PG 密码、临时签名、授权快照不得写入代码、提交记录、日志、响应或错误信息。 - 用户隐私字段必须脱敏后展示或记录;完整手机号、邮箱、证件号、银行卡号不得进入普通日志。 --- ## 三、外部依赖与异步可靠性 - 涉及外部服务、模型调用、对象存储、支付、通知、消息队列、异步任务时,必须设计超时、失败、重试、幂等、补偿和审计路径。 - 外部依赖未配置时必须 fail-closed:拒绝执行并给出可追踪错误,不得静默降级成假成功。 - 写路径必须有幂等键或命令记录;重试不得重复扣费、重复发放权益、重复创建投影或重复发送不可撤销通知。 - 异步投影必须有源事件、处理状态、重放或补偿策略;只写一侧而无法读回的设计不得声称端到端完成。 - 事务边界必须明确:跨 BC 写入优先通过端口/事件/投影,不得用跨域 DAL 拼接一个大事务。 ### 三.A 跨域资产物化(market 安装下游物化特有红线) > 由来:market KB 物化 D0-fork(见 [`../knowledge/market-install-downstream-materialization.md`](../knowledge/market-install-downstream-materialization.md))。把市场资产物化成下游可用实体时,以下三条是会导致**静默失效**或**私有泄露**的具体红线,是 §一/§三 通用原则在本场景的硬化,不得重蹈。 - **本地实体的本地键不得存外域 id**:把市场资产物化成本地实体时,本地表的主键/外键(如知识库绑定的 `kb_id`)必须落**本地新建/复用的主键**,绝不能把市场资产 id 直接当本地主键写入。否则后续按本地键的查询永远落空,且表现为"无报错的静默省略"(检索 `no_dataset`),极难排查。外域 id 只能存进专门的来源引用列(如 `source_market_asset_id`)。 - **跨可见性隔离必须靠物理隔离,不得依赖运行时过滤字段**:当一份数据源同时含公开与私有内容、且生命周期不冻结(发布后仍可加私有内容)时,隔离必须靠**物理分离出只含公开快照的副本**让消费方只读副本,不得依赖外部运行时的 metadata/过滤参数做隔离——这类参数可能字段名错配被静默忽略(RAGFlow `metadata_filter` vs `metadata_condition` 即是,见外部依赖坑),一旦失效就是私有泄露。隔离是安全边界,不能押在一个"可能不生效"的外部入参上。 - **物化前置依赖未就绪必须 fail-closed**:物化依赖的下游副本/资源处于中间态(如 fork 的 pending/partial/failed)时,必须拒绝建立绑定并给可追踪错误,绝不建出"绑了但用不了"的迷惑态实体(这是 §三"未就绪不得静默降级成假成功"在物化场景的落点)。 --- ## 四、日志、审计与追踪 - 关键业务状态变更、管理员操作、安全敏感操作、外部调用必须留下可追踪记录:who、what、when、where、result、commandId/traceId。 - ERROR 日志必须包含异常堆栈和足够定位的上下文;WARN 用于可恢复异常、降级、重试;INFO 记录关键业务事件;DEBUG 只用于开发诊断。 - 日志禁止输出大段正文、完整 prompt、完整 token、完整密钥、完整隐私字段。AI prompt 只记录模型、token 数、任务 ID、摘要性上下文。 - 前端请求应携带请求 ID 或等价关联信息;SSE/长连接需有 connectionId 关联事件流。 - 审计日志不得被业务普通删除路径修改或清除;敏感操作需要记录变更前后关键值或可重建来源。 --- ## 五、故障处理与回滚 - 发现安全漏洞、数据错写、权限绕过、外部依赖异常时,先止血并保留证据,再修复;不得用“刷新缓存/重跑脚本”掩盖根因。 - 不可简单回滚的动作(删数据、发通知、扣费、授权发放、第三方永久写入)必须有人类确认、备份或补偿方案。 - 数据迁移必须可验证:迁移前后行数/关键约束/抽样数据有证据;大批量迁移要分批、可中断、可恢复。 - 配置变更应可独立回滚;敏感配置只通过仓库外环境或密钥系统注入。 --- ## 六、机械门禁与人工评审边界 | 约束 | 机械落点 | |---|---| | 跨 BC 不直连他域实现 / DAL | `BcBoundaryArchTest` | | AI runtime 不得自授权 / 不得直连 Tool Grant 写模型 | `AiGrantRuntimeBoundaryArchTest` | | API/DB 契约与迁移卫生 | `ContractFirstGateTest` + `openapi-diff` | | completed 必须有测试证据 | `P1rApiCoverageReportTest` | | 真实 PG / 外部依赖 fail-closed 证据 | `P1r*IT` 与总账证据 | | 跨域物化:私有不泄露 + forkStatus fail-closed | `P1rMarketKbForkMaterializationIT`(真 PG + 真 RAGFlow 证私有探针不泄露 + AFTER_COMMIT 时序);kb_id 去污染目前由该 IT + 代码评审兜底,无独立 ArchUnit | | `.agents` 规则索引 | `AgentsInfraIntegrityTest` | 目前尚无全量静态密钥扫描、SAST、依赖漏洞扫描门禁。涉及密钥、权限、支付、对象存储、模型调用、通知、生产数据迁移的变更,在补机械门禁前必须作为人工评审高风险项处理。