1. 威胁模型:CI 是“高权限机器人”
Runner 执行你的脚本时,往往持有部署凭证、云 API、数据库连接串。攻击路径包括:恶意 MR 窃取变量、误配的缓存与制品、 被攻破的分支直接推生产脚本、以及内部人员越权操作。治理抓手要同时覆盖身份(谁)、引用(哪条分支/tag)、 执行语境(MR 还是主干)与事后证据(审计日志)。
2. CI/CD 变量:masked、protected 与作用域
变量可在实例 / 组 / 项目等层级定义,并支持 environment scope(限定到某环境名,如 production)。 Masked:在日志与 UI 中隐藏值(仍要满足格式要求,且不是加密万能药)。 Protected:仅在受保护分支/tag触发的 pipeline 中注入,避免特性分支流水线拿到生产密钥。
# Reference in job (value comes from GitLab UI / API settings)
deploy_stage:
stage: deploy
script:
- deploy --token "$DEPLOY_TOKEN"
environment:
name: staging
| 标志 | 意图 | 典型误用 |
|---|---|---|
| Masked | 减少日志泄露面 | 以为“已加密”;短字符串无法 mask |
| Protected | 绑定受保护 ref | 全设为 unprotected 以“省事” |
| Environment scope | 同名变量在不同环境取值 | scope 过宽导致 prod 密钥进错 job |
文件型变量与短时凭证
平台支持将文件内容作为变量注入(适用于 kubeconfig、客户端证书等场景),减少把多行 PEM 硬编码进脚本。 中长期仍建议把“长期有效的高权限凭证”迁出 GitLab:OIDC / JWT 对接云厂商 IAM、或 Vault / 云 Secret Manager 在 job 内动态拉取短时 token,缩小泄露窗口。
3. Protected branches & tags:改代码与打标签的阀门
受保护分支定义谁能 push、谁能 merge,常与 Code Owners、required approvals、CI 成功检查一起构成合并门禁。 受保护标签则保护发布标签不被随意挪动——对语义化版本与制品追溯至关重要。 把“能合进 main”与“能在 main 上跑带 protected 变量的流水线”对齐,是变量策略生效的前提。
4. Fork、外部贡献与流水线信任
公开项目常遇到 fork MR:默认若允许在 upstream 跑流水线,恶意改动可能试图打印变量、发外联请求、挖矿。 GitLab 提供多种项目设置(例如由维护者批准后才运行流水线、限制 fork pipeline 的权限)。平台工程团队应把这项写进贡献指南 + 组织基线。
5. 审计、审批与留存
Audit events(具体可用性与许可依 GitLab 版本与 tier 而定)记录关键操作:受保护分支变更、变量增删、成员角色变化等。 运维与合规团队通常把这些事件流导入 SIEM,并设定留存周期满足审计要求。 与 CI 搭配时,还要关注 job 日志、部署记录、制品下载 的访问控制与脱敏。
6. 基线清单(可直接当团队规范草案)
- 区分 build-time 与 deploy-time 机密;生产机密默认 protected + scoped。
- 梳理 Maintainer/Owner 人数;变量与受保护分支变更走双人复核。
- 为 fork / 外部贡献启用维护者批准流水线或等价控制。
- 开启并导出审计事件;与 IAM 变更告警联动。
- 每季度做秘密轮转与“是否还能缩小变量面”的复盘。
7. 与下一章的衔接
受保护环境与 environment 级审批、Review App 的生命周期,将在下一章与 CD 场景结合展开;本章打牢的是谁有权动配置、谁有权触达机密、如何留痕。