GitCode 流水线安全能力指南
概述
GitCode 流水线(官方名称 AtomGit Action)以 Pipeline as Code 方式运行:工作流文件存放在仓库 .gitcode/workflows/ 目录下,与代码同仓管理,共享提交、评审与版本追溯流程。这一形态决定了流水线安全的两个基本面:流水线配置的变更天然受仓库写权限与保护分支规则约束;流水线运行时的凭据、权限与外部输入则由平台提供专门的安全机制。
本文档梳理 GitCode 流水线在各安全层面的工具能力,供搭建门禁、配置密钥、接入外部贡献时参考。GitCode 帮助文档由 AtomGit 文档体系承载,页面中 AtomGit 与 GitCode 品牌名混用,流水线系统变量前缀为 ATOMGIT_*,阅读官方文档时两者指同一平台。
| 安全能力域 | 核心机制 | 主要配置入口 |
|---|---|---|
| 门禁安全 | 保护分支、PR 合并门禁、仓库级辅助设置 | 项目设置 |
| 私密参数配置 | Secret 加密存储、日志遮掩、运行时主动脱敏 | 组织/项目设置 → 密钥与变量 |
| 流水线权限与防注入 | Token 最小权限、Fork PR 双事件模型、Webhook 凭据 | 工作流 YAML、仓库 Webhook 设置 |
| 敏感信息扫描 | CodeCheck 流水线、AI 代码审查 | 工作流 YAML、插件市场 |
官方文档:产品总览中对安全能力有整体说明,本文各章节给出对应的专项文档入口。
门禁安全
门禁安全解决"什么样的代码、什么人、以什么方式才能进入主干"的问题。GitCode 将门禁拆解为保护分支、PR 合并门禁与仓库级辅助设置三层,逐层收紧合并路径。
保护分支
保护分支限制对指定分支的访问和更改,官方文档明确四项措施:
| 措施 | 作用 |
|---|---|
| 强制代码评审 | 合并更改到受保护分支必须经过 Pull Request 评审并获得批准 |
| 限制合并权限 | 只有特定的人或团队成员才能合并更改 |
| 禁止直接推送 | 阻止直接向受保护分支提交更改,要求通过 Pull Request 提交 |
| 要求流水线检查通过 | 确保提交的更改通过 CI/CD 流程的检查 |
配置入口:项目设置 → 左侧导航「保护分支」→ 在「保护分支规则」中选择分支 → 启用允许推送、允许合并、是否允许强制推送等规则 → 确定。主分支建议同时开启禁止直接推送与流水线检查通过两项,使 CI 结果成为合并的硬性前提。
官方文档:保护分支
PR 合并门禁
PR 设置在评审维度上补充门禁条件,与保护分支配合形成完整的合并卡点:
| 功能 | 门禁效果 |
|---|---|
| 最低评审人数 | 设置合并 PR 所需的最低评审人数 |
| 评审问题全部解决才能合入 | 所有评审问题被标记为解决之前禁止合并 PR |
| 流水线运行通过 | 合并 PR 前需确保关联的流水线任务成功运行并通过检查 |
| 禁止合入自己创建的 Pull Request | 防止开发者合并自己创建的 PR,保持评审客观性 |
| 允许管理员强制合入 | 赋予管理员绕过限制强制合并 PR 的权限 |
「允许管理员强制合入」是门禁的旁路开关,仅在紧急修复等例外场景使用。开启后管理员的合并操作不受上述门禁约束,建议配套评审记录留痕。除门禁项外,PR 审查设置支持在创建 PR 时自动分配审查人员与测试人员,并分别设置通过审查、通过测试所需的最低人数。
官方文档:PR 设置
仓库级辅助设置
仓库设置中与流水线安全直接相关的选项:
| 功能 | 安全作用 |
|---|---|
| 启用 GPG 签名校验 | 验证提交的 GPG 签名,确保代码来源可信 |
| 禁止开发者角色创建分支 | 限制开发者角色的权限,避免未经授权的分支创建 |
| 禁止开发者角色创建 Tag | 限制开发者角色标记 Tag,防止无效或误导性标记 |
| 合并请求 PR 预合并 | 提供预合并检查,确保代码合并前经过严格校验 |
| 分支名规则 / Tag 名规则 | 统一分支与版本标记的命名,便于门禁规则匹配 |
工作流文件位于 .gitcode/workflows/ 目录,与代码同仓,因此修改流水线即修改仓库代码,受仓库写权限与保护分支规则约束。对流水线配置的敏感变更(如新增凭据引用、放宽权限声明)走与业务代码相同的 PR 评审流程。
官方文档:仓库设置
私密参数配置
流水线运行需要密码、API Key、访问凭证等敏感信息,私密参数配置的目标是让这些值不落入代码仓库、不出现在运行日志。
Secret 管理与引用
Secret 分为组织级与项目级两个作用域:组织级 Secret 在组织下所有项目生效,适合存放企业级共享凭据;项目级 Secret 仅在当前项目生效,适合项目独立凭据。
创建入口:
- 组织级:组织设置 → 密钥与变量 → 组织秘钥 → 新建组织密钥
- 项目级:项目设置 → 密钥与变量 → 仓库密钥 → 新建仓库密钥
在工作流中通过 ${{ secrets.SECRET_NAME }} 引用:
# .gitcode/workflows/deploy.yml
stages:
deploy:
name: 部署
jobs:
name: push-to-prod
runs-on: [ubuntu-latest, x64, medium]
steps:
- name: Run bash
run: |
ssh -i ${{ secrets.PROD_DEPLOY_KEY }} \
user@prod-server.example.com \
"deploy.sh ${{ secrets.PROD_API_TOKEN }}"
容器凭据同样支持 Secret 引用,私有镜像拉取场景将用户名密码注入 container.credentials:
jobs:
private-image-build:
name: private-image-build
runs-on: [ubuntu-latest, x64, medium]
container:
image: registry.example.com/myapp:latest
credentials:
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
Secret 命名规则:仅允许大写字母、数字和下划线;不得以 ATOMGIT_ 开头(与系统变量冲突);不得以数字开头。
官方文档:使用 Secrets
Secret 安全机制
| 安全措施 | 说明 |
|---|---|
| 日志遮掩 | Secret 值在日志中自动替换为 *** |
| 不可查看 | 创建后无法在界面查看原值,只能更新覆盖 |
| Fork 隔离 | pull_request 事件来自 fork 仓库的 workflow 不可访问项目级 Secret |
Fork 隔离是外部贡献场景的关键机制:来自 fork 仓库的 PR 触发的 workflow 无法读取项目 Secret,防止外部贡献者通过 PR 流水线窃取密钥。若确需在 PR 流水线中使用 Secret,须使用 pull_request_target 事件,其安全差异见下文 Fork PR 双事件模型。
官方文档:使用变量和密钥
变量类型与敏感数据边界
工作流提供四种变量类型,敏感数据只应进入 secrets,普通配置进入 vars,避免用明文变量承载凭据:
| 类型 | 适合存储 | 是否敏感 | 定义位置 | 引用方式 |
|---|---|---|---|---|
env |
workflow 内部临时环境变量 | 否 | YAML 文件 | $APP_NAME 或 ${{ env.APP_NAME }} |
vars |
仓库/组织级普通配置 | 否 | 平台界面 | ${{ vars.VAR_NAME }} |
secrets |
密码、token、私钥 | 是 | 平台界面 | ${{ secrets.NAME }} |
inputs |
workflow_dispatch / workflow_call 输入 | 否 | YAML 文件 | ${{ inputs.NAME }} |
变量优先级从高到低:Step 级 env > Job 级 env > Workflow 级 env > vars > 系统变量(ATOMGIT_*)。
官方安全提示中有三条实践约束:不要在日志中打印 secret(echo "$SECRET" 会脱敏,但 echo "${{ secrets.MY_SECRET }}" 的表达式内插可能绕过脱敏);不要把 secret 写入制品或缓存;外部贡献者的 PR/MR 默认不应暴露高权限 secret。
官方文档:使用变量和密钥
日志主动脱敏
日志遮掩默认只覆盖 Secret 渠道传入的值。运行时生成的临时凭据(如脚本中动态获取的临时 token)不会自动脱敏,需要在 step 中显式声明:
steps:
- name: Mask secret
run: |
echo "::add-mask::$MY_SECRET"
echo "The secret value is $MY_SECRET"
执行 add-mask 后,日志中该值显示为 ***。脚本中先获取临时凭据、再执行需要打印该凭据相关输出的命令时,应在获取后立即 add-mask。
官方文档:使用脚本命令
流水线权限与防注入
Token 权限控制
每次流水线运行自动生成 ATOMGIT_TOKEN,用于克隆代码仓库、推送构建产物、创建 PR 与 Issue 评论、操作项目资源。该 Token 的权限范围由 workflow 的 permissions 字段控制,共五个权限域:
| 权限域 | read | write | 说明 |
|---|---|---|---|
project |
读取项目信息 | 修改项目设置 | 项目元数据操作 |
pr |
读取 PR | 创建/评论/合并 PR | Pull Request 操作 |
issue |
读取 Issue | 创建/评论 Issue | Issue 操作 |
note |
读取评论 | 创建评论 | 通用评论操作 |
repository |
克隆/读取 | 推送/修改仓库 | 代码仓库操作 |
最小权限实践:每个 workflow 显式声明所需权限,用不到的域声明为 none。仅做代码检查的流水线无需任何写权限:
permissions:
repository: read # 仅需克隆代码
pr: none
issue: none
note: none
project: none
permissions: {}(空对象)时 Token 仅拥有最小默认权限(repository:read)。未声明 permissions 的 workflow 使用仓库设置中定义的权限。
官方文档:Token 权限
Fork PR 双事件模型
外部贡献(fork 仓库的 PR)是流水线注入攻击的主要入口:恶意 PR 可以篡改 workflow 文件注入执行逻辑。GitCode 用两种 PR 触发事件区分信任边界:
| 事件 | 执行上下文 | Token 权限 | Secret 访问 | 典型用途 |
|---|---|---|---|---|
pull_request |
PR 分支的 workflow 文件 | Fork PR 仅 read | 不可访问 | PR 代码检查、构建验证 |
pull_request_target |
目标分支的 workflow 文件 | 可声明写权限 | 可访问 | PR 评论、自动标签 |
pull_request 执行的是 PR 分支中的 workflow 文件,但权限与 Secret 双重收紧,即使文件被恶意修改也无法越权;pull_request_target 执行目标分支(受信任)的 workflow 文件,可访问 Secret 并拥有写权限,但需要显式 checkout PR 的 head SHA 才能操作 PR 代码:
# .gitcode/workflows/pr-build.yml
on:
pull_request_target:
branches: [main]
permissions:
repository: write
pr: write
stages:
build:
name: 构建
jobs:
Build:
name: build-and-report
runs-on: [ubuntu-latest, x64, medium]
steps:
- name: Checkout source code
uses: checkout
with:
ref: ${{ atomgit.event.pull_request.head.sha }} # checkout PR 代码
- name: build
run: make build
判断标准:流水线只需验证 PR 代码(lint、测试、构建)时用 pull_request;流水线需要访问 Secret 或对 PR 执行写操作(评论、打标签)时用 pull_request_target,并确保其中的脚本步骤不执行 PR 分支中的代码。
官方文档:PR/MR 流水线安全
并发控制
concurrency 字段限制同一 workflow 的并行运行数(取值范围 1-5),支持两种超限策略:IGNORE 忽略新触发请求,QUEUE 排队执行。对部署类流水线设置并发为 1 可避免多个部署任务交叉执行导致的资源竞争与状态错乱。
官方文档:工作流文件结构与位置
Webhook 凭据保护
仓库 Webhook 支持两类凭据保护参数:
| 参数 | 说明 |
|---|---|
password |
请求 URL 时带上该密码,防止 URL 被恶意请求 |
encryption_type |
加密类型:0 为密码,1 为签名密钥 |
回调方应对请求中的密码或签名做校验,丢弃校验失败的请求,防止伪造的 Webhook 事件触发流水线或外部系统状态变更。Webhook 可订阅的事件包括 push、tag push、issues、评论、合并请求。
官方文档:WebHooks API
敏感信息扫描
平台侧能力
CodeCheck 流水线
CodeCheck 通过 codecheck-action 插件在流水线中执行静态代码检查,支持 JAVA、C++、C、PYTHON、GO、RUST、KOTLIN、SHELL、SQL 等 18 种语言,按语言配置规则集:
name: codecheck-pipeline
jobs:
build:
runs-on: euleros-2.10.1
steps:
- name: codecheck-action-task
uses: codecheck-action@0.0.3
with:
repo_url: "https://gitcode.com/your-org/your-repo.git"
branch: "main"
rule_sets: '[{"language":"JAVA"},{"language":"SHELL"}]'
access_token: ${{ secrets.GITCODE_ACCESS_TOKEN }}
access_token 为个人账号设置的访问令牌,应配置为项目 Secret 后在工作流中引用,不要明文写入工作流文件或仓库。CodeCheck 面向代码质量检查,规则集按语言维度配置;GitCode 官方文档未将其描述为密钥泄露检测服务,密钥类扫描需求见下节的自建方案。
官方文档:创建 CodeCheck 流水线
AI 代码审查(AtomCode AI Review)
AI 代码审查插件在 PR 提交后 2-3 分钟内自动完成审查,五大审查维度中的安全维度覆盖 SQL 注入、XSS、凭证泄露、危险依赖、配置与容器风险。插件仅获取 Webhook、PR 读写、仓库文件读取权限,不修改代码文件。使用限制:内测期仅支持公开仓库,配额按用户类型每周刷新(普通用户 30 次、普通组织 200 次、企业 1000 次)。
官方文档:AI 代码审查
需自行集成的扫描能力
GitCode 官方文档未提供平台级的密钥泄露扫描(Secret Detection)服务。代码中的密钥泄露检测可通过流水线中运行开源扫描工具实现:
- Gitleaks:Git 仓库密钥泄露检测工具,支持扫描提交历史,适合在流水线中做全量与增量扫描
- detect-secrets:Yelp 开源的密钥检测工具,通过基线文件管理已确认的密钥,适合增量场景
openLiBing 已提供基于 GitCode 流水线的 CodeQL 安全扫描方案,其密钥配置与结果可视化流程见 CodeQL 代码检查指南,其中 Secrets 配置清单一节演示了组织级与项目级密钥在 GitCode 上的完整配置过程。
相关文档
- CodeQL 代码检查指南 — GitCode 流水线上的 CodeQL 安全扫描与秘钥配置实践
- pre-commit 落地指南 — 本地提交前检查与 PR 门禁的工程方案
- Gitleaks 工具详解 — 密钥泄露检测工具的安装、配置与集成
- detect-secrets 工具详解 — 基线化的密钥检测工具
- CodeArts Pipeline 安全能力指南 — 华为云 CodeArts Pipeline 的门禁、私密参数与审计能力