detect-secrets:扫描代码仓库中的密钥泄露

Yelp 开源的 detect-secrets 目前收获了 4,532 个 Star:

正文顶部截图

README区域截图

detect-secrets 是一款扫描代码中密钥和密码的 Python 工具。它面向企业场景设计,核心思路和其他产品不同:接受大型仓库里可能已经存在历史遗留密钥的事实,把工作重点放在建立基线上,优先阻止新的密钥继续进入代码库。

这个工具围绕三个目标展开:

  1. 防止新的密钥进入代码库
  2. 检测防护措施是否被显式绕过
  3. 提供密钥清单,帮助团队逐步迁移到更安全的存储位置

它通过正则和熵值检测来分析代码差异,判断是否有新的疑似密钥被提交。这种方式不需要扫描全部 git 历史,也无需每次都扫描整个仓库,开销比较小。对大型仓库来说,这一点比较重要,因为全量扫描往往会消耗大量时间和计算资源。

detect-secrets 提供三个命令行工具:

detect-secrets scan 用于生成和更新基线文件
detect-secrets-hook 用于在提交前拦截新增的密钥
detect-secrets audit 用于人工审查和标注基线中的结果

安装

detect-secrets 可通过 pip 安装:

pip install detect-secrets

macOS 用户也可以通过 Homebrew 安装:

brew install detect-secrets

快速开始

首次使用时,扫描仓库生成基线文件:

detect-secrets scan > .secrets.baseline

如果仓库里包含未被 git 追踪的文件,可以加上 --all-files 参数:

detect-secrets scan --all-files > .secrets.baseline

后续发现新的密钥时,更新基线:

detect-secrets scan --baseline .secrets.baseline

这个命令会保留你已有的标注,同时把新发现的密钥加入基线,并移除已经不在代码库里的旧条目。

pre-commit 钩子

推荐将 detect-secrets-hook 配置为 pre-commit 钩子,只检查本次变更涉及的内容:

git diff --staged --name-only -z | xargs -0 detect-secrets-hook --baseline .secrets.baseline

也可以检查所有已追踪文件:

git ls-files -z | xargs -0 detect-secrets-hook --baseline .secrets.baseline

插件与过滤机制

detect-secrets 通过插件识别密钥,再通过过滤器降低误报。内置插件覆盖 AWS 密钥、Azure 存储密钥、GitHub Token、GitLab Token、私钥、Slack Token、Stripe 密钥等类型。这些插件大致分为三类:基于正则的规则适合结构清晰的密钥,熵值检测适合没有固定格式的字符串,关键词检测则通过变量名来判断是否存在硬编码凭证。

查看所有可用插件:

detect-secrets scan --list-all-plugins

禁用不需要的插件:

detect-secrets scan --disable-plugin AWSKeyDetector

过滤器用于排除文件、行或内容。例如按正则排除匹配的行:

detect-secrets scan --exclude-lines 'password = (blah|fake)'

或者排除匹配的文件:

detect-secrets scan --exclude-files '.*\.signature$'

针对单行误报,可以使用注释内联放行:

API_KEY = 'this-will-be-detected'  # pragma: allowlist secret

审计基线

audit 命令用于审查基线文件,区分误报和真实的密钥:

detect-secrets audit .secrets.baseline

审计完成后,可以生成报告查看结果分布,也可以对比两个基线文件来评估不同插件配置的效果。

Python API

detect-secrets 提供 Python API,方便集成到其他脚本:

from detect_secrets import SecretsCollection
from detect_secrets.settings import default_settings

secrets = SecretsCollection()
with default_settings():
    secrets.scan_file('test_data/config.ini')

import json
print(json.dumps(secrets.json(), indent=2))

还可以通过 transient_settings 加载自定义插件和过滤器:

from detect_secrets import SecretsCollection
from detect_secrets.settings import transient_settings

secrets = SecretsCollection()
with transient_settings({
    'plugins_used': [
        {'name': 'Base64HighEntropyString', 'limit': 5.0},
    ],
    'filters_used': [
        {'path': 'file://private-filters/example.py::check_result'},
    ]
}) as settings:
    secrets.scan_file('test_data/config.ini')

对于已经积累了大量历史密钥的仓库,detect-secrets 提供了一种分阶段的过渡路径。先划定基线,再阻止新增,最后逐步清理存量。这种方式比一次性全面扫描更容易在团队中落地。

ettings:
secrets.scan_file(‘test_data/config.ini’)


对于已经积累了大量历史密钥的仓库,detect-secrets 提供了一种分阶段的过渡路径。先划定基线,再阻止新增,最后逐步清理存量。这种方式比一次性全面扫描更容易在团队中落地。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