GitHub AI & ML

GitHub 的秘密检测模型:以更少的噪音发现更多秘密

GitHub公开其上下文感知密钥检测分类器的内部实现:先用正则高召回生成候选,再用微调的ModernBERT结合文件路径、变量名和周边代码判断真伪,过滤占位符、测试样例等难负例。相比此前基于LLM的流水线,所有者加权验收率提高11.5%,推送后扫描中位执行时间降低86%,服务成本降低超过98%,离线评估精度和召回率分别提升13%和19%。

GitHub Copilot app for Beginners: Teach Copilot your codebase
配图来源 · GitHub AI & ML
11.5%

更高的接受率

所有者加权的警报精确率

86%

更低的扫描执行时间中位数

推送后扫描

98%

更低的服务成本

紧凑型模型 vs. 远程 LLM 调用

当开发人员对扫描结果有信心时,秘密扫描的效果最佳。发现得太少,真实的凭据可能会留在仓库中。警报太频繁,开发人员可能会把时间浪费在调查并非秘密的字符串上。

通用秘密使这种平衡尤为困难。同一个字符串可能是一个真实的凭据,也可能是一个文档占位符,因此检测它需要理解周围的代码和文本。

为应对这一挑战,我们专门针对 GitHub 的产品需求训练了一个秘密分类器:在满足大规模扫描的速度和效率要求的同时,将真实凭据与相似字符串区分开来。

在我们的姊妹篇 《秘密保护必须随软件扩展》中,我们解释了为什么秘密保护必须跟上 AI 加速开发的步伐。在这里,我们深入幕后,介绍为这项工作提供支撑的上下文感知分类器:我们如何设计、训练和评估它,以便以更少的噪音发现更多真实秘密。

我们启用了什么

GitHub 秘密扫描在两个关键时刻运行:

  • 推送保护 通过在接受推送之前扫描更改来帮助防止秘密进入仓库,给开发人员一个处理发现结果的机会。
  • 推送后扫描 在代码提交之后工作,持续扫描仓库内容,并在检测到潜在秘密时创建警报,以便开发人员和安全团队进行调查和修复。

我们开发了一个快速分类器,与之前基于 LLM 的流水线相比,将推送后扫描的执行时间中位数降低了86%。这种效率使得将通用秘密检测扩展到推送保护成为可能,能够在开发人员推送更改之前返回结果,而不仅仅是在代码提交之后。

秘密扫描阻止了一次提交 在模型检测到文件第5行存在秘密后,推送保护将其拦截。

为什么秘密难以检测

结构化凭据通常包含独特的前缀、长度、字符集或校验和。通用秘密可能没有。它们的语法与构建标识符、校验和、资源哈希、示例值和其他非敏感字符串重叠。上下文是决定性的信号。

可能是真实凭据可能无害的相似字符串
在生产数据库 URL 旁边赋值的密码测试夹具中同样形似密码的值
部署配置中的连接字符串设置指南中的 localhost 连接字符串
绑定到 API 凭证的高熵值高熵校验和、构建 ID 或资源哈希

这些情况属于困难负样本:即匹配凭证模式但并非可用凭证的字符串。增加更多规则可以抑制其中一部分,但每个例外都有隐藏真实密钥的风险。而学习型分类器可以利用诸如文件路径、密钥类型、变量名以及附近代码或文本等信号。

这就是我们推出采用两阶段流水线的新扫描器的原因:

  1. 候选生成:正则过滤器以高召回率扫描内容以发现潜在密钥。该阶段经过优化,可以快速且确定性地捕获广泛的类凭证模式族群。
  2. 情境感知分类:一个经过微调的 ModernBERT 分类器评估每个候选及其周围上下文。它经过训练,能够识别区分真实机密与误报的信号,包括占位符值、示例、文档片段、生成内容和非敏感标识符。由于该模型体积小、在我们的推理基础设施上运行高效,其服务成本远低于基于 LLM 的流水线,并且更易于扩展。

