GitHub工程复盘:用ModernBERT替代LLM实现低成本密钥检测
GitHub’s model for secret detection: Finding more secrets with less noise
这是一篇极具参考价值的工程复盘,清晰展示了如何用轻量级模型解决LLM在特定场景下的性能与成本瓶颈,参数取舍对做AI落地应用的同学很有启发。
OUR PIPELINE VS. THE PREVIOUS LLM PIPELINE
我们的流水线与之前的 LLM 流水线对比
Smarter secret scanning, at a fraction of the cost
更智能的密钥扫描,成本仅为原来的几分之一
11.5%
higher acceptance
更高的接受率
Owner-weighted alert precision
按所有者加权的警报精度
86%
lower median scan execution time
更低的中间件扫描执行时间
Post-push scanning
推送后扫描
98%
lower serving cost
更低的服务成本
Compact model vs. remote LLM calls
紧凑模型 vs. 远程 LLM 调用
Secret scanning works best when developers are confident in the findings. Catch too little, and real credentials can remain in a repository. Alert too often, and developers may spend time investigating strings that aren’t secrets.
当开发者对发现结果有信心时,密钥扫描的效果最佳。如果捕获得太少,真正的凭证可能会留在仓库中;如果警报过于频繁,开发者可能会花费时间调查那些并非密钥的字符串。
Generic secrets make that balance especially difficult. The same string could be a real credential or a documentation placeholder, so detecting it requires understanding the surrounding code and text.
通用密钥使得这种平衡尤为困难。同一个字符串可能是真正的凭证,也可能是文档占位符,因此检测它需要理解周围的代码和文本。
To address this challenge, we trained a secret classifier specifically for GitHub’s product needs: distinguishing real credentials from lookalikes while meeting the speed and efficiency requirements of scanning at scale.
为了解决这一挑战,我们针对 GitHub 的产品需求训练了一个专门的密钥分类器:在满足大规模扫描的速度和效率要求的同时,区分真正的凭证和相似物。
In our companion post, Secret protection must scale with software, we explained why secret protection must keep pace with AI-accelerated development. Here, we go behind the scenes of the context-aware classifier powering that effort: how we designed, trained, and evaluated it to find more real secrets with less noise.
在我们的配套文章《密钥保护必须随软件扩展》中,我们解释了为什么密钥保护必须跟上 AI 加速的开发步伐。在这里,我们将深入幕后,展示驱动这一努力的上下文感知分类器:我们如何设计、训练和评估它,以用更少的噪声发现更多真正的密钥。
What we enabled
我们所实现的能力
GitHub secret scanning operates at two key moments:
GitHub 密钥扫描在两个关键时刻运行:
- Push protection helps prevent secrets from entering a repository by scanning changes before a push is accepted, giving developers an opportunity to address the finding.
- Post-push scanning works after code has been committed, continuously scanning repository content and creating alerts when potential secrets are detected so developers and security teams can investigate and remediate them.
- 推送保护通过在接受推送之前扫描更改来防止密钥进入仓库,使开发者有机会处理发现的问题。
- 推送后扫描在代码提交后工作,持续扫描仓库内容并在检测到潜在密钥时创建警报,以便开发者和安全团队进行调查和修复。
We developed a fast classifier that reduced median post-push scan execution time by 86% compared with the previous LLM-based pipeline. That efficiency made it practical to extend generic secret detection to push protection, returning results before developers push changes, not only after code is committed.
我们开发了一种快速分类器,与之前的基于 LLM 的流水线相比,将中间件推送后扫描的执行时间减少了 86%。这种效率使得将通用密钥检测扩展到推送保护变得切实可行,能够在开发者推送更改之前(而不仅仅是在代码提交之后)返回结果。
Secret scanning blocks a commit with push protection after the model detects a secret on line 5 of the file.
在使用推送保护的密钥扫描中,当模型检测到文件第 5 行存在密钥时,会阻止提交。
Why secrets are hard to detect
为什么密钥难以检测
Structured credentials often include a distinctive prefix, length, alphabet, or checksum. Generic secrets may not. Their syntax overlaps with build identifiers, checksums, asset hashes, sample values, and other non-sensitive strings. Context is the deciding signal.
结构化凭证通常包含独特的后缀、长度、字母表或校验和。通用密钥可能不具备这些特征。它们的语法与构建标识符、校验和、资产哈希、示例值和其他非敏感字符串重叠。上下文是决定性的信号。
| Likely real credential | Likely harmless lookalike |
|---|---|
| A password assigned beside a production database URL | The same password-shaped value in a test fixture |
| A connection string in deployment configuration | A localhost connection string in a setup guide |
| A high-entropy value bound to an API credential | A high-entropy checksum, build ID, or asset hash |
| 可能是真实凭证 | 可能是无害的相似物 |
|---|---|
| 生产数据库 URL 旁边的密码 | 测试夹具中相同的密码形状值 |
| 部署配置中的连接字符串 | 设置指南中的 localhost 连接字符串 |
| 绑定到 API 凭证的高熵值 | 高熵校验和、构建 ID 或资源哈希 |
These cases are hard negatives: strings that match a credential pattern but are not usable credentials. Adding more rules can suppress some of them, but each exception risks hiding a real secret. A learned classifier can instead use signals such as file path, secret type, variable names, and nearby code or text.
这些情况属于困难负例:匹配凭证模式但不可用的字符串。增加更多规则可以抑制其中一些,但每个例外都可能掩盖真正的秘密。相反,学习到的分类器可以利用文件路径、密钥类型、变量名以及附近代码或文本等信号。
That is why we shipped a new scanner using a two-stage pipeline:
这就是我们推出使用两阶段管道的新扫描器的原因:
- Candidate generation: Regex filters scan content for potential secrets with high recall. This stage is optimized to catch broad families of credential-like patterns quickly and deterministically.
- Context-aware classification: A fine-tuned ModernBERT classifier evaluates each candidate and its surrounding context. It is trained to recognize the signals that separate real secrets from false positives, including placeholder values, examples, documentation snippets, generated content, and non-sensitive identifiers. Because the model is small and efficient to run on our inference infrastructure, it costs much less to serve and is simpler to scale than an LLM-based pipeline.
- 候选生成:正则表达式过滤器扫描内容,以高召回率查找潜在的秘密。此阶段经过优化,能够快速且确定性地捕获广泛的类凭证模式家族。
- 上下文感知分类:微调后的 ModernBERT 分类器评估每个候选项及其周围上下文。它被训练用于识别区分真实秘密与误报的信号,包括占位符值、示例、文档片段、生成内容和非敏感标识符。由于该模型小巧高效,可在我们的推理基础设施上运行,因此其服务成本远低于基于 LLM 的管道,且扩展更简单。
Impact:
影响:
- 11.5% user acceptance improvement, reducing false positives.
- 86% faster post-push secret detection execution time.
- More than 98% cost savings compared with the LLM-based pipeline.
- 用户接受度提高 11.5%,减少了误报。
- 推送后秘密检测执行时间加快 86%。
- 与基于 LLM 的管道相比,节省超过 98% 的成本。
How our pipeline works
我们的管道工作原理
As content is scanned, regex patterns cast a wide net and flag anything that looks like a credential, so real secrets aren’t missed at the start. Each candidate then goes to a fine-tuned ModernBERT classifier, which reads the value together with its file path, variable names, and surrounding code. The classifier estimates how likely it is to be a real secret. High-confidence findings become alerts, and lookalikes such as placeholders, test fixtures, and checksums are filtered out before they reach developers.
在扫描内容时,正则表达式模式撒下大网,标记任何看起来像凭证的内容,以确保不会在开始时遗漏真实秘密。然后,每个候选项都会进入微调后的 ModernBERT 分类器,该分类器结合值、文件路径、变量名和周围代码进行读取。分类器评估其为真实秘密的可能性。高置信度的发现将成为警报,而占位符、测试夹具和校验和等相似物会在到达开发人员之前被过滤掉。
HOW OUR PIPELINE WORKS
我们的管道工作原理
Broad first, careful second
先广泛覆盖,再仔细甄别
STEP 1
步骤 1
Scan
扫描
Repository content, commits, pull requests, and other scanned surfaces.
仓库内容、提交、拉取请求以及其他被扫描的表面。
STEP 2
步骤 2
Generate candidates
生成候选项
Regex patterns identify possible tokens, keys, and credential-like strings.
正则表达式模式识别可能的令牌、密钥和类凭证字符串。
STEP 3
步骤 3
Classify
分类
Fine-tuned ModernBERT evaluates candidate + context and assigns likelihood of a true secret.
微调后的 ModernBERT 评估候选项 + 上下文,并分配真实秘密的可能性。
STEP 4
步骤 4
Alert or suppress
发出警报或抑制
High-confidence findings move forward; likely false positives are filtered.
高置信度的发现得以推进;可能的假阳性被过滤掉。
The important design choice is that the model does not replace deterministic scanning. Instead, it complements it. Regexes remain the right tool for finding candidate strings quickly. The classifier is used where machine learning provides the most leverage: distinguishing “looks like a secret” from “is likely a real secret.”
重要的设计选择在于,该模型并未取代确定性扫描,而是对其进行补充。正则表达式仍然是快速查找候选字符串的正确工具。分类器用于机器学习最能发挥作用的场景:区分“看起来像秘密”和“很可能是真实秘密”。
The classifier model makes a best effort to distinguish “looks like a secret” from “is likely a real secret.”
分类器模型尽力区分“看起来像秘密”和“很可能是真实秘密”。
A hard-negative problem: secrets that almost look real
硬负样本问题:几乎看起来像真实的秘密
Most false positives are not random. They are hard negatives: strings that match a credential pattern but are not usable credentials. Examples include documentation placeholders, toy examples in tests, redacted values, non-sensitive IDs, and generated fixtures. These cases are easy for a regex to match and hard for a purely rule-based system to suppress without accidentally losing real secrets.
大多数假阳性并非随机产生。它们是硬负样本:匹配凭证模式但不可用的凭证字符串。示例包括文档占位符、测试中的玩具示例、脱敏值、非敏感 ID 以及生成的夹具(fixtures)。这些情况很容易被正则表达式匹配,而纯基于规则的系统很难在不意外丢失真实秘密的情况下将其抑制。
ModernBERT helps because it can read the candidate together with nearby code and text providing contextual understanding comparable to an LLM without the latency and computational overhead of generating natural-language output. For example, a candidate surrounded by words like “example,” “dummy,” “fake,” or “replace-me” may be lower risk than a candidate assigned to an environment variable in a deployment file. The classifier learns these contextual differences from labeled examples rather than requiring engineers to encode every exception as another rule.
ModernBERT 之所以有帮助,是因为它能够将候选字符串与附近的代码和文本一起读取,提供可与 LLM 相媲美的上下文理解能力,同时避免了生成自然语言输出所带来的延迟和计算开销。例如,周围环绕着“example”、“dummy”、“fake”或“replace-me”等词汇的候选项,其风险可能低于部署文件中分配给环境变量的候选项。分类器从带标签的示例中学习这些上下文差异,而不是要求工程师将每个例外都编码为另一条规则。
We chose ModernBERT because it provides a strong fit for this workload: it is compact, efficient, and well suited for classification over code-adjacent text. For secret scanning, the model needs to make a calibrated decision over short candidate windows with high throughput and low latency.
我们选择 ModernBERT,因为它非常适合此工作负载:它紧凑、高效,并且非常适合对代码相关文本进行分类。对于秘密扫描,模型需要在短候选窗口内做出校准后的决策,同时具备高吞吐量和低延迟。
That makes a fine-tuned encoder classifier a better serving shape than a general-purpose LLM for this stage of the pipeline. The model can be trained directly on our decision boundary, and evaluated using the same recall and precision metrics that matter to secret scanning quality.
这使得微调后的编码器分类器成为该管道阶段的更优服务形态,优于通用 LLM。该模型可以直接在我们的决策边界上进行训练,并使用对秘密扫描质量至关重要的召回率和精确率指标进行评估。
How we trained
我们的训练方法
The challenge was finding representative data for cases in which syntax alone is misleading. The training and evaluation strategy combines three sources:
挑战在于找到具有代表性的数据,以应对仅凭语法具有误导性的情况。训练和评估策略结合了三个来源:
- Product-derived examples from GitHub repositories, using feedback from the secret detection experience and additional human validation.
- High-recall regex candidates from GitHub repository data, including human-annotated examples and weak labels used to expand coverage.
- Synthetic examples targeted at sparse and difficult cases, such as documentation secrets, test fixtures, public keys, checksums, structured lookalikes, and near-miss pairs.
- 来自 GitHub 仓库的产品衍生示例,利用秘密检测经验的反馈以及额外的人工验证。
- 来自 GitHub 仓库数据的高召回率正则表达式候选项,包括人工标注的示例和用于扩展覆盖范围的弱标签。
- 针对稀疏且困难案例的合成示例,例如文档密钥、测试夹具、公钥、校验和、结构化相似物以及近失对。
更进一步:量化金融体系
看懂新闻只是起点——沿量化金融路径,把它变成能交付的工程能力