← 文章 / AI技术
GitHub Blog 3小时前 · 2026-10-14 02:51:14 · 10 阅读

GitHub 密钥检测模型:更少噪音,揪出更多泄露密钥

只有在开发者对扫描结果足够信任时,secret scanning 才能发挥最大价值。检出的太少,真实的凭证就可能留在仓库里;误报太多,开发者又会浪费时间去排查那些根本不是密钥的字符串。

通用密钥让这个平衡变得尤其困难。同一段字符串既可能是真实凭证,也可能只是文档里的占位符,因此检测时必须理解周围的代码和文本。

为了解决这个难题,我们针对 GitHub 的产品需求专门训练了一个密钥分类器:在满足大规模扫描的速度和效率要求的同时,准确区分真实凭证和“长得像”的字符串。

在姊妹篇《Secret protection must scale with software》中,我们解释了为什么密钥防护必须跟上 AI 加速开发的步伐。本文将深入介绍支撑这一目标的上文感知分类器:我们如何设计、训练和评估它,从而以更少的噪音找出更多真实密钥。

我们实现了什么

GitHub secret scanning 在两个关键节点上工作:

  • Push protection 在推送被接受前扫描变更,防止密钥进入仓库,并给开发者处理告警的机会。
  • 推送后扫描 在代码提交之后持续扫描仓库内容,一旦发现疑似密钥就生成告警,供开发者和安全团队调查并修复。

我们开发了一个快速分类器,将推送后扫描的中位执行时间相比原有的 LLM 流水线降低了 86%。正是这种效率提升,让我们得以把通用密钥检测扩展到 push protection,在开发者推送变更之前就返回结果,而不必等到代码提交之后。

模型在文件第 5 行检测到密钥后, push protection 拦截了这次提交。

为什么密钥难以检测

结构化凭证通常带有独特的前缀、长度、字符集或校验和,而通用密钥未必如此。它们的语法与构建标识符、校验值、资源哈希、示例值等非敏感字符串高度重叠。此时,上下文就成了决定性的信号。

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

这些是困难负样本:匹配凭证模式但不可用的字符串。增加规则可以抑制其中部分,但每个例外都可能掩盖真实密钥。学习型分类器可以利用文件路径、密钥类型、变量名和附近代码或文本等信号来区分。

因此,我们发布了使用两阶段流水线的新扫描器:

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

影响:

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

我们的流水线如何工作

扫描内容时,正则模式广撒网,标记所有看似凭证的内容,确保初期不遗漏真实密钥。每个候选然后交给微调的 ModernBERT 分类器,它读取该值及其文件路径、变量名和周围代码。分类器估计其为真实密钥的可能性。高置信度结果成为告警,占位符、测试夹具和校验和等相似物在到达开发者之前就被过滤掉。

第 1 步

扫描

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

步骤 2

生成候选项

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

步骤 3

分类

微调后的 ModernBERT 评估候选项及其上下文,并判定其为真实密钥的可能性。

步骤 4

告警或抑制

高置信度的发现被推进一步;可能是误报的结果则被过滤。

JavaScript 绘制箭头连接这些卡片。我们的管道如何工作 先广泛扫描,再精细过滤 步骤 1 扫描 仓库内容、提交记录、拉取请求以及其他被扫描的表面。 步骤 2 生成候选项 正则表达式模式用于识别可能的 token、密钥和类似凭据的字符串。 步骤 3 分类 微调后的 ModernBERT 评估候选项及其上下文,并判定其为真实密钥的可能性。 步骤 4 告警或抑制 高置信度的发现被推进一步;可能是误报的结果则被过滤。 连接:从扫描到生成候选项。 连接:从生成候选项到分类。 连接:从分类到告警或抑制。

关键的设计选择在于模型并不取代确定性扫描,而是与之互补。正则表达式仍然是快速发现候选字符串的最佳工具。分类器被用在机器学习最能发挥作用的环节:区分“看起来像密钥”和“可能是真实密钥”。

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

困难负样本问题:看似真实的密钥

大多数误报并非随机出现。它们是困难负样本:符合凭据模式但无法使用的字符串。示例包括文档占位符、测试中的玩具示例、已脱敏的值、非敏感 ID 和生成的测试数据。这些情况很容易匹配正则表达式,但如果仅依赖基于规则的系统,很难在不意外丢失真实密钥的情况下将它们抑制。

ModernBERT 的优势在于,它能结合候选值周边的代码和文本进行判断,获得与 LLM 相当的上下文理解能力,同时省去了生成自然语言输出的延迟和算力开销。举例来说,如果候选值周围出现 "example"、"dummy"、"fake"、"replace-me" 这类词,风险往往低于部署文件中赋给环境变量的候选值。分类器从标注样本中学习这些上下文差异,而不需要工程师为每种例外情况再写一条规则。