影响:

  • 用户接受度提升11.5%,减少了误报。
  • 86% 的推送后机密检测执行时间加速。
  • 与基于LLM的流水线相比,节省了超过98%的成本。

我们的流水线是如何工作的

在扫描内容时,正则表达式模式会撒下一张大网,标记任何看起来像凭证的内容,从而确保一开始不会漏掉真实的秘密。每个候选结果随后会进入一个经过微调的 ModernBERT 分类器,该分类器会将值与其文件路径、变量名及 surrounding code 一起读取。分类器会估计它是真实秘密的可能性。高置信度的发现会成为告警,而诸如占位符、测试夹具和校验和之类的相似项会在到达开发者之前被过滤掉。

第1步

扫描

仓库内容、提交、拉取请求以及其他被扫描的表面。

第 2 步

生成候选

正则表达式模式识别可能的令牌、密钥和类似凭据的字符串。

步骤 3

分类

微调后的 ModernBERT 对候选信息加上下文进行评估,并给出其为真实秘密的可能性。

步骤 4

警报或抑制

高置信度的发现会被推进;可能的假阳性则被过滤掉。

重要的设计选择在于,该模型并不取代确定性扫描,而是对其加以补充。正则表达式仍然是快速查找候选字符串的正确工具。分类器则用于机器学习最能发挥作用之处:区分“看起来像密钥”与“很可能是真实密钥”。

分类器模型尽力区分“看起来像秘密”和“很可能是真实秘密”。

一个困难负样本问题:几乎以假乱真的秘密

大多数误报并非随机出现。它们是困难负样本:即匹配了凭据模式但并非可用凭据的字符串。例如文档中的占位符、测试中的示例玩具代码、已脱敏的值、非敏感 ID 以及生成的测试夹具。这些情况很容易被正则表达式匹配到,而对于纯粹基于规则的系统来说,要在不误删真实密钥的前提下抑制它们却很困难。

ModernBERT 之所以有帮助,是因为它能将候选内容连同附近的代码和文本一起读取,从而提供与 LLM 相当的上下文理解能力,同时又没有生成自然语言输出所带来的延迟和计算开销。例如,被 “example”、“dummy”、“fake” 或 “replace-me” 等词包围的候选内容,其风险可能低于部署文件中被赋值给环境变量的候选内容。分类器从带标签的示例中学习这些上下文差异,而不需要工程师把每一个例外都编码成另一条规则。

我们选择 ModernBERT 是因为它非常适合这一工作负载:它紧凑、高效,非常适合对代码周边文本进行分类。对于秘密扫描,该模型需要以高吞吐量和低延迟对较短的候选窗口做出经过校准的决策。

这使得微调过的编码器分类器成为流水线这一阶段比通用 LLM 更好的服务形态。该模型可以直接在我们的决策边界上训练,并使用对秘密扫描质量至关重要的相同召回率和精确率指标进行评估。

我们如何训练

挑战在于为那些仅凭语法会误导判断的情况找到具有代表性的数据。训练与评估策略结合了三种来源:

  • 来自 GitHub 仓库的产品衍生示例,利用秘密检测经验的反馈以及额外的人工验证。
  • 来自 GitHub 仓库数据的高召回率 regex 候选,包括人工标注的示例和用于扩大覆盖面的弱标签。
  • 针对稀疏和困难案例的合成示例,例如文档中的秘密、测试夹具、公钥、校验和、结构相似的仿冒项以及近似命中配对。

合成数据行在纳入前需通过确定性验证和基于模型的质量审查。训练重点包括真实密钥、现实的误报以及经常让仅依赖正则表达式的方法感到困惑的困难负样本。每个模型输入包含候选值、文件路径、密钥类型以及有限数量的周围上下文。我们通过离线评估来选择阈值,然后在更大范围推广之前,在类生产流量上验证其行为。

