Repository navigation
fix(public-safety): reject unlabeled OpenAI and Anthropic keys - #7814
huangruiteng merged 1 commit into
Conversation
Signed-off-by: Lihua <1017343802@qq.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent — gpt-6.1-sol / OpenAI; runtime_reported; reasoning_effort=max.
动机 / Motivation
维护者把含有未标注供应商密钥的文本导出为公开页面、源码或聊天详情时,会经过本次修改的扫描链路。 旧版本把四类长密钥形状当作普通文本放行,静态打包会写出文件;当前版本在写出前拒绝,短文档示例继续可用。 真实 CLI 与静态打包对照确认了新增拒绝、短示例放行,以及修正文本后成功生成并读回产物。 范围仅为现有文本发布边界补齐四类形状,不验证线上密钥真伪,不新增发送权限、页面或配置。
改动思路 / Approach
供应商形状集中在已有 owner,源码预筛选只补充候选字面量;继续复用既有表面策略,既能阻断真实写出,又避免新增状态或第二套扫描器。 当前边界是四类文本形状、候选预筛选和既有消费者的拒绝及恢复;不新增线上凭证校验、发送流程、持久协议或 UI。
入口仍是调用方明确提供的文本或扫描路径:presentation 消费公共模式集合;源码 check 先做候选字面量预筛选,再由同一个正则与既有引用策略判定。静态站点在写入目的目录前扫描所有选中文件,管理详情在已有递归投影中省略敏感文本。没有新增 provider 请求、持久状态或第二个权限 owner。正向路径是短示例或已修正内容正常发布;反向路径是长形状被拒绝,修正后沿同一入口继续。
已经独立比较不可变基线 789694fa42972db17acd47aa2604b1907060028d 与当前 head 64524d390f5ba75d686e528fb877143aa40b4dc4;下表只呈现本次实际观察,并非供应商格式认证。
| 同一组合成输入 | 基线 | 当前 head |
|---|---|---|
| 18 个新增长形状,含大小写、Unicode casefold、内部 placeholder 单词 | 公开扫描及打包放行 | 真实 CLI 拒绝,打包不产生目的目录 |
| 11 个短示例、未知前缀及普通文本控制 | 放行 | 完整规范化返回内容相等 |
| 3 个原有供应商拒绝控制 | 拒绝 | 完整规范化返回内容相等 |
| 修正内容后生成及再次请求 | 成功且重复请求不重复写入 | 读回字节一致,semantic no-op,日志仅一行 |
具体改动 / Changes
规格依据:issue #7799,正文快照 sha256:7fa6b7b8b8b99967a8aa6382fe836a54af20190f6aad12beda5dafd0e1d9bbd4,更新时间 2026-11-01T09:36:08Z。原 issue 没有逐项编号,以下标签只用于映射其已有要求:ISSUE7799-ISSUER 对应四类未标注长形状拒绝;ISSUE7799-EXAMPLES 对应短示例及普通文本兼容;ISSUE7799-CONSUMERS 对应既有发布消费者拒绝或脱敏;ISSUE7799-OWNER 对应复用共有来源并保留调用方策略。四项均已实现并由下述路径覆盖,没有将线上密钥有效性扩充为本次要求。
完整 diff 为五个文件 +35/-1,生产代码只增加六行:两条模式分支覆盖四类前缀,四个候选字面量避免源码扫描预筛选遗漏。其余修改保留在三个既有测试模块,补充形状、包含 placeholder 单词的 opaque body、短示例和打包拒绝用例,并更正短示例测试的过时名称。
关键代码讲解
PROVIDER_TOKEN_SHAPE_PATTERN_SOURCE继续集中拥有供应商形状。四个已知前缀后要求至少 20 个允许字符,按既有消费者的大小写策略应用;没有改成匹配任何sk子串。scan_public_boundary_text仍把公共模式命中转换为ok=false和不含原值的provider token警告,Dash、打包和 manager gate 共用该结果。scan_public_boundary保留显式选路径、私有祖先拒绝、候选预筛选、正则分类及引用处理顺序。新增字面量仅是必要候选条件;内部含 example 等字样不会把未标注 opaque token 豁免成安全示例。package_static_site的现有扫描顺序使 notes 文件中的命中在输出前失败。独立调用真实 packager 验证目的目录不存在,并在修正后读取实际输出及 manifest、再次请求验证幂等。_safe_context沿已有嵌套结构处理文本,新覆盖形状变成敏感文本占位;没有新增保存原值或发送消息的路径。public manager result 的既有调用链也已读码并由相关隔离测试覆盖。
本次独立验证
- PASS:七个相关测试模块 373 项,以及两个 activity 模块 41 项;这些是本次执行结果,不是复述作者计数。
- PASS:同一脚本及相同 fixture 在两版各跑 32 个案例、37 次真实
checkCLI,共 74 次;14 个未改变案例比较完整规范化载荷。只归一物理临时路径与生成时间,诊断、输出内容、状态及语义摘要均保留;私有路径诊断另统一绝对路径的显示形式。 - PASS:显式选中文件、同目录未选邻居、目录中新文件、dotdot 私有祖先逃逸及修正恢复五类范围反例。新增目录成员按调用方明确选择的目录范围扫描,不从 Goal 激活推导权限。
- PASS:真实静态打包拒绝前无输出;修正后的入口字节读回正确,重复请求不重复写入。Dash 命令体的既有显式
--no-boundary-scan分支在两版完整载荷及写出摘要相同,默认扫描的新增拒绝是有意变化。 - PASS:五个改动文件 Ruff、配置内 mypy 的 17 个源文件、编译/DCO/diff 检查、标准 premerge 六项直接检查及九项所选 canary。diff 语义探针未发现支持范围内的新词汇载体,完整 semantic drift canary 也通过;探针不覆盖动态语义推导。
- PASS:五个改动文件公共边界扫描零错误;保留四个非字面量凭证引用警告及一次空隔离 runtime 提示,没有把警告写成零。
- UNVERIFIED:远端 CI 按当前策略未获取、轮询或等待;不据此宣称 CI 通过,也不推断失败原因。
对主干的风险 / Risks
最强回归风险是两处契约脱节:只有 presentation 正则通过而源码候选预筛选仍漏掉,或扩大到泛化 sk 匹配使短文档示例无法使用。真实 CLI、打包无输出断言与短示例完整返回比较分别覆盖这两种方向;18 个基线漏检也是明确的旧缺陷对照,不是只在新 helper 上自证。
20 字符门槛属于保守形状策略:很长的虚构已知前缀示例可能被拦截,短形状、未知发行方或分隔形式并不由此规则穷尽。这不证明密钥由供应商颁发或仍有效。既有较宽的内部文本分类和小写 activity 遮罩原先已能拦截许多案例;本次不能把它们全部算作新修复。新增 source owner 同时令大写 activity 形状被遮罩、outbound 增加不含原值的 provider 命中,已在两版观察中明确保留。
CLI 与静态打包走真实文件系统;Dash 命令体的上游 projection/render 使用合成输入,服务方法使用合成响应 sink,manager roundtrip 使用隔离 fixture。因此这里证明的是现有发布边界与恢复,未冒称真实 HTTP、线上发送、浏览器视觉或安装后旅程。没有新增协议名称、actor 生命周期或授权语义;拒绝是机器执行的发布约束,不能称为建议。
语义与 CI 对齐
本次复用现有词汇及 typed 输出,不把文本启发式用于 Goal/Todo 状态判定;供应商前缀留在资源检测 owner,通用错误仍保持领域无关。默认显式发布扫描由放行变为拒绝的四类形状已在 PR 标题、正文、测试命名及此处披露,没有新增 opt-in/default-off 声明。已有 Dash 显式绕过开关的兼容性已实测,批准不扩大其权限。
当前目标 main 已前进到 b000bf3;与不可变基线比较,相关扫描 owner、消费者、测试及依赖没有变化。未改生产源码,未替作者处理无关历史问题;合并资格及授权仍是独立步骤。
我的整体评价 / Verdict
APPROVE,未发现本次 exact head 的阻塞项。issue 的有限发布安全目标已经通过实际拒绝与修正后产物读回实现;采用已有 owner、保持调用方策略,比建立另一套 scanner 更合适。保留现有结构是有证据的简化选择,无需在本 PR 合并更宽的文本分类策略或新增跟踪任务。
long_horizon 判定为 preserved:修正后能继续形成有用产物,重复请求没有重复效果;没有据此宣称团队长程效率或成本收益。user_experience 判定为 improved:已有发布操作获得真实拒绝及恢复,不增加配置或确认轮次。已检查 public_safety、static_site、dash_server 和 manager detail 的现有调用;本次没有页面布局或首屏控件改动,因此不需要新增视觉截图。 未验证已安装 App、真实 HTTP 服务、跨渠道消息发送或线上供应商凭证;打包探针的视觉检查标记是合成输入,不是视觉验收。
English verdict: APPROVE — head 64524d3; the four issuer families fail closed with short-example and recovery compatibility verified by paired real CLI/package checks, 414 focused tests and native validation; remote CI was not consulted.
Goal And Delivered Outcome
Unlabeled OpenAI and Anthropic keys passed the shared presentation publication gate in #7799. Extend the existing provider-token owner for
sk-proj-,sk-svcacct-,sk-admin-andsk-ant-, and update the repository-publication prefilter so it actually examines those issuer families.Closes #7799. Target:
loopx-project/loopx:main, based on789694fa42972db17acd47aa2604b1907060028d.Author Declaration
checkCLI cases, including bodies containing placeholder wordsScope And Continuation
The existing
public_safe_textowner remains responsible for issuer shapes; the contract scanner keeps its existing prefilter and reference policy. The 20-character body floor follows the neighboring provider-shape convention; this is a conservative text-publication gate, not issuer-side key validity or an online credential check.Compared the maintained MIT-licensed Gitleaks OpenAI and Anthropic rules. Their exact issuer-format validation is useful design evidence; this existing publication gate retains its bounded prefix policy. No external source code or new dependency was copied.
Bounded refactoring: kept the shared owner and its actual prefilter in agreement, and corrected the obsolete test name that called the short example an unclaimed issuer. Broader classifier consolidation remains outside this defect.
Validation
Tested revision:
64524d390f5ba75d686e528fb877143aa40b4dc4.Frontend / Visual Evidence
No graphical first-screen change. The existing static publication journey's rejection and absence of output are exercised through the real packager.
Every commit is DCO signed. No private state, live credentials, raw logs or generated artifacts are included.