一、技能概述
该技能专门用于处理 GitHub Secret Scanning 产生的告警。当 GitHub 检测到仓库中有明文密钥(如 Discord Bot Token、Feishu App Secret 等)被提交或评论时,该技能提供了一套完整的处理流程:识别泄露位置、脱敏或删除敏感内容、清理编辑历史痕迹、通知相关用户,并最终关闭告警。
核心原则:
-
所有通知和替换评论必须使用英文
-
维护者专属:需要仓库管理员/维护者权限才能编辑或删除其他用户的评论并关闭告警
-
机械操作由脚本执行:所有 API 调用、临时文件管理、安全强制措施均由
secret-scanning.mjs脚本处理
二、核心功能
1. 告警识别与内容获取
技能首先列出所有未关闭的告警,然后获取特定告警的元数据和泄露位置:
# 列出所有未关闭的告警
node secret-scanning.mjs list-open
# 获取特定告警的元数据 + 位置
node secret-scanning.mjs fetch-alert <alert_number>
# 获取每个位置的内容(将 body 保存到临时文件)
node secret-scanning.mjs fetch-content '<location_json>'
fetch-content 的输出包含:
-
body_file:包含完整内容的临时文件路径 -
author:内容发布者 -
issue_number/pr_number:所在 Issue 或 PR -
edit_history_count:现有编辑次数 -
type:位置类型,用于路由后续操作
2. 位置类型路由
不同类型的内容采用不同的处理方式:
| 位置类型 | 处理方式 |
|---|---|
issue_comment |
评论:删除 + 重建 |
pull_request_comment |
评论:删除 + 重建 |
pull_request_review_comment |
评论:删除 + 重建 |
discussion_comment |
Discussion 评论:删除 + 重建(使用 GraphQL) |
issue_body |
Issue 正文:原地脱敏 |
pull_request_body |
PR 正文:原地脱敏 |
commit |
仅通知,无法清理 |
other |
跳过并报告 |
3. 决策与脱敏(唯一需要语义理解的步骤)
Agent 读取 fetch-content 输出的 body 文件,并执行以下操作:
-
识别内容中所有密钥(可能不止告警标记的那一个)
-
判断当前正文中是否仍存在明文凭证
-
将每个剩余密钥替换为
[REDACTED]——不保留任何部分值、不保留前缀/后缀 -
将脱敏后的内容保存到新的临时文件
对于 issue_body 和 pull_request_body:如果当前正文已被作者自行脱敏且不再包含明文凭证,则不发布公开通知评论,仅以维护者专用备注关闭告警。
4. 评论清理(删除 + 重建,不保留编辑历史)
对于评论类型(issue_comment、PR 评论等):
-
不进行 PATCH 脱敏——直接跳到删除+重建
-
先删除原评论(所有编辑历史一并消失)
-
再用脱敏后的内容重建评论
-
重建的评论格式为:
Note: The original comment by @{author} has been removed due to secret leakage. Below is the redacted version of the original content.
对于 Discussion 评论,使用 GraphQL 删除和重建,并保留原始回复线程位置。
5. Issue/PR 正文脱敏(无法清除编辑历史)
对于 issue_body 和 pull_request_body:
-
使用
redact-body-if-needed命令进行原地 PATCH 脱敏 -
⚠️ 关键限制:编辑会创建包含明文内容的编辑历史版本,无法通过 API 清除
-
不要公开建议作者删除/重建 Issue 或关闭/重开 PR——这会吸引对历史内容的关注
-
脱敏指导仅限维护者终端输出,绝不出现在公开评论中
-
输出到维护者终端:
⚠️ Issue/PR body edit history still contains plaintext secrets. Contact GitHub Support to purge: https://support.github.com/contact[reference:17]
-
关键:绝不在任何公开评论或
resolution_comment中提及编辑历史或“edited”按钮
6. 通知
对于 issue_body 和 pull_request_body,仅在当前正文仍包含明文且维护者进行了脱敏时才发送通知。如果用户已自行脱敏,则跳过此步骤并静默关闭告警。
通知模板根据位置类型自动选择:
-
评论类型:“your comment … removed and replaced”
-
正文类型:“your issue/PR description … redacted in place”
-
Commit:“code you committed”
7. 关闭告警
# 默认使用 "revoked" 理由关闭
node secret-scanning.mjs resolve <alert_number>
# 或使用自定义备注
node secret-scanning.mjs resolve <alert_number> revoked "Custom comment"
revoked 的含义是“此密钥应视为已泄露”,不是“我确认它已被撤销”。维护者的责任是移除当前的明文暴露并通知,而非确保用户已轮换密钥。
8. 汇总报告
处理完成后,创建 JSON 结果文件并传递给 summary 命令:
node secret-scanning.mjs summary /tmp/results.json
脚本输出由 ---BEGIN SUMMARY--- 和 ---END SUMMARY--- 标记的内容块,必须逐字输出,不得重新措辞、重新格式化、缩写或创建自己的摘要。
三、主要用途
-
处理 GitHub Secret Scanning 告警:当 GitHub 检测到仓库中有明文密钥泄露时,快速响应并清理
-
评论中的密钥泄露清理:删除包含密钥的评论并重建脱敏版本,彻底清除编辑历史
-
Issue/PR 正文中的密钥脱敏:对正文进行原地脱敏,并告知维护者需联系 GitHub Support 清除编辑历史
-
通知泄露者:通过自动化的通知模板告知相关用户其内容已被清理
-
批量处理告警:支持按升序逐个或批量处理多个告警
-
维护者专属操作:所有删除、重建和关闭操作均需维护者权限
四、安全规则
技能强制执行以下安全规则:
| 规则 | 说明 |
|---|---|
| Agent 只读内容、识别密钥、生成脱敏 | 脚本处理所有 API 调用 |
| 绝不公开密钥的任何部分 | 不在公开评论、脱敏标记或终端输出中包含任何密钥片段 |
| 绝不公开告警 URL 或编号 | 不在公开评论中包含告警链接或编号 |
| 评论跳过 PATCH,直接 DELETE + 重建 | 避免创建不必要的编辑历史版本 |
| 绝不提及编辑历史 | 不在任何公开内容中提及编辑历史、“edited”按钮或 commit SHA |
| 删除前需确认 | 删除任何评论前需征得确认 |
| 逐个处理告警 | 除非用户明确要求批量处理 |
| 所有公开评论用英文 | |
| 跳过不支持的类型并报告 | 在摘要中说明 |
五、总结
OpenClaw Secret Scanning Maintainer 是 OpenClaw 项目中专门用于处理 GitHub Secret Scanning 告警的维护者技能,覆盖从告警识别、内容获取、密钥脱敏、评论删除与重建、正文 PATCH 脱敏、通知发送到告警关闭的完整工作流。它通过脚本化的机械操作和 Agent 的语义理解相结合,确保敏感信息被彻底清理,同时严格遵循安全规则——绝不公开密钥、告警 URL 或编辑历史信息。该技能适用于 OpenClaw 维护者在收到 GitHub Secret Scanning 告警时快速响应并清理泄露密钥的场景。