在拆分数据之前,我们对共享仓库、候选值或示例的行进行了分组,这样近似重复项就不会同时出现在训练集和评估集中。

训练聚焦于对告警质量最重要的案例:真实的密钥、符合实际的误报,以及正则表达式经常匹配到的困难负例。输入表示包括候选密钥字符串、文件路径、类型以及有界的周边上下文。输出是一个分类分数,供扫描器用来决定该候选是否应继续处理。

我们针对产品层面的权衡进行优化:在降低误报和服务成本的同时保持或提高召回率。在实践中,这意味着分类器阈值通过离线评估选择,然后在上线前通过与生产环境类似的流量进行验证。

最重要的训练原则是让模型看到令人混淆的示例。我们纳入了在语法上与真实密钥相似但在语义上不同的候选,这样模型不仅学会密钥长什么样,也学会在上下文中误报长什么样。

训练好的模型被导出为带8位量化的ONNX格式,从而实现快速推理。

评估结果

线上结果与之前的LLM管道相比的变化衡量内容
按仓库所有者加权后的接受率高出11.5% 客户对检测到的发现的接受情况
推送后扫描的执行时间中位数降低86% 生产环境扫描执行时间
服务成本降低超过98% 紧凑分类器与远程LLM调用相比的成本
针对我们微调模型与之前LLM管道的客户A/B评估结果。

我们分两个阶段评估了新管道在生产环境中的影响:首先在与生产基线相同的公共流量上进行对比,然后通过客户A/B实验进行验证。

  • 离线评估: 在推送后扫描中,新管道在相同的公共流量上评估时,达到了 比之前的LLM管道高出13%的精确率和高出19%的召回率 翻译:在同一公共流量上进行评估时,比之前的 LLM 流水线表现更好。 
  • 线上评估: 随后,我们通过与之前的LLM管道进行A/B实验,验证了这些质量改进是否转化为客户成果。 按仓库所有者加权后的接受率提高了11.5%。 我们按仓库所有者对接受率进行加权,以减少一次性批量处理大量告警的客户的影响,否则这种做法可能会扭曲简单的平均值。 

带走这些要点

最好的安全工具是开发人员足够信任并愿意使用的工具。更高的精确率意味着更少的干扰性告警。更高的召回率意味着能捕获更多真实密钥。更低的成本意味着我们可以在不使扫描成本高得令人望而却步的情况下持续改进覆盖率。

对于开发人员和安全团队而言,这应转化为更少的误报,以及在密钥最有可能被引入的地方获得更快的反馈:提交、拉取请求和日常开发工作流。

混合系统非常强大。正则表达式为我们提供了速度、透明度和广泛的候选覆盖。ModernBERT 为我们提供了可学习的上下文理解和误报减少能力。在这种产品约束下,两者的结合优于任何一种单独使用的方法。

我们还了解到,模型规模并不等于模型实用性。当任务范围狭窄、决策边界可度量且服务效率至关重要时,一个更小的微调分类器可能才是正确的答案。

这是让密钥扫描更准确、更具可扩展性且更易于使用的一步。展望未来,我们将专注于两个领域:

  • 构建持续改进的飞轮。我们将利用生产环境的反馈循环来识别新的漏报和误报,将真实世界的信号转化为更高质量的训练和评估数据。
  • 探索新的模型架构。我们正在研究能够在单一步骤中完成密钥检测和提取的方法,在保持准确性和规模的同时降低流水线复杂度。

致谢

衷心感谢 GitHub 和 Microsoft 的工程、科学和产品团队,他们帮助构建了这个新密钥扫描器的训练数据、评估套件、服务架构和发布计划。

这篇文章 GitHub 的密钥检测模型:以更少的噪音发现更多的密钥 首发于 The GitHub Blog.

原始出处

GitHub AI & ML

内容说明

原始发布及相关权利归来源方。

机器翻译 · 请以原文为准