我们选择 ModernBERT,是因为它非常适合这项工作:模型紧凑、高效,特别擅长对代码相关文本做分类。秘密扫描场景要求模型对较短的候选窗口做出校准良好的判断,同时保持高吞吐、低延迟。

因此在流水线的这个环节,微调后的 encoder 分类器比通用 LLM 更适合上线。这个模型可以直接按我们的判定边界训练,并用与秘密扫描质量直接相关的 recall 和 precision 指标来评估。

训练方法

难点在于为那些仅凭语法容易误判的情况找到有代表性的数据。我们的训练和评估策略综合了三个来源:

  • 来自 GitHub 仓库的产品数据样本,结合秘密检测的线上反馈以及额外的人工校验。
  • 从 GitHub 仓库数据中用高召回 regex 产生的候选,包括人工标注样本和用于扩大覆盖面的弱标签。
  • 针对稀疏和疑难场景构造的合成样本,比如文档中的密钥、测试 fixture、公钥、校验和、结构上相似的内容以及近似命中样本。

合成样本在纳入之前会经过确定性校验和基于模型的质量审查。训练重点覆盖真实密钥、典型的误报,以及常让纯 regex 方案出错的困难负样本。每次模型输入包含候选值、文件路径、密钥类型和一定量的周边上下文。我们通过离线评估选择阈值,再在接近生产流量的环境中验证行为,最后才全面上线。

在切分数据之前,我们会把共享同一仓库、候选值或样本来源的记录归为一组,确保近似重复的样本不会同时出现在训练集和评估集中。

训练重点关注那些对警报质量影响最大的用例:真实密钥、逼真的误报,以及正则表达式容易误匹配的困难负样本。输入特征包含候选密钥字符串、文件路径、类型以及有限的上下文信息。输出是一个分类得分,扫描器据此判断该候选项是否应进入后续处理流程。

我们针对产品层面的权衡进行了优化:在降低误报率和部署成本的同时,保持甚至提升召回率。具体来说,分类器阈值通过离线评估选定,然后在发布前针对类生产流量进行验证。

最重要的训练原则是让模型接触那些易混淆的样本。我们纳入了那些在语法上类似真实密钥但在语义上不同的候选项,使模型不仅学习密钥的特征,还学会在上下文中识别误报的样子。

训练好的模型被导出为 ONNX 格式,并采用 8 位量化技术,以实现快速推理。

评估结果

在线结果相较于前代 LLM 流水线的变化衡量指标
基于仓库所有者的加权接受率 提高 11.5% 客户对检测结果的接受程度
推送后扫描执行时间的中位数 降低 86% 生产环境扫描执行时间
部署成本 降低超过 98% 紧凑分类器与远程 LLM 调用的成本对比
我们微调模型与前代 LLM 流水线相比的客户 A/B 评估结果。

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

  • 离线评估:在推送后扫描中,针对相同的公开流量进行评估,新流水线的精确率比前代 LLM 流水线高 13%,召回率高 19%。
  • 在线评估:随后,我们通过 A/B 实验验证了这些质量改进是否真正转化为更好的客户体验,对照组为旧的 LLM 流水线。按仓库所有者加权计算后,告警接受率提升了 11.5%。之所以采用这种加权方式,是为了削弱那些一次性批量处理大量告警的客户对结果的影响,从而避免拉低或扭曲简单的平均值。

核心要点

最好的安全工具,是开发者足够信任并愿意使用的工具。更高的准确率意味着更少的干扰告警;更高的召回率意味着能捕获更多的真实密钥;更低的成本则让我们能在不显著推高扫描价格的前提下,持续提升覆盖范围。

对于开发者和安全团队而言,这意味着误报将大幅减少,且在密钥最易泄露的场景——提交、拉取请求以及日常开发流程中,他们能获得更快的反馈。

混合系统威力强大。正则表达式提供速度、透明度和广泛的候选覆盖;ModernBERT 则提供学习到的上下文理解和误报抑制。在当前产品约束下,两者结合的效果优于单独使用其中任何一种。

我们还意识到,模型大小并不等同于模型实用性。当任务范围窄、决策边界可量化且对服务效率要求极高时,一个较小的微调分类器往往才是最佳答案。

这是让密钥扫描更准确、更具可扩展性且更易于使用的一步。展望未来,我们将重点关注以下两个方面:

原始来源: GitHub Blog

评论 (0)