关于 open-source-checker
open-source-checker 是一项只读审计技能,用于判断私有仓库是否适合公开。它检查许可证、历史记录中的秘密信息、内部引用和发布准备情况,并给出允许发布或阻止发布的结论。
主要功能
- 01许可证与署名审查
- 02扫描仓库历史中的秘密信息
- 03搜索内部引用
- 04检查发布准备情况
- 05按严重程度报告发现并给出结论
适用场景
- 01公开发布前审计私有仓库
- 02找出需要轮换的凭据
- 03检查仓库历史中的内部信息
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ shipshitdev/ skills --skill open-source-checker安装后在 Claude Code 中输入/open-source-checker确认已加载。
附带文件plugin.jsonreferences/full-guide.md
详细介绍
开源检查器
发布关卡。在一个始终保持私有的仓库中,有人提出将其公开时,此检查器会运行一次。私有仓库中的所有内容,都是在假设外部无人会阅读的前提下编写的——注释、主机名、客户端名称,以及曾经创建的每一笔提交。这项审计会找出这个假设遗留下来的内容。
四轮检查,然后给出结论。定期的提交时防护属于另一项技能——参见相关。
约定
输入:
- 仓库根目录,已获取完整历史记录(
git fetch --all --tags) - 已选定的目标公开许可证(如已选定)
- 需视为私密的信息:公司域名、客户名称、内部主机名
输出:
- 各轮检查结果,包含文件、行号或提交,以及严重程度
- 发布 / 阻止的结论,并列出所有阻止项
- 交给
git-safety的凭据轮换清单和历史重写清单
创建 / 修改:
- 无。此审计为只读操作。
外部副作用:
- 无。修复工作会交由其他工具执行,此处不会执行。
需要确认:
- 在将仓库设为公开之前——结论仅供参考,是否公开由仓库所有者决定
委托给:
git-safety:轮换凭据、重写历史,并安装持续运行的提交时防护security-audit:审查应用层漏洞
预检
审计的完整程度取决于本地已有的引用。
git fetch --all --tags --prune
git log --all --oneline | wc -l # commits in scope
git branch -a && git tag -l # refs in scope
git stash list # stashes are not in --all
当所有远程分支和标签都已存在于本地时结束。
第 1 轮——许可证和署名
私有仓库无需许可证。公开仓库若未附上明确的许可证,任何发现它的人在法律上都无法使用其中的内容;而在某一许可证下借用的代码,并不总能以另一种许可证重新发布。
检查:
- 根目录中是否存在
LICENSE文件,且与仓库所有者的意图一致 - 依赖项许可证是否与预期的发布许可证兼容——采用著佐权许可证(GPL、AGPL)的依赖项会限制宽松许可证下的发布
- 是否标注了引入和复制粘贴代码的来源——摘自 Stack Overflow、博客文章或其他仓库的代码片段,受其来源处的条款约束
- 版权声明是否一致,并且是否列明正确的实体
- 如果代码是在公司工作时间编写的,是否已厘清雇主所有权
ls LICENSE* COPYING* 2>/dev/null
bunx license-checker --summary # JS dependency licenses
grep -rniE 'copyright|\(c\) [0-9]{4}|SPDX-License' --include='*.*' -l . | head -30
grep -rniE 'adapted from|based on|taken from|source: http' --include='*.*' . | head -30
当发布许可证已明确、每项依赖的许可证都与之兼容,并且所有借用的代码块都已注明来源或移除时结束。
第 2 轮——历史记录中的密钥
从工作树中删除密钥,并不会将其从曾经包含它的提交中删除。发布仓库也会一并发布这些提交。
扫描所有引用,而不只是 HEAD:
# Automated sweep across all history — start here
gitleaks detect --source . --verbose
trufflehog git file://. --only-verified
# Every file that ever existed
git log --all --pretty=format: --name-only --diff-filter=A | sort -u \
| grep -iE '\.(env|pem|key|secret)$|credentials|secrets\.|id_rsa'
# Files deleted from the tree but alive in history
git log --all --pretty=format: --name-only --diff-filter=D | sort -u \
| grep -iE '\.(env|pem|key|secret)$|credentials'
# Content search across every commit
git log -p --all -S 'API_KEY' --source -- ':(exclude)*.lock'
git log -p --all -G 'AKIA[0-9A-Z]{16}' --source
还要检查 --all 会遗漏的地方:储藏、合并提交以及所有标签。命令见 references/full-guide.md §3。
每个命中项都应先列入凭据轮换清单,再列入历史重写清单。清理历史记录无法撤销曾经推送过的凭据泄露。
当 gitleaks 和 truffleHog 在完整历史记录中都未发现问题,并且所有先前发现的凭据都已确认轮换时结束。
Pass 3 — 私有引用
这一轮不使用工具,也是泄露内容最多的一轮。这些不是凭据,而是只有在公司内部才有意义的事实。
| 类别 | 查找内容 |
|---|---|
| 内部主机 | *.internal、*.corp、*.local、VPN 主机名、RFC1918 IP 地址 |
| 内部服务 | Jira/Linear 工单 URL、内部 Wiki、管理仪表板 |
| 人员 | 员工邮箱、个人邮箱、TODO 和 FIXME 注释中的姓名 |
| 客户 | 客户名称、Logo、合同条款、测试夹具中的客户数据 |
| 基础设施 | 账号 ID、存储桶名称、集群名称、暂存环境 URL |
| 商业信息 | 定价逻辑、未发布的产品名称、内部路线图备注 |
| 提交元数据 | 每次提交的作者邮箱——这些也会公开 |
# Internal domains and hosts (substitute your own)
grep -rniE '@(yourcompany|internal|corp)\.(com|net|local)' . | grep -v node_modules
grep -rniE '\b(10|192\.168|172\.(1[6-9]|2[0-9]|3[01]))\.[0-9]+\.[0-9]+\b' . | grep -v node_modules
# People and intent left in comments
grep -rniE '(TODO|FIXME|HACK|XXX|NOTE)[:( ].*(ask|per|@[a-z]+)' --include='*.*' . | head -40
# Author identities that ship with the history
git log --all --format='%ae' | sort -u
git log --all --format='%an <%ae>' | sort -u | head -30
通过一个问题判断每项命中内容:陌生人读到这些内容后,是否会了解到公司不会公开的信息? 暂存环境 URL 属于发现项。公开的文档链接则不属于。
当每个类别都已搜索,且每项命中内容都已删除、替换为中性占位符,或由负责人明确接受后,本轮结束。
Pass 4 — 发布就绪度
陌生人在最初 30 秒内会看到的内容:
- README 面向外部读者编写——说明项目是什么、如何运行,不包含“在 #eng 询问团队”之类的指示
- 提供完整的
.env.example,无需内部访问权限即可完成设置 - 文档 不包含指向内部 Wiki、仪表板和运行手册的链接
- Issue 和 PR 模板 不会将请求转交给内部流程
- CI 配置 仅引用 fork 合理可提供的机密信息,不使用内部注册表或运行器
- 测试夹具 使用合成数据,而非生产环境导出数据
- 仓库设置——现有的
.github/配置可能会在CODEOWNERS中暴露内部团队名称
ls README* .env.example .github/ 2>/dev/null
grep -rniE 'internal|confidential|do not distribute|proprietary' README* docs/ 2>/dev/null
cat .github/CODEOWNERS 2>/dev/null
当没有内部访问权限的读者能够根据仓库中的内容完成安装、运行和贡献时,本轮结束。
结论
报告以下两种结果之一。不设中间状态——“基本干净”仍会发布机密信息。
阻止发布 — 列出所有阻止发布的发现项:
BLOCK — 3 blockers
License No LICENSE file; two AGPL dependencies conflict with intended MIT
History AWS key in commit a1b2c3d (deleted in e4f5g6h, still in history)
Private Client name "Acme Corp" in 14 files and 3 commit messages
Rotate now: AWS key AKIA… (leak precedes any rewrite)
Then hand to: git-safety clean — strip .env from all refs, force-push
Re-run this audit after the rewrite; commit hashes will have changed.
发布 — 说明已核实的内容,确保结论可审计:
PUBLISH
License MIT at root; 214 deps all permissive; 2 adapted blocks attributed
History gitleaks + truffleHog clean across 1,847 commits, 12 branches, 40 tags
Private No internal hosts, customer names, or employee emails outside git authorship
Ready README, .env.example, CI runs on a fork without internal secrets
Note: 4 distinct author emails remain in commit history and will be public.
Next: install the ongoing commit-time guard — git-safety prevent
重写会使发现项中的所有提交哈希失效,因此 git-safety 完成后,请重新运行第 2 轮和第 3 轮。
相关工具
git-safety— 用于已投入日常使用的仓库的常规防护工具:阻止机密信息进入下一次提交、限制强制推送和历史重写,并安装忽略规则和提交前钩子。它还会执行本次审计后续交由其处理的凭据轮换和历史重写。每次提交时运行;仅在决定是否发布时运行本次审计。security-audit— 对代码本身进行应用级漏洞审查。
完整的凭据模式目录、涵盖所有引用的历史记录命令(储藏、合并、标签、分支)、许可证兼容性矩阵、私有引用搜索方法和报告模板: references/full-guide.md