关于 gh-code-scanning
gh-code-scanning 是用于读取 GitHub 代码扫描告警的技能,面向仓库安全排查。它通过脚本汇总并按出现次数排序告警,也可限定分支并纳入仍被检测到的已关闭告警。
主要功能
- 01汇总并排序开放告警
- 02按分支筛选结果
- 03纳入仍被检测到的已关闭告警
- 04输出含规则、严重性和受影响路径的 JSON
适用场景
- 01按出现次数确定告警排查顺序
- 02检查指定分支的代码扫描告警
- 03将告警数据交给程序处理
MCP 相关
该技能说明,配置 GitHub MCP server 的 code_security 工具集后,可只读访问代码扫描告警。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ microsoft/ hve-core --skill gh-code-scanning安装后在 Claude Code 中输入/gh-code-scanning确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
SECURITY.mdscripts/get-code-scanning-alerts.shGet-CodeScanningAlerts.ps1tests/Get-CodeScanningAlerts.Tests.ps1详细介绍
GitHub 代码扫描技能
概述
GitHub 代码扫描警报由 CodeQL 和 Scorecard 等静态分析工具生成,并显示在 GitHub Security 选项卡中。默认 MCP 工具集无法访问 GitHub Security 选项卡,因此此技能提供了用于所有读取操作的脚本。
前提条件
| 要求 | 详细信息 |
|---|---|
pwsh | PowerShell 7+;从 https://learn.microsoft.com/powershell 安装 |
gh CLI | 已安装且位于 PATH 中;从 https://cli.github.com 安装 |
| 身份验证 | 运行 gh auth login 或设置 GH_TOKEN;需要 security_events 作用域 |
| 作用域 | 私有仓库需要 security_events;仅限公共仓库时需要 public_repo |
repo 作用域也满足 security_events 的要求。gh CLI 会自动处理身份验证;命令中无需显式传递令牌。
Get-CodeScanningAlerts.ps1 会在启动时验证这两个前提条件,如果任一检查失败,则会中止并显示针对性的错误消息。
快速开始
运行此命令,按出现频率排序,获取开放代码扫描警报的分组摘要。在对仓库的代码扫描状况进行分类时,建议首先运行此命令。
pwsh scripts/Get-CodeScanningAlerts.ps1 -Owner "{owner}" -Repo "{repo}" -OutputFormat Json
此命令会返回按出现次数降序排列的警报组 JSON 数组。以编程方式处理结果时,务必使用 -OutputFormat Json。
参数参考
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
-Owner | String | 是 | 拥有该仓库的 GitHub 组织或用户 | |
-Repo | String | 是 | 仓库名称 | |
-OutputFormat | String | 否 | Table | 输出格式:Agent 以编程方式处理结果时必须使用 Json;GroupedJson 可作为 Json 的别名 |
-Branch | String | 否 | main | 用于限定警报结果范围的分支 |
-IncludeDismissedStillDetected | Switch | 否 | 还会报告分支上仍可检测到的已关闭警报,并将其作为 Kind 设置为 dismissed-still-detected 的组返回 |
这些参数适用于
Get-CodeScanningAlerts.ps1。有关 bash 脚本标志(包括-s {severity}和-d),请参阅下文的“脚本参考”部分。
脚本参考
Get-CodeScanningAlerts.ps1
按出现次数降序对开放代码扫描警报进行分组和排序。
# JSON output for programmatic consumption
pwsh scripts/Get-CodeScanningAlerts.ps1 -Owner "{owner}" -Repo "{repo}" -OutputFormat Json
# Scope to a specific branch
pwsh scripts/Get-CodeScanningAlerts.ps1 -Owner "{owner}" -Repo "{repo}" -Branch "{branch}" -OutputFormat Json
# Also report dismissed alerts that are still detected
pwsh scripts/Get-CodeScanningAlerts.ps1 -Owner "{owner}" -Repo "{repo}" -OutputFormat Json -IncludeDismissedStillDetected
get-code-scanning-alerts.sh
按出现次数降序对开放代码扫描警报进行分组和排序。需要 jq。
# JSON output for programmatic consumption
bash scripts/get-code-scanning-alerts.sh -o "{owner}" -r "{repo}"
# Scope to a specific branch
bash scripts/get-code-scanning-alerts.sh -o "{owner}" -r "{repo}" -b "{branch}"
# Filter by severity
bash scripts/get-code-scanning-alerts.sh -o "{owner}" -r "{repo}" -s critical
# Also report dismissed alerts that are still detected
bash scripts/get-code-scanning-alerts.sh -o "{owner}" -r "{repo}" -d
何时使用此技能
仅当任务涉及读取代码扫描警报时,才使用此技能。Get-CodeScanningAlerts.ps1 是列出和分组代码扫描警报的唯一受支持方法。不得使用 gh api 作为列出或分组操作的后备方案。
当 GitHub MCP 服务配置了 code_security 工具集时,无需使用 gh api 即可只读访问代码扫描警报。可通过 toolsets: all 或显式工具集配置启用。
代码扫描警报
列出并分组未关闭的警报
始终使用 -OutputFormat Json 运行。解析 JSON 输出并呈现给用户。
pwsh scripts/Get-CodeScanningAlerts.ps1 -Owner "{owner}" -Repo "{repo}" -OutputFormat Json
使用 -Branch {branch} 将范围限定为 main 以外的分支。
JSON 输出结构
-OutputFormat Json 会返回一个分组对象数组:
[
{
"RuleDescription": "Empty except",
"RuleId": "py/empty-except",
"Tool": "CodeQL",
"SecuritySeverity": null,
"Severity": "warning",
"Count": 23,
"AffectedPaths": [
"scripts/plugins/Sync-PluginManifest.ps1",
"scripts/linting/Validate-MarkdownFrontmatter.py"
],
"HasFilePaths": true,
"AlertUrl": "https://github.com/microsoft/hve-core/security/code-scanning/42",
"FindingDescription": "'except' clause does nothing but pass and there is no explanatory comment."
},
{
"RuleDescription": "Code injection",
"RuleId": "actions/code-injection/medium",
"Tool": "CodeQL",
"SecuritySeverity": "medium",
"Severity": "error",
"Count": 2,
"AffectedPaths": [
".github/workflows/validate.yml"
],
"HasFilePaths": true,
"AlertUrl": "https://github.com/microsoft/hve-core/security/code-scanning/17",
"FindingDescription": "Potential code injection in ${{ inputs.version }}, which may be controlled by an external user."
},
{
"RuleDescription": "Branch-Protection",
"RuleId": "BranchProtectionID",
"Tool": "Scorecard",
"SecuritySeverity": "high",
"Severity": "error",
"Count": 1,
"AffectedPaths": [],
"HasFilePaths": false,
"AlertUrl": "https://github.com/microsoft/hve-core/security/code-scanning/1",
"FindingDescription": "score is 9: branch protection is not maximal on development and all release branches"
}
]
对于没有安全分类的代码质量规则,SecuritySeverity 为 null;Severity(非安全规则严重级别:error、warning、note、none)提供回退值。AffectedPaths 始终是一个 JSON 数组,其中包含唯一且已排序的文件路径,并已过滤掉哨兵字符串。如果警报没有关联的源文件(例如 BranchProtectionID),则 HasFilePaths 为 false,且 AffectedPaths 为 []。AlertUrl 直接链接到 GitHub Security 选项卡中的警报。FindingDescription 是最新的警报消息文本。
使用 -IncludeDismissedStillDetected(或在 bash 中使用 -d)时,最近一次在该分支上的实例状态不是 fixed 的已忽略警报,会作为单独分组追加在未关闭警报分组之后。这些分组会添加 Kind(dismissed-still-detected)和 DismissedReason;未关闭警报分组不变。忽略警报并不能解决问题,因此应将这些警报作为需要重新打开并修复的警报呈现。
获取单个警报详情
此调用返回一条记录;它不是列表或分组操作,因此不违反上述 gh api 限制。
gh api repos/{owner}/{repo}/code-scanning/alerts/{alert_number}
列出受影响的文件路径
使用 -OutputFormat Json,并从每个规则分组中读取 AffectedPaths 字段。对于每个分组,JSON 输出都包含 RuleDescription、RuleId、Tool、SecuritySeverity、Severity、Count、AffectedPaths(唯一且已排序的文件路径)、HasFilePaths(布尔值:对于没有关联源文件的仓库级规则为 false)、AlertUrl(字符串:指向 GitHub Security 选项卡中警报的直接链接)和 FindingDescription(字符串:分析工具提供的最新警报消息文本)。
关键字段
这些是 GitHub API 响应字段路径,而非输出对象属性。分组输出对象的字段名称见上文的 JSON 输出结构部分。
rule.security_severity_level:安全严重级别:critical、high、medium或low;对于代码质量规则为nullrule.severity:非安全规则严重级别:error、warning、note或none;始终有值rule.id:用于去重和交叉引用的规则标识符tool.name:生成警报的分析工具(例如CodeQL)most_recent_instance.location.path:最近一次警报发生位置的源文件路径
解决策略
在代码或配置中解决警报。切勿忽略警报,也切勿建议忽略警报,包括误报或测试代码中的警报。如果暂时无法修复某项发现,维护者可以添加经过审核、设有到期时间且受追踪的例外;警报仍会保持未关闭状态。采用此策略的仓库会在其代码扫描警报生命周期文档中说明该策略;对于 hve-core,请参阅 https://github.com/microsoft/hve-core/blob/main/docs/security/code-scanning-alert-lifecycle.md。
代码扫描分析
这些调用会检索分析元数据,而非警报列表,因此不违反上述 gh api 限制。
列出最近的分析
返回 main 分支上最近 10 次 CodeQL 运行。
gh api repos/{owner}/{repo}/code-scanning/analyses \
-f tool_name=CodeQL \
-f ref=refs/heads/main \
-f per_page=10
关键字段
created_at:分析运行的时间戳results_count:生成的警报数量rules_count:评估的规则数量tool.version:分析工具的版本warning/error:分析过程中报告的任何问题
创建待办事项
创建前检查重复项
创建新问题之前,使用标题和嵌入式自动化标记搜索现有问题。
existing=$(gh issue list --repo "{owner}/{repo}" \
--search "\"[Security] {rule_description}\" in:title" \
--state open --json number --jq '.[0].number // empty')
if [[ -z "$existing" ]]; then
gh issue create --repo "{owner}/{repo}" \
--title "[Security] {rule_description}" \
--label "security" \
--body "
## Code Scanning Alert: {rule_description}
**Rule:** \`{rule_id}\`
$([ -n "{severity}" ] && echo "**Severity:** {severity}")
**Tool:** {tool}
**Affected files:** {count} occurrences
### Affected paths
{affected_paths}
"
fi
自动化标记 `` 嵌入在问题正文中,用作去重锚点。将所有 {placeholders} 替换为警报分组 JSON 输出中的实际值。
故障排除
| 症状 | 可能原因 | 修复 |
|---|---|---|
gh CLI not found. Install it from https://cli.github.com | gh CLI 不在 PATH 中 | 从 https://cli.github.com 安装,然后重新打开终端 |
gh CLI is not authenticated. Run 'gh auth login' | 尚未完成 gh 身份验证 | 运行 gh auth login;确保已授予 security_events 范围 |
HTTP 403 Resource not accessible by integration | 令牌缺少 security_events 范围 | 重新进行身份验证:gh auth refresh -s security_events,或设置具有相应范围的 GH_TOKEN |
结果为空 [] | ref 格式错误,或该分支没有警报 | 省略 -f ref= 以搜索所有分支,或使用 refs/heads/main 格式(而不只是 main) |
bash: jq: command not found | 未安装 jq | 使用 brew install jq(macOS)、apt-get install jq(Debian/Ubuntu)安装,或从 https://jqlang.github.io/jq/ 获取 |