关于 oss-hygiene
oss-hygiene 是用于改善公开 GitHub 仓库社区规范和供应链基线的技能,面向维护者。它可补齐社区文件、配置部分 OpenSSF Scorecard 相关工作流,并检查安全设置;覆盖 OpenSSF Best Practices Badge 的准备,但不代替项目所有者填写徽章。
主要功能
- 01补齐社区规范文件和 issue 模板
- 02配置 Dependabot 与供应链工作流
- 03审查工作流权限及危险模式
- 04检查并启用 GitHub 安全功能
- 05提示 OpenSSF 最佳实践徽章注册
适用场景
- 01为公开仓库补充贡献指南和安全政策
- 02为项目配置依赖更新与依赖审查
- 03检查 GitHub Actions 权限和不安全写法
- 04准备仓库的 OpenSSF 徽章注册材料
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ paulnsorensen/ git-gouda --skill oss-hygiene安装后在 Claude Code 中输入/oss-hygiene确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/CODE_OF_CONDUCT.mdCONTRIBUTING.mdREADME-badge-snippet.mdSECURITY.mdassets/.github/dependabot.ymlPULL_REQUEST_TEMPLATE.mdassets/.github/ISSUE_TEMPLATE/bug_report.ymlconfig.ymlfeature_request.ymlassets/.github/workflows/codeql.ymldependency-review.ymlscorecard.ymlevals/evals.jsonreferences/badge-criteria.mdcommunity-standards.mddependabot.mdscorecard-checks.mdworkflow-hardening.md详细介绍
oss-hygiene
让公开的 GitHub 仓库达到 GitHub 社区标准的基线和 OpenSSF Scorecard 供应链基线,并为申请 OpenSSF 最佳实践徽章做好准备。
此工具与 /gh-bootstrap 配合使用,但解决的是另一个问题:gh-bootstrap 锁定合并入口;oss-hygiene 完善面向贡献者和供应链的部分。
此技能的适用场景
| 关注事项 | 技能 |
|---|---|
| 合并按钮、分支保护、发布说明配置 | /gh-bootstrap |
| 社区文件、供应链检查、OSSF 安全状况 | /oss-hygiene(此技能) |
| 以代码形式管理多个仓库的组织级设置 | /safe-settings |
本目录不涉及单项 PR、议题或 CI 运维。
先运行 /gh-bootstrap(锁定 main),然后运行 /oss-hygiene(让贡献者了解如何参与,并通过供应链检查来管控 PR)。
配置内容
此技能针对三个相互独立的方面进行操作。它会将每个文件与 assets/ 模板进行比较,并在覆盖任何现有文件前征求确认。
方面 1 — GitHub 社区标准
仓库 Insights 下的“Community Standards”选项卡会显示这些文件。缺少文件将无法通过检查清单。
| 文件 | 源资源 | 用途 |
|---|---|---|
README.md | (不提供脚手架 — 仓库有自己的 README) | 仅检查是否存在 |
LICENSE | (不提供脚手架 — 需自行选择许可证) | 仅检查是否存在 |
CODE_OF_CONDUCT.md | assets/CODE_OF_CONDUCT.md | Contributor Covenant 2.1 |
CONTRIBUTING.md | assets/CONTRIBUTING.md | 如何提交议题、创建 PR、运行测试 |
SECURITY.md | assets/SECURITY.md | 漏洞报告(私密安全公告) |
.github/ISSUE_TEMPLATE/bug_report.yml | assets/.github/ISSUE_TEMPLATE/bug_report.yml | 结构化错误报告表单 |
.github/ISSUE_TEMPLATE/feature_request.yml | assets/.github/ISSUE_TEMPLATE/feature_request.yml | 结构化功能请求表单 |
.github/ISSUE_TEMPLATE/config.yml | assets/.github/ISSUE_TEMPLATE/config.yml | 禁用空白议题、设置联系链接 |
.github/PULL_REQUEST_TEMPLATE.md | assets/.github/PULL_REQUEST_TEMPLATE.md | PR 检查清单 |
如果缺少 LICENSE,不要悄悄创建脚手架文件。许可证选择(MIT、Apache-2.0、AGPL-3.0 等)需要由用户决定——指出这一缺失,并将用户引导至 https://choosealicense.com/。
如果 README 缺失或内容过于单薄,应提示用户,但不要自动生成。README 应体现项目自身的风格。
表面 2 — 供应链(Scorecard 检查)
OpenSSF Scorecard 会运行约 18 项自动检查。该技能会配置其中与脚手架相关的检查:
| Scorecard 检查 | 风险 | 操作 |
|---|---|---|
Security-Policy | 中 | SECURITY.md(表面 1) |
License | 低 | LICENSE(表面 1,仅表面) |
Dependency-Update-Tool | 高 | assets/.github/dependabot.yml |
Branch-Protection | 高 | 由 /gh-bootstrap 规则集覆盖 |
Code-Review | 高 | 由 /gh-bootstrap PR 规则覆盖 |
CI-Tests | 低 | 仓库现有的 CI |
Token-Permissions | 高 | 审核现有工作流中的 permissions: 块;仅报告 |
Dangerous-Workflow | 严重 | 仅审核 — 对 pull_request_target 与 actions/checkout 检出 head ref 的组合发出警告 |
SAST | 中 | assets/.github/workflows/codeql.yml(适用时) |
Pinned-Dependencies | 中 | 仅报告 — 依赖固定因生态系统而异,且存在争议 |
Maintained | 高 | 被动检查 — 随实际活动逐渐体现 |
Binary-Artifacts | 高 | 扫描目录树中的 .so、.dll、.jar、.exe、.zip、.tgz;发出警告 |
Vulnerabilities | 高 | 被动检查 — 由 Dependabot 警报处理 |
Signed-Releases | 高 | 仅报告 — sigstore 配置因项目而异 |
Fuzzing | 中 | 仅报告 — 因语言而异 |
Packaging | 中 | 仅报告 — 取决于发布流水线 |
Contributors | 低 | 被动检查 |
CII-Best-Practices | 低 | 表面 3 |
此外,还有不会写入仓库文件的 GitHub 原生代码安全功能:
| 功能 | 启用方式 | 操作 |
|---|---|---|
| Dependabot 警报 | 仓库设置 → Advanced Security(公开仓库默认自动启用) | 通过 API 验证 |
| Secret scanning 警报(针对用户) | 仓库设置 → Advanced Security(公开仓库免费,需主动启用) | 通过 API 启用 |
| 推送保护(secret scanning) | 仓库设置 → Advanced Security | 通过 API 启用 |
| 依赖关系图 | 仓库设置 → Security(公开仓库默认自动启用) | 通过 API 验证 |
| Dependency Review Action | assets/.github/workflows/dependency-review.yml | 配置脚手架 |
| Scorecard 发布 | assets/.github/workflows/scorecard.yml | 配置脚手架(上传供徽章使用的 SARIF) |
表面 3 — OpenSSF Best Practices 徽章
此徽章需在 https://www.bestpractices.dev 上自行申报。该技能不会代为填写 — 项目所有者必须自行完成。该技能会:
- 检查仓库是否已有徽章(在 README 中查找徽章 URL)。
- 输出预填仓库 URL 的注册链接。
- 建议将徽章 Markdown 添加到 README(
assets/README-badge-snippet.md)。
该徽章是 Scorecard 的 CII-Best-Practices 检查启用器 — 即使只注册到进行中级别,也是提升该评分最省力的方式。
协议
1. 确认范围并检查当前状态
gh auth status
gh repo view --json nameWithOwner,visibility,isPrivate,licenseInfo,description
gh api "repos/$REPO/community/profile" --jq '{
health_percentage,
files: (.files | to_entries | map(select(.value != null)) | from_entries | keys)
}'
gh api "repos/$REPO/vulnerability-alerts" 2>/dev/null && echo "dependabot alerts: ON" || echo "dependabot alerts: OFF"
gh api "repos/$REPO" --jq '{
secret_scanning: .security_and_analysis.secret_scanning.status,
push_protection: .security_and_analysis.secret_scanning_push_protection.status
}'
一次性向用户提出一个合并后的问题,将所有选项内联其中。不要逐项提问;用户应能回复“采用默认设置”后继续执行。列表最多包含以下项目(≤5):
- 可见性——此技能面向公开仓库。私有仓库可使用其中一部分(社区文件可以使用;秘密扫描需要 Advanced Security;发布 scorecard 需要仓库公开,徽章才能显示)。
- 许可证——如果
licenseInfo为 null,提示用户选择许可证,并暂停操作。 - CodeQL 适用性——仓库是否包含 CodeQL 支持的语言代码(
actions、c-cpp、csharp、go、java-kotlin、javascript-typescript、python、ruby、swift)?如果没有,则跳过 CodeQL 工作流。如果唯一匹配项是 CI 辅助脚本(例如.github/scripts/*.py),只提供建议,不要强制提问——这些不是项目代码,默认应跳过,由用户选择是否启用。 - FUNDING.yml——用户是否接受赞助?如果接受,询问平台和账号名(GitHub Sponsors、Buy Me a Coffee、Ko-fi、OpenCollective 等)。
- CODEOWNERS——仅当仓库有多位维护者时才建议添加。个人维护者则跳过。
- 联系邮箱——询问用于安全问题/行为准则问题报告的邮箱。如果用户未提供,则不要在
CODE_OF_CONDUCT.md或SECURITY.md中写入字面量{{CONTACT_EMAIL}}占位符;在生成这两个文件前暂停并询问。
2. 生成社区文件
按顺序处理 assets/ 下的每个文件:
CODE_OF_CONDUCT.md
CONTRIBUTING.md
SECURITY.md
.github/ISSUE_TEMPLATE/bug_report.yml
.github/ISSUE_TEMPLATE/feature_request.yml
.github/ISSUE_TEMPLATE/config.yml
.github/PULL_REQUEST_TEMPLATE.md
与现有文件(如果存在)进行差异比较。如果内容不同,先询问是否覆盖。替换 {{REPO}}、{{OWNER}}、{{CONTACT_EMAIL}} 占位符。
CONTRIBUTING.md 包含通用骨架——请提醒用户合并后将其改为适合项目的内容。
3. 生成供应链工作流
| 资源 | 目标位置 | 跳过条件 |
|---|---|---|
assets/.github/dependabot.yml | .github/dependabot.yml | 从不(始终有用) |
assets/.github/workflows/dependency-review.yml | .github/workflows/dependency-review.yml | 未启用 Code Security 的私有仓库 |
assets/.github/workflows/scorecard.yml | .github/workflows/scorecard.yml | 私有仓库(徽章需要公开仓库) |
assets/.github/workflows/codeql.yml | .github/workflows/codeql.yml | 仓库没有 CodeQL 支持的语言 |
生成 codeql.yml 时,将 language 矩阵中的 {{CODEQL_LANGUAGES}} 替换为在仓库中检测到的 CodeQL 支持语言(以逗号分隔并加引号,例如 "python", "go")。
dependabot.yml 会根据在仓库中检测到的语言包进行配置(查找 package.json、Cargo.toml、pyproject.toml、go.mod、Gemfile、composer.json、pom.xml 等),并添加 github-actions 生态系统条目,以保持工作流中的操作版本为最新。
清单检测范围。 仅统计项目源代码根目录中的清单——不统计 .github/scripts/、.devcontainer/、tools/ci/ 或其他 CI 辅助路径下的清单。项目根目录下的 pyproject.toml 是有效清单;工作流中的硬编码 pip install foo==1.2.3 则不是,Dependabot 无法在没有实际顶层清单的情况下跟踪它。如果唯一的语言代码出现在 CI 辅助代码中,跳过该生态系统,并在生成的 dependabot.yml 中添加一行注释说明原因(例如:“没有顶层 Python 清单;唯一的 Python 代码位于 .github/scripts/”)。这与第 1 步中用于判断 CodeQL 适用性的规则一致。
4. 切换 GitHub 原生安全功能
使用 gh api 启用或验证(幂等——重复应用不会产生变化):
# Automated security fixes / Dependabot security updates
gh api -X PUT "repos/$REPO/automated-security-fixes"
# Vulnerability alerts (Dependabot alerts)
gh api -X PUT "repos/$REPO/vulnerability-alerts"
# Secret scanning alerts for users + push protection
gh api -X PATCH "repos/$REPO" \
-F security_and_analysis[secret_scanning][status]=enabled \
-F security_and_analysis[secret_scanning_push_protection][status]=enabled
# Private vulnerability reporting
gh api -X PUT "repos/$REPO/private-vulnerability-reporting"
如果无法启用私有漏洞报告,则在写入 SECURITY.md 前,必须向用户索取有效的联系邮箱——不要退而使用占位报告渠道。
对于私有仓库,如果未付费启用 GitHub Code Security,这些操作可能会返回 403——提示用户并跳过,不要因此失败。
5. 审核现有工作流中的 Token-Permissions 和 Dangerous-Workflow
这是检测,而非修改。该技能会读取每个 .github/workflows/*.yml:
- Token-Permissions: 标记没有顶层
permissions:块(或设置为permissions: write-all)的工作流。建议使用安全默认值permissions: { contents: read },并仅提升每个作业所需的权限。 - Dangerous-Workflow: 标记
pull_request_target与检出actions/checkout的 head SHA 这一不安全模式,以及任何将github.event.*输入插值到 shell 脚本中的${{ ... }}。
打印发现的问题;不要自动编辑。这些细微更改应由用户审核。
6. 展示 OpenSSF Best Practices Badge 步骤
打印,不要应用。项目注册后,替换 <owner>、<repo> 和项目 ID。读取 assets/README-badge-snippet.md,如果第 3 步跳过了 CodeQL,则移除 和 标记之间的内容——设置这些标记,正是为了能够明确地按条件裁剪代码片段。
Register at: https://www.bestpractices.dev/en/projects/new
Repo URL: https://github.com/<owner>/<repo>
Once you have a project ID, paste this into README.md:
[](https://scorecard.dev/viewer/?uri=github.com/<owner>/<repo>)
[](https://www.bestpractices.dev/projects/<id>)
该技能不会代用户注册项目——注册涉及凭据和判断,需要用户如实填写答案。
7. 验证并报告
重新读取社区资料和工作流文件。打印一份简短摘要:
gh api "repos/$REPO/community/profile" --jq '{health_percentage, missing: ([.files | to_entries[] | select(.value == null) | .key])}'
gh api "repos/$REPO/private-vulnerability-reporting"
ls .github/workflows/ | sort
摘要应说明:
- 创建了哪些文件(以及与现有文件相比的差异,如有)
- 哪些内容原本就正确(未作更改)
- 跳过了哪些内容及原因(没有 LICENSE、私有仓库、没有适用 CodeQL 的语言等)
- OSSF Badge 注册链接
幂等性
- 文件:覆盖前先进行差异比较;如果内容不同,应先询问。
- API 开关:
PUT/PATCH具有幂等性。 - 工作流审核:只读——重新运行只会再次打印相同的发现。
- 绝不删除:如果之前的运行留下了某个产物(名称不同的旧工作流),应将其指出并让用户决定。
此技能不适用于
- 选择许可证——它会指出缺失项,但不会替你选择
- 编写 README——内容应体现项目自身的风格
- 组织范围的社区文件——使用
/safe-settings - 分支保护 / 合并队列——使用
/gh-bootstrap - Sigstore 发布签名——特定于语言和流水线,不在范围内
- 填写 OSSF Best Practices Badge 问卷——这是维护者的确认
- 固定依赖项——因生态系统而异,且常有争议
- 设置模糊测试——特定于语言
注意事项
- 默认社区健康文件:如果用户/组织拥有包含这些文件的
.github仓库,这些文件会应用于所有没有自己副本的仓库。将模板文件放入仓库会覆盖组织默认设置;只有在确实需要针对单个仓库设置覆盖项时才这样做。 - Dependency Review Action:在公开仓库中可免费使用,在私有仓库中则仅适用于 GitHub Advanced Security。该工作流在私有免费版仓库中会直接失败。
- Scorecard 工作流:通过 OIDC 向 scorecard.dev 发布需要
id-token: write;模板文件已配置正确权限。如果工作流首次运行时因 403 失败,则用户受到组织级 OIDC 限制。 - CodeQL setup-mode:
default设置需在 GitHub UI 中配置(Settings → Code security → CodeQL → Set up)。模板文件使用advanced设置(工作流文件)。两者互斥——如果用户先启用了默认设置,工作流文件就会冲突。 - Token-Permissions 审计:
softprops/action-gh-release等操作以及许多发布操作都需要contents: write。不要建议用户将每个工作流都设为只读——应指出并解释所需权限。 pull_request_target默认存在危险:不要仅仅为了在 fork PR 中访问机密而使用它。此技能会标记这一点;用户应改用独立的workflow_run或带标签的 PR 模式。- OSSF 徽章由项目自行申报:徽章通过表示维护者回答了相关问题,而非进行过审计。这是一项参考信号,并非保证。
- 小型/新建仓库的 Scorecard 分数:
Maintained检查要求有 90 天的活动记录;新仓库在积累足够时间前分数会较低。这是预期表现,并非错误。 - 固定工作流的维护:模板工作流使用经过审核的提交 SHA。Dependabot 可以附上版本注释并提出 SHA 更新;合并前请审核这些 PR,并确保校验和或固定版本的依据保持最新。
参考资料
references/scorecard-checks.md— 完整列出全部 18 项 Scorecard 检查、衡量内容及修复建议。references/badge-criteria.md— OpenSSF Best Practices Badge 通过标准与仓库文件的对应关系。references/community-standards.md— GitHub 自带的检查清单,以及各文件的检测方式。references/dependabot.md—dependabot.yml架构参考及各生态系统示例。references/workflow-hardening.md— Token-Permissions 和危险工作流规则及具体示例。