真正防止非特权分支读取敏感Token需联动保护分支、变量保护与作业策略:必须在项目设置中显式配置受保护分支(如main、release/*),变量须同时启用Protected(限受保护分支注入)和Masked(防日志泄露),并禁用手动流水线触发覆盖功能,关键作业还需添加分支守卫规则校验变量存在性。

要真正防止非特权分支读取敏感 Token,光靠勾选“Protected”远远不够。关键在于把“保护分支”、“变量保护”和“作业执行策略”三者联动起来,形成闭环控制。
明确受保护分支的范围
变量是否生效,取决于它所绑定的分支是否被 GitLab 认定为“受保护”。这不是手动标记,而是必须在项目设置中显式配置:
- 进入 Settings → Repository → Protected branches
- 为
main、stable、release/*等生产相关分支添加保护规则 - 确保 Allowed to merge 和 Allowed to push 仅限 Maintainer 或更高级别角色
- 特别注意:
dev、feature/*、hotfix/*这类开发分支默认不被保护,即使你给变量打了勾,它们也拿不到值
变量本身必须双重启用:Protected + Masked
仅启用 Protected 只是限制“在哪跑”,不防日志泄露;仅启用 Masked 只是遮掩输出,不防误用。两者缺一不可:
OpenClaw 技能 — 给定一个 GitHub 仓库 URL,自动解析出 owner/repo 名称,发现其中的 YAML/properties 配置文件及其配对的中文字段说明;在 `workspace/{repo}/` 目录下按同步日期(格式为 `YYYY-MM-DD`)创建时间戳子目录;写入 `.openclaw-config-state.json` 状态文件。每次用户提问前,先比对远程仓库当前 ref(如 `main` 或 `master`)的最新提交 SHA 与本地状态文件中记录的 SHA:
- 在 Settings → CI/CD → Variables → Add variable 中创建变量(如
PROD_API_TOKEN) - 务必勾选 Protect variable —— 这样该变量只会在上述受保护分支的流水线中注入
- 务必勾选 Mask variable —— 这样即使脚本里写了
echo $PROD_API_TOKEN,日志里也只会显示[MASKED] - 注意:Masked 无法对已出现在历史日志中的值生效。所以首次设置敏感变量前,务必确认此前从未在任何作业中打印过它的明文
禁用非保护分支的手动触发与覆盖能力
这是最容易被忽略的突破口:手动触发流水线时,GitLab 允许用户在 UI 中覆盖所有变量——包括已设为 Protected 的变量。这意味着,哪怕 feature/login 分支本身无权访问 PROD_API_TOKEN,只要有人手动触发并填入值,就能绕过保护。
- 进入 Settings → CI/CD → General pipelines → Pipeline triggers
- 关闭 Enable trigger tokens for manual pipelines(或严格管控 trigger token 权限)
- 在 .gitlab-ci.yml 中为关键作业增加分支守卫逻辑:
stage: deploy
rules:
- if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'
- if: '$CI_COMMIT_REF_NAME == "main"'
- if: '$CI_COMMIT_REF_NAME =~ /^release\/.*$/'
script:
- '[ -n "$PROD_API_TOKEN" ] || { echo "ERROR: PROD_API_TOKEN missing or inaccessible"; exit 1; }'
- ./deploy-to-prod.sh
进阶加固:用组级变量 + 作用域继承强化一致性
如果多个项目共用同一套生产凭证,建议将 PROD_API_TOKEN 提升到组级变量,并同样启用 Protected 和 Masked:
- 在群组设置中定义变量,避免每个项目重复配置、漏设保护
- 组级变量自动继承给所有子项目,且保护策略统一生效
- 配合 group-level protected branches(GitLab 16.0+ 支持),可实现跨项目分支策略同步
- 这样即使某个项目管理员疏忽未保护本项目分支,只要群组级分支保护开启,变量依然不会泄漏

















