流水线参考
本文档提供 CAST DevSecOps 流水线的完整技术参考。
目录
概述
CAST DevSecOps 流水线是一个 GitHub Actions 工作流,在每次推送和向主分支发起 Pull Request 时运行六个作业。
Trigger: push / pull_request / workflow_dispatch
│
├── Job 1: secrets (Gitleaks) ─┐
├── Job 2: sast (Semgrep) │ Run in parallel
├── Job 3: sca (pip-audit) │
├── Job 4: container (Trivy) ─┘
├── Job 5: quality (Ruff)
│
└── Job 6: gate (Security Gate) ← waits for 1, 2, 3, 5
作业参考
1. 密钥检测
作业 ID:secrets
运行器:ubuntu-latest
工具:Gitleaks v2
功能说明
扫描仓库的完整 Git 历史,检测硬编码的密钥、API 密钥、令牌、密码及其他凭证。Gitleaks 使用一套全面的正则表达式模式,能检测超过 150 种类型的密钥。
配置
secrets:
name: Secrets Detection
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history — critical for catching old commits
- name: Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
关键配置项
| 配置项 | 值 | 原因 |
|---|---|---|
fetch-depth: 0 |
完整历史 | Gitleaks 扫描所有提交,而非仅扫描最新提交 |
GITHUB_TOKEN |
自动提供 | 用于公开仓库的请求频率限制规避 |
失败行为
- 若任何提交中检测到密钥则失败
- 通过安全门禁阻止合并
抑制误报
在仓库根目录添加 .gitleaks.toml:
[allowlist]
description = "Allowlist"
regexes = [
'''false-positive-pattern''',
]
paths = [
'''path/to/test/fixtures''',
]
2. SAST
作业 ID:sast
运行器:ubuntu-latest(容器化)
工具:Semgrep
功能说明
执行静态应用程序安全测试(SAST)——在不执行代码的情况下,分析源代码中的安全漏洞、不安全模式和常见编码错误。
配置
sast:
name: SAST
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v4
- name: Semgrep scan
run: semgrep ci --sarif --output=semgrep.sarif || true
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
- name: Upload to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: semgrep.sarif
关键配置项
| 配置项 | 值 | 原因 |
|---|---|---|
semgrep/semgrep 容器 |
官方镜像 | 确保使用正确的 Semgrep 版本 |
|| true |
始终退出码为 0 | 发现结果通过 SARIF 上报,而非退出码 |
SEMGREP_APP_TOKEN |
可选密钥 | 启用云端规则;未配置则回退到开源规则 |
上传步骤的 if: always() |
始终上传 | 即使扫描有发现,也确保 SARIF 被上传 |
SARIF 集成
发现结果上传至 GitHub Security 标签页后,将以以下形式呈现:
- 仓库的代码扫描告警
- Pull Request 差异视图上的内联标注
可选:Semgrep Cloud
将 SEMGREP_APP_TOKEN 配置为 GitHub Actions 密钥以启用:
- 额外的专有规则集
- 在 Semgrep 看板中进行历史追踪
- 团队级别的发现管理
3. SCA
作业 ID:sca
运行器:ubuntu-latest
工具:pip-audit
功能说明
执行软件成分分析(SCA)——对照已知漏洞数据库(PyPI Advisory Database、OSV)检查您的 Python 依赖项。
配置
sca:
name: SCA
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.x"
cache: pip
- name: pip-audit
uses: pypa/gh-action-pip-audit@v1
with:
inputs: requirements*.txt
关键配置项
| 配置项 | 值 | 原因 |
|---|---|---|
cache: pip |
已启用 | 加速后续运行 |
inputs: requirements*.txt |
通配符模式 | 扫描所有 requirements 文件 |
失败行为
- 若任何依赖项存在已知 CVE 则失败
- 通过安全门禁阻止合并
自定义
若要扫描 pyproject.toml 中的依赖项而非 requirements 文件:
- uses: pypa/gh-action-pip-audit@v1
with:
inputs: pyproject.toml
4. 容器安全
作业 ID:container
运行器:ubuntu-latest
工具:Trivy
功能说明
扫描 Docker 镜像中操作系统软件包和应用程序依赖项的已知 CVE。若仓库中不存在 Dockerfile,该作业将自动跳过。
配置
container:
name: Container Security
runs-on: ubuntu-latest
if: hashFiles('Dockerfile') != ''
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t cast-scan:${{ github.sha }} .
- name: Trivy scan
uses: aquasecurity/trivy-action@master
with:
image-ref: cast-scan:${{ github.sha }}
format: sarif
output: trivy.sarif
severity: CRITICAL,HIGH
exit-code: "0"
- name: Upload to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: trivy.sarif
关键配置项
| 配置项 | 值 | 原因 |
|---|---|---|
hashFiles('Dockerfile') != '' |
条件判断 | 若无 Dockerfile 则优雅跳过 |
severity: CRITICAL,HIGH |
过滤器 | 聚焦于可操作的发现 |
exit-code: "0" |
不退出 | 由门禁作业处理阻断逻辑 |
github.sha 标签 |
唯一标签 | 防止并发运行时发生冲突 |
失败行为
- 不会直接阻止合并——发现结果通过 SARIF 上报
- 若要添加阻断行为,请将
container加入门禁作业的needs数组
5. 代码质量
作业 ID:quality
运行器:ubuntu-latest
工具:Ruff
功能说明
运行 Ruff——一款极速 Python 代码检查器和格式化工具——以强制执行代码风格规范并捕获常见错误。
配置
quality:
name: Code Quality
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/ruff-action@v1
自定义
Ruff 从 pyproject.toml 或 ruff.toml 读取配置:
# pyproject.toml
[tool.ruff]
target-version = "py39"
line-length = 100
[tool.ruff.lint]
select = ["E", "F", "W", "I"]
ignore = ["E501"]
失败行为
- 若发现任何代码检查错误则失败
- 默认情况下不阻止合并(未包含在门禁的
needs数组中) - 若要在质量检查失败时阻止合并,请将
quality添加到门禁的阻断条件中
6. 安全门禁
作业 ID:gate
运行器:ubuntu-latest
依赖:secrets、sast、sca、quality
功能说明
汇总所有安全作业的结果,并做出单一的通过/失败决策。GitHub 分支保护规则应以此作业为目标。
配置
gate:
name: Security Gate
runs-on: ubuntu-latest
needs: [secrets, sast, sca, quality]
if: always()
steps:
- name: Evaluate results
run: |
echo "secrets : ${{ needs.secrets.result }}"
echo "sast : ${{ needs.sast.result }}"
echo "sca : ${{ needs.sca.result }}"
echo "quality : ${{ needs.quality.result }}"
if [[ "${{ needs.secrets.result }}" == "failure" ||
"${{ needs.sast.result }}" == "failure" ||
"${{ needs.sca.result }}" == "failure" ]]; then
echo "❌ Security gate failed — merge blocked"
exit 1
fi
echo "✅ All checks passed — safe to merge"
门禁决策矩阵
| 密钥检测 | SAST | SCA | 门禁结果 |
|---|---|---|---|
| ✅ 通过 | ✅ 通过 | ✅ 通过 | ✅ 允许合并 |
| ❌ 失败 | ✅ 通过 | ✅ 通过 | ❌ 阻止合并 |
| ✅ 通过 | ❌ 失败 | ✅ 通过 | ❌ 阻止合并 |
| ✅ 通过 | ✅ 通过 | ❌ 失败 | ❌ 阻止合并 |
| 任意 | 任意 | 任意 | ❌ 阻止合并(以上任一失败) |
注意:代码质量(Ruff)失败会被上报,但在默认配置下不会阻止合并。
通过分支保护强制执行门禁
若要将安全门禁设为 Pull Request 的强制要求:
- 进入 Settings → Branches → Branch protection rules
- 为
main(或master)添加规则 - 启用 "Require status checks to pass before merging"
- 搜索并添加 "Security Gate"
- 可选:启用 "Require branches to be up to date before merging"
权限
工作流申请最小必要权限:
permissions:
contents: read # checkout code
security-events: write # upload SARIF to Security tab
actions: read # read workflow status for gate
不授予对仓库内容的写入权限。
触发配置
默认触发器覆盖最常见的工作流:
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
workflow_dispatch: # manual trigger from GitHub UI
仅在 Pull Request 时运行
为减少 Actions 用时,移除 push 触发器:
on:
pull_request:
branches: [main, master]
workflow_dispatch:
添加定时扫描
每日运行一次完整扫描(例如,用于捕获新披露的 CVE):
on:
schedule:
- cron: "0 6 * * *" # 06:00 UTC daily
push:
branches: [main, master]
pull_request:
branches: [main, master]
自定义指南
修改严重性阈值
在 Trivy 作业中修改 severity 输入:
severity: CRITICAL,HIGH,MEDIUM # report medium and above
在门禁失败时发送邮件通知
gate:
# ... existing config ...
steps:
- name: Evaluate results
# ... existing step ...
- name: Notify on failure
if: failure()
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.example.com
to: security-team@example.com
subject: "CAST Security Gate Failed — ${{ github.repository }}"
body: "Security gate failed on ${{ github.ref }}"
跳过特定路径的检查
on:
push:
branches: [main, master]
paths-ignore:
- "docs/**"
- "*.md"
故障排查
Gitleaks 对合法测试固件报错
添加 .gitleaks.toml 允许列表(参见 密钥检测 章节)。
Semgrep SARIF 上传失败
确保 permissions 中已设置 security-events: write。github/codeql-action/upload-sarif 操作需要此权限。
pip-audit 找不到 requirements 文件
若您仅使用 pyproject.toml,请修改 inputs 参数:
with:
inputs: pyproject.toml
或安装您的包并审计环境:
- run: pip install -e .
- uses: pypa/gh-action-pip-audit@v1
容器作业意外被跳过
若 Dockerfile 位于子目录中,hashFiles('Dockerfile') 条件将返回空字符串。请修改条件以匹配您的路径:
if: hashFiles('**/Dockerfile') != ''