GitHub 的密钥检测模型将扫描速度提升 86%
GitHub’s model for secret detection: Finding more secrets with less noise
GitHub 部署了由正则候选生成和微调 ModernBERT 分类器组成的两阶段密钥扫描流程,将通用密钥检测扩展到 push protection。与此前的 LLM 流程相比,post-push 扫描中位执行时间降低 86%,服务成本降低超过 98%,仓库所有者加权的告警接受率提升 11.5%。
GitHub展示了将规则扫描与小型分类模型结合的实践,并用线上指标说明其在降低误报、延迟和服务成本上的收益。
我们的流水线与此前的 LLM 流水线对比
更智能的机密扫描,成本仅为原来的一小部分
11.5%
更高的接受率
按负责人加权的告警精确率
86%
更低的扫描执行时间中位数
推送后扫描
98%
更低的服务成本
小型模型与远程 LLM 调用对比
开发者对扫描结果有信心时,机密扫描效果最佳。检测过少,真实凭据可能留在代码库中;告警过多,开发者可能会花时间调查并非机密的字符串。
通用机密尤其难以把握这一平衡。同一个字符串可能是真实凭据,也可能是文档中的占位符,因此检测时需要理解周围的代码和文本。
为应对这一挑战,我们专门针对 GitHub 的产品需求训练了一个机密分类器:既能区分真实凭据与相似字符串,又能满足大规模扫描所需的速度和效率要求。
在配套文章 机密保护必须跟上软件发展步伐 中,我们解释了为什么机密保护必须跟上 AI 加速开发的步伐。在这里,我们将深入介绍为实现这一目标而提供支持的上下文感知分类器:我们如何设计、训练和评估它,从而以更少的噪声发现更多真实机密。
我们实现了什么
GitHub 机密扫描在两个关键时刻运行:
- 推送保护会在接受推送之前扫描变更,帮助防止机密进入代码库,让开发者有机会处理检测结果。
- 推送后扫描会在代码提交后运行,持续扫描代码库内容,并在检测到潜在机密时创建告警,以便开发者和安全团队调查并修复问题。
我们开发了一款快速分类器,与此前基于 LLM 的流水线相比,它将推送后扫描的执行时间中位数缩短了 86%。这一效率让我们得以将通用机密检测扩展到推送保护,在开发者推送变更之前而非仅在代码提交之后返回结果。
为什么机密难以检测
结构化凭据通常具有鲜明的前缀、长度、字符集或校验和。通用机密则可能没有这些特征。它们的语法与构建标识符、校验和、资源哈希、示例值及其他非敏感字符串相重叠。上下文才是决定性信号。
| 很可能是真实凭据 | 很可能是无害的相似字符串 |
|---|---|
| 与生产数据库 URL 并列赋值的密码 | 测试样例中的同一密码格式值 |
| 部署配置中的连接字符串 | 设置指南中的 localhost 连接字符串 |
| 与 API 凭据关联的高熵值 | 高熵校验和、构建 ID 或资源哈希 |
这些情况属于难以排除的误报:字符串符合凭据模式,但并非可用的凭据。添加更多规则可以抑制其中一部分误报,但每个例外都可能导致真实机密被隐藏。学习型分类器则可以利用文件路径、机密类型、变量名称以及附近的代码或文本等信号。
因此,我们发布了一个采用两阶段流水线的新扫描器:
- 候选项生成:正则表达式过滤器会扫描内容,以较高召回率寻找潜在机密。此阶段经过优化,可快速、确定性地捕获范围广泛的凭据类模式。
- 上下文感知分类:经过微调的 ModernBERT 分类器会评估每个候选项及其周围的上下文。它经过训练,能够识别出区分真实机密与误报的信号,包括占位值、示例、文档片段、生成内容和非敏感标识符。由于该模型体积小且能够在我们的推理基础设施上高效运行,其服务成本远低于基于 LLM 的流水线,扩展起来也更加简单。
影响:
- 用户接受度提高 11.5%,误报减少。
- 推送后机密检测执行时间缩短 86%。
- 与基于 LLM 的流水线相比,成本节省超过 98%。
我们的流水线工作方式
在扫描内容时,正则表达式模式会广泛匹配并标记任何看起来像凭据的内容,确保一开始不会漏掉真实机密。随后,每个候选项都会交由经过微调的 ModernBERT 分类器处理,该分类器会结合值本身、文件路径、变量名及其周围代码进行分析。分类器会估算其为真实机密的可能性。高置信度的发现会转化为警报,而占位符、测试固件和校验和等相似内容则会在触达开发者之前被过滤掉。
我们的流水线工作方式
先广泛扫描,再谨慎判断
第 1 步
扫描
代码仓库内容、提交、拉取请求以及其他扫描对象。
第 2 步
生成候选项
正则表达式模式会识别可能的令牌、密钥和类似凭据的字符串。
第 3 步
分类
经过微调的 ModernBERT 会评估候选项 + 上下文,并分配其为真实机密的可能性。
第 4 步
发出警报或抑制
高置信度的发现会继续处理;可能的误报则会被过滤。
重要的设计选择在于,模型并不会取代确定性扫描,而是对其进行补充。正则表达式仍然是快速查找候选字符串的合适工具。分类器则用于机器学习最能发挥作用的地方:区分“看起来像机密”和“很可能是真实机密”。
一个困难负样本问题:几乎看起来真实的机密
大多数误报并非随机产生,而是困难负样本:这些字符串符合凭据模式,却不是可用的凭据。例如文档中的占位符、测试中的简单示例、经过编辑的值、非敏感 ID 以及生成的测试固件。这些情况很容易被正则表达式匹配,而纯规则系统很难在不意外漏掉真实机密的情况下将其抑制。
ModernBERT 能够发挥作用,是因为它可以将候选项与附近的代码和文本一同读取,从而提供可与 LLM 相媲美的上下文理解,同时避免生成自然语言输出所带来的延迟和计算开销。例如,周围带有“example”“dummy”“fake”或“replace-me”等词的候选项,其风险可能低于部署文件中被分配给环境变量的候选项。分类器会从带标签的示例中学习这些上下文差异,而不要求工程师将每个例外都编码成另一条规则。
我们选择 ModernBERT,是因为它非常适合这一工作负载:体积小、效率高,并且非常适合对代码相关文本进行分类。对于机密扫描而言,模型需要在高吞吐量和低延迟的条件下,针对较短的候选窗口做出校准后的判断。
这使得经过微调的编码器分类器在流水线的这一阶段比通用 LLM 更适合作为部署形态。模型可以直接针对我们的决策边界进行训练,并使用对机密扫描质量至关重要的召回率和精确率指标进行评估。
我们的训练方式
挑战在于,为语法本身具有误导性的情况找到具有代表性的数据。训练和评估策略结合了三个来源:
- 来自 GitHub 仓库的产品衍生示例,使用机密检测体验中的反馈以及额外的人工验证。
- 来自 GitHub 仓库数据的高召回率正则表达式候选项,包括人工标注示例和用于扩大覆盖范围的弱标签。
- 针对稀疏且困难案例的合成示例,例如文档中的机密、测试固件、公钥、校验和、结构化相似项以及近似匹配对。
合成行在纳入之前会通过确定性验证和基于模型的质量审查。训练重点关注真实机密、逼真的误报,以及经常使仅依赖正则表达式的方法产生混淆的困难负例。每个模型输入都包括候选值、文件路径、机密类型以及有界数量的周边上下文。我们通过离线评估选择阈值,然后在更广泛发布前,使用类似生产环境的流量验证行为。
在拆分数据之前,我们将共享同一仓库、候选值或示例的行分组,以避免近似重复项同时出现在训练集和评估集中。
训练重点关注对告警质量最重要的案例:真实机密、逼真的误报,以及正则表达式经常匹配到的困难负例。输入表示包括候选机密字符串、文件路径、类型以及有界数量的周边上下文。输出是一个分类分数,扫描器据此决定是否应继续处理该候选项。
我们针对产品权衡进行了优化:在保持或提升召回率的同时,降低误报率和服务成本。实际上,这意味着使用离线评估来选择分类器阈值,然后在发布前根据类似生产环境的流量进行验证。
最重要的训练原则是让模型看到容易混淆的示例。我们纳入了在语法上类似真实机密、但语义上不同的候选项,使模型不仅学习机密是什么样子,也学习误报在上下文中是什么样子。
训练好的模型以 ONNX 格式导出,并采用 8 位量化,从而实现快速推理。
评估结果
| 线上结果 | 相比之前的 LLM 流水线的变化 | 衡量内容 |
|---|---|---|
| 按仓库所有者加权的接受率 | 提高 11.5% | 客户对检测结果的接受度 |
| 推送后的扫描执行时间中位数 | 降低 86% | 生产环境中的扫描执行时间 |
| 服务成本 | 降低超过 98% | 紧凑型分类器与远程 LLM 调用相比的成本 |
我们分两个阶段评估了新流水线在生产环境中的影响:首先使用相同的公开流量与生产基线进行对比,然后通过客户 A/B 实验进行评估。
- 离线评估:在推送后扫描中,使用相同的公开流量进行评估时,新流水线的精确率比之前的 LLM 流水线高 13%,召回率高 19%。
- 在线评估:随后,我们通过与之前的 LLM 流水线进行 A/B 实验,验证这些质量改进能否转化为客户成果。按仓库所有者加权的接受率提高了 11.5%。我们按仓库所有者对接受率加权,以降低一次性批量处理大量警报的客户所造成的影响,否则这可能会扭曲简单平均值。
带上这些经验
最好的安全工具,就是开发者足够信任并愿意使用的工具。更高的精确率意味着更少的干扰性警报。更高的召回率意味着能捕获更多真实密钥。更低的成本意味着我们可以持续提升覆盖范围,而不让扫描变得贵得难以承受。
对于开发者和安全团队而言,这意味着更少的误报,并能在最可能引入密钥的场景中更快获得反馈:提交、拉取请求和日常开发工作流。
混合系统十分强大。正则表达式为我们带来速度、透明度和广泛的候选项覆盖。ModernBERT 则提供基于学习的上下文理解能力,并减少误报。在这款产品的限制条件下,两者结合的效果优于单独使用任一方法。
我们还了解到,模型规模不等于模型的实用性。当任务范围明确、决策边界可衡量且服务效率至关重要时,较小的微调分类器可能就是正确选择。
这是让密钥扫描更加准确、可扩展且易于使用的一步。展望未来,我们将重点关注两个方面:
- 构建持续改进的飞轮。我们将利用生产环境中的反馈回路发现新的漏报和误报,并将真实场景中的信号转化为更高质量的训练和评估数据。
- 探索新的模型架构。我们正在研究能够通过单一步骤完成密钥检测和提取的方法,在保持准确性和规模的同时降低流水线复杂度。
致谢
衷心感谢 GitHub 和 Microsoft 的工程、科学及产品团队,感谢大家协助构建新密钥扫描器所需的训练数据、评估套件、服务技术栈和发布计划。
这篇文章 GitHub 的密钥检测模型:以更少噪声发现更多密钥 最初发表于 The GitHub Blog。
来源:GitHub Blog · AI & ML · github.blog