Kubescape 与 GitHub Code Scanning 集成实战:用 SARIF 把 Kubernetes 安全扫描结果送进代码安全看板
【免费下载链接】kubescapeKubescape is an open-source Kubernetes security platform for your IDE, CI/CD pipelines, and clusters. It includes risk analysis, security, compliance, and misconfiguration scanning, saving Kubernetes users and administrators precious time, effort, and resources.项目地址: https://gitcode.com/GitHub_Trending/ku/kubescape
本指南讲解如何将开源 Kubernetes 安全平台 Kubescape 接入 GitHub Code Scanning——GitHub 原生的安全告警看板。Kubescape 会把对 Kubernetes 清单文件、Helm Chart 与 Kustomize 目录的扫描结果输出为 SARIF(Static Analysis Results Interchange Format)文件,再由 GitHub 解析为Security → Code scanning页面中的告警,并支持在 Pull Request 的Files changed视图中内联标注。读完本文,你将掌握完整的 GitHub Actions 工作流编写方法、合规阈值门禁配置、分支保护规则设置,以及常见故障的排查手段。
集成原理:从扫描结果到 Code Scanning 告警
Kubescape 与 GitHub Code Scanning 的对接建立在 SARIF 这一标准之上。SARIF 是静态分析工具输出的通用交换格式,GitHub Code Scanning 与 Azure DevOps 等平台均可直接消费。整体数据流如下:
Push / PR → GitHub Actions → Kubescape scan → results.sarif → GitHub Security dashboard具体来说,Kubescape 在 GitHub Actions 工作流中扫描仓库内的 Kubernetes 资源,将结果写入.sarif文件;工作流随后通过github/codeql-action/upload-sarif动作把该文件上传给 GitHub;GitHub 解析 SARIF 后,把每一条发现呈现为仓库Security → Code scanning看板中的一条告警。
这一链路在仓库中的底层实现位于 SARIF 输出器 sarifprinter.go,几点实现细节值得了解:
- 严重级别映射:Kubescape 将每个控制项(control)的严重度评分(score factor)映射为 SARIF 的
level。源码scoreFactorToSARIFSeverityLevel(sarifprinter.go)规定:评分 ≥ 9.0 映射为error,≥ 4.0 映射为warning,其余映射为note。因此你在 Code Scanning 中看到的error/warning/note三级告警并非随机,而是由控制项的 base score 决定的。 - 安全严重度属性:每个规则还带
security-severity属性(取值为控制项评分,形如9.0),GitHub Code Scanning 会据此渲染与筛选告警严重度。 - 告警指纹与去重:输出器为每条 finding 计算
kubescapeFindingFingerprint(基于控制 ID、资源 ID、文件相对路径、行号列号及失败证据生成 SHA-256 指纹),GitHub 依据规则 ID 与位置去重,避免同一问题重复刷屏。 - 修复建议:SARIF 结果中会附带
fixes字段,给出基于失败路径(FixPath)的替换建议;同时消息文本会列出受影响字段。敏感字段(如 Secret 数据、容器环境变量值)默认以占位符脱敏,这是有意为之——SARIF 文件常常被上传到 CI 看板或作为流水线产物提交,具体逻辑见 sarifprinter.go 中showSecrets的注释说明。 - 位置解析:告警携带文件路径与精确行号、列号。主位置指向修复点,若失败由多个字段引起,还会为每个失败字段添加
relatedLocations(参见resolveReviewPathLocations)。无法关联到文件路径的结果会被直接跳过,因为 GitHub 不接受无位置的结果。
格式限制(重要):SARIF 格式仅支持扫描本地文件或 Git 仓库,不支持对运行中集群的扫描(集群扫描无文件可定位)。在 CI 中扫描仓库目录正好满足这一前提。
前置条件
- 一个 GitHub 仓库(公开仓库,或已开启 GitHub Advanced Security 的私有仓库);
- 仓库中包含 Kubernetes 清单文件、Helm Chart 或 Kustomize 配置;
- 仓库已启用 GitHub Actions。
注意:GitHub Code Scanning 对公开仓库免费;私有仓库需要 GitHub Advanced Security。
基本示例:一键接入的 Workflow
在仓库中创建.github/workflows/kubescape.yml:
name: Kubescape on: push: branches: - main pull_request: branches: - main jobs: kubescape: name: Scan Kubernetes manifests runs-on: ubuntu-latest permissions: security-events: write # required to upload SARIF results actions: read contents: read steps: - name: Checkout code uses: actions/checkout@v4 - name: Install Kubescape run: | curl -s https://raw.githubusercontent.com/kubescape/kubescape/master/install.sh | bash echo "$HOME/.kubescape/bin" >> "$GITHUB_PATH" - name: Run Kubescape scan run: | kubescape scan . \ --format sarif \ --output results.sarif \ --verbose continue-on-error: true # upload results even when findings are detected - name: Upload SARIF to GitHub Code Scanning uses: github/codeql-action/upload-sarif@v3 with: sarif_file: results.sarif几个关键点:
permissions.security-events: write必不可少,缺少该权限时 SARIF 上传会静默失败,而工作流本身不会报错;--format sarif指定输出格式,--output results.sarif指定输出文件,上传步骤的sarif_file必须与之保持一致;--verbose输出更详细的日志,便于排查;continue-on-error: true保证即使扫描发现大量问题(扫描步骤会返回非零退出码),后续上传步骤依然会执行,告警照常进入看板。
工作流运行结束后,进入仓库的Security → Code scanning即可查看结果。
安装脚本即仓库根目录下的 install.sh(安全产品,建议先阅读脚本内容再执行);更多安装方式见 installation.md。
扫描指定路径:子目录、Helm Chart 与 Kustomize
如果清单文件位于子目录,直接把路径传给 Kubescape:
- name: Install Kubescape run: | curl -s https://raw.githubusercontent.com/kubescape/kubescape/master/install.sh | bash echo "$HOME/.kubescape/bin" >> "$GITHUB_PATH" - name: Run Kubescape scan run: | kubescape scan ./k8s/ \ --format sarif \ --output results.sarif continue-on-error: true也可以扫描 Helm Chart 或 Kustomize 目录,只需指向其根目录。Kubescape 会自动识别:目录中存在Chart.yaml即按 Helm Chart 处理(默认加载values.yaml,可用--helm-values指定自定义 values 文件);存在kustomization.yaml/kustomization.yml/kustomization即按 Kustomize 处理,会先渲染再扫描:
- name: Install Kubescape run: | curl -s https://raw.githubusercontent.com/kubescape/kubescape/master/install.sh | bash echo "$HOME/.kubescape/bin" >> "$GITHUB_PATH" - name: Run Kubescape scan run: | kubescape scan ./charts/my-app/ \ --format sarif \ --output results.sarif continue-on-error: true注意:若目录同时包含
Chart.yaml与kustomization.yaml,Kubescape 会将其视为 Helm Chart。另外,Kustomize 可能跟随扫描根目录之外的引用,嵌套的helmCharts.repo也可能拉取远程 Chart 内容,因此只扫描你信任的源码。
扫描特定合规框架
默认的kubescape scan <path>运行的是综合安全视图(allcontrols)。若要限定到某个合规框架,使用framework子命令:
- name: Install Kubescape run: | curl -s https://raw.githubusercontent.com/kubescape/kubescape/master/install.sh | bash echo "$HOME/.kubescape/bin" >> "$GITHUB_PATH" - name: Run Kubescape scan (NSA framework) run: | kubescape scan framework nsa . \ --format sarif \ --output results.sarif continue-on-error: true内置框架包括nsa(NSA-CISA Kubernetes 加固指南)、mitre(MITRE ATT&CK 容器化威胁矩阵),以及按需下载的 CIS Benchmark 框架(如cis-v1.23-t1.0.1)。运行kubescape list frameworks可查看完整列表——该命令的实现位于 list.go,其帮助文本列出了本地默认框架的查询方式;从源码看,Kubescape 内置的原生框架标识符为allcontrols、nsa、mitre(见 datastructures.go),更多框架(含 CIS)由策略库按需下载。框架子命令的解析入口见 framework.go,支持nsa,mitre这种逗号分隔的多框架组合。
设置合规阈值:让工作流在分数过低时失败
--compliance-threshold用于在合规分数低于阈值时让命令失败(退出码 1)。该标志在 scan.go 中定义:取值是一个百分比(0–100 之间,源码在 framework.go 中对越界值做了校验),默认值为 0;它只对scan framework、scan control、scan workload以及--view resource|control生效,普通的kubectl scan <path>安全视图不会评估该阈值。若低于阈值,框架扫描会以错误scan compliance-score is below permitted threshold结束(见 framework.go)。
与continue-on-error: true组合使用,确保 SARIF 上传仍会执行:
- name: Install Kubescape run: | curl -s https://raw.githubusercontent.com/kubescape/kubescape/master/install.sh | bash echo "$HOME/.kubescape/bin" >> "$GITHUB_PATH" - name: Run Kubescape scan run: | kubescape scan . \ --format sarif \ --output results.sarif continue-on-error: true - name: Upload SARIF to GitHub Code Scanning uses: github/codeql-action/upload-sarif@v3 with: sarif_file: results.sarif - name: Enforce compliance threshold run: | kubescape scan . \ --compliance-threshold 80 \ --format pretty-printer注意:这里有意运行 Kubescape 两次。第一次始终生成 SARIF 文件供上传;第二次应用阈值,当分数低于 80 时该步骤返回失败(未设置
continue-on-error),从而让整个 Job 失败、阻止合并。
注意:旧标志
--fail-threshold(短名-t)已被弃用,源码中它被绑定到独立变量并标记为 deprecated,提示改用--compliance-threshold(见 scan.go),请勿在新工作流中使用。
使用官方 Kubescape GitHub Action
除手动安装外,还可直接使用官方 GitHub Action(仓库kubescape/github-action,本仓库 README 与文档均将其作为推荐接入方式):
name: Kubescape on: push: branches: - main pull_request: branches: - main jobs: kubescape: name: Scan Kubernetes manifests runs-on: ubuntu-latest permissions: security-events: write actions: read contents: read steps: - name: Checkout code uses: actions/checkout@v4 - name: Run Kubescape scan uses: kubescape/github-action@main continue-on-error: true with: format: sarif outputFile: results.sarif args: "." - name: Upload SARIF to GitHub Code Scanning uses: github/codeql-action/upload-sarif@v3 with: sarif_file: results.sarif该动作封装了 Kubescape 的安装与扫描参数:format: sarif对应--format sarif,outputFile: results.sarif对应--output results.sarif,args: "."则是传给kubescape scan的路径参数。
查看 GitHub Security 看板中的结果
工作流完成后:
- 打开仓库首页,点击Security标签;
- 在左侧边栏选择Code scanning;
- 每条 Kubescape 发现都会列作一条告警,包含:
- 控制项名称与 ID(例如
Privileged container/C-0057); - 受影响的文件与行号;
- 严重级别(
error、warning或note,对应关系见前文源码分析); - 指向 Kubescape 控制项文档的修复指引链接(SARIF 规则的
help字段即由控制项的 remediation 说明生成)。
- 控制项名称与 ID(例如
在 Pull Request 上发现的告警还会内联标注在Files changed标签页中,审查者无需跳转即可看到问题所在行。
分支保护规则:阻止引入新问题的 PR 合并
要让引入新安全发现的 PR 无法合并,可配置分支保护规则,要求 Code Scanning 检查通过:
- 进入仓库Settings → Branches;
- 点击Add branch protection rule(或编辑
main分支的既有规则); - 启用Require status checks to pass before merging;
- 搜索并选择 Kubescape 工作流检查(例如
Kubescape / Scan Kubernetes manifests); - 可选:启用Require branches to be up to date before merging;
- 点击Save changes。
规则生效后,Kubescape 工作流检查必须通过,PR 才能合并。
注意(关于 continue-on-error 与门禁的配合):基本示例与官方 Action 示例都在扫描步骤使用了
continue-on-error: true——它会把步骤标记为失败但让整个 Job 成功,而分支保护以 Job 结论为准,因此这两类工作流无论发现多少问题,检查都会通过。若要让安全发现真正阻止合并,应使用上文"设置合规阈值"的模式:专门的Enforce compliance threshold步骤不带continue-on-error,阈值不达标即让 Job 失败。另外,也可以在Settings → Code security → Code scanning中配置失败严重度(failure severity),让 GitHub 本身在达到该严重度的告警时阻止合并。
故障排查
Security 标签页中没有告警
- 在Actions标签页确认工作流是否成功运行;
- 确认
permissions块包含security-events: write——缺少该权限时 SARIF 上传会静默失败; - 私有仓库需在Settings → Security & analysis中确认已启用 GitHub Advanced Security;
- 确认上传步骤的
sarif_file路径与扫描步骤的--output路径一致。
results.sarif: no such file or directory
扫描步骤在写出文件之前就失败了。查看工作流日志,常见原因:
kubescape: command not found——安装后 PATH 未持久化,确认 Install 步骤包含echo "$HOME/.kubescape/bin" >> "$GITHUB_PATH";- 扫描路径下没有找到 Kubernetes 清单文件;
- Kubescape 安装失败(网络问题或缺少
curl/bash)。
可在扫描命令后添加--verbose获取详细输出。
设置了continue-on-error: true但扫描仍以退出码 1 结束
这是预期行为。continue-on-error: true允许后续步骤继续执行,但会把该步骤标记为失败;只要后续步骤(包括 SARIF 上传)正常完成,整个 Job 依然成功。
多次运行后出现重复告警
GitHub 依据规则 ID 与位置对 Code Scanning 告警去重。若出现重复,检查是否为同一提交同时上传了push与pull_request两次事件的结果。
告警严重度显示为none
Kubescape 将控制项严重度映射为 SARIF 级别(见前文scoreFactorToSARIFSeverityLevel的映射规则)。如果控制项没有严重度信息,请确认 Kubescape 版本为 v3 或更高:
kubescape version延伸阅读
- 官方 GitHub Action:
kubescape/github-action(可通过uses: kubescape/github-action@main直接引用); - 更多 SARIF 输出细节与格式对照,可阅读 getting-started.md 中的 Output Formats 一节(JSON、JUnit、SARIF、HTML、PDF);
- Kubescape 命令参考:cli-reference.md;
- 其他 CI 集成(Azure DevOps、CircleCI、GitLab CI)可参考 azure-pipelines.md、circleci.md、gitlab-ci.md;
- 控制项库与修复指引:仓库 rules 目录收录了每个控制项的
raw.rego规则与rule.metadata.json元数据,可离线查阅控制项 ID、描述与修复建议。
【免费下载链接】kubescapeKubescape is an open-source Kubernetes security platform for your IDE, CI/CD pipelines, and clusters. It includes risk analysis, security, compliance, and misconfiguration scanning, saving Kubernetes users and administrators precious time, effort, and resources.项目地址: https://gitcode.com/GitHub_Trending/ku/kubescape
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考