4. CI/CD 模板访问控制机制
CI/CD 模板的访问控制是权限边界评审的核心环节。GitLab 通过模板可见性规则、模板引用权限以及跨项目/跨组调用限制三层机制,共同构建模板的访问边界。任何一层的配置疏漏都可能导致模板被未授权访问或滥用。
4.1 模板可见性规则
模板的可见性由其所在项目的可见性决定,并遵循“向上继承、向下隔离”的原则。下表总结了不同项目可见性下模板的默认可见范围:
| 项目可见性 | 模板可见范围 | 典型风险场景 |
|---|---|---|
| Public | 所有已登录用户及未登录用户(若实例允许) | 敏感变量、硬编码密钥通过模板泄露 |
| Internal | 所有已登录的 GitLab 实例用户 | 内部非授权团队引用包含安全漏洞的模板 |
| Private | 仅项目成员(Guest 及以上角色) | Guest 角色可查看模板内容,间接获取敏感逻辑 |
⚠️ 评审要点: 即使项目为 Private,拥有 Guest 角色的成员仍可浏览项目代码(包括
.gitlab-ci.yml 及模板文件)。若模板中包含数据库连接串、API 等敏感信息,Guest 用户即可获取。建议将敏感模板移至独立的 Private 项目,并严格控制成员角色。
4.2 模板引用权限
模板引用权限决定了“谁”可以“引用”哪些模板。GitLab 支持两种引用方式,其权限模型存在显著差异:
- 本地引用(
include: local):仅限同一项目内的.gitlab-ci.yml引用本仓库中的模板文件。权限等同于项目代码访问权限。 - 跨项目引用(
include: project):允许引用其他项目中的模板文件。引用方需要具备被引用项目的 Reporter 及以上角色权限。 - 跨组引用(
include: remote+ URL):通过完整 URL 引用模板。权限由 URL 指向的仓库访问控制决定,通常需要 或公开访问。
📌 权限模型对比:
# 本地引用 —— 仅限本仓库
include:
- local: '/templates/security-scan.yml'
# 跨项目引用 —— 需要目标项目 Reporter 权限
include:
- project: 'security/templates'
file: '/compliance/audit.yml'
# 跨组远程引用 —— 依赖 URL 可访问性
include:
- remote: 'https://gitlab.example.com/security/templates/-/raw/main/scan.yml'
4.3 跨项目/跨组模板调用限制
跨边界调用是权限泄露的高发区。GitLab 提供了以下限制机制,评审时应逐一验证:
- 项目设置限制:在项目设置 > CI/CD > Access 中,可限制仅允许特定项目/组引用本项目的模板。
- 组级别限制:在组设置中可禁用“允许其他组引用本组项目模板”的开关,从组层面阻断跨组调用。
- 实例级别限制:管理员可在 Admin Area 中设置“允许的 CI/CD 模板来源”,仅允许白名单内的项目/组提供模板。
下图展示了跨项目/跨组模板调用的权限边界与阻断点:
4.4 边界评审检查清单
在实际评审中,建议按照以下清单逐项核查:
| 检查项 | 检查方法 | 通过标准 |
|---|---|---|
| 模板项目可见性 | 查看项目 Settings > General > Visibility | 敏感模板必须为 Private |
| 跨项目引用权限 | 验证引用方角色是否 ≥ Reporter | 最小权限原则,仅授权必要项目 |
| 组级别引用白名单 | 检查组 Settings > CI/CD > Template access | 未授权的组应被拒绝 |
| 实例级别来源限制 | Admin Area > CI/CD > Allowed template sources | 仅允许受信项目/组 |
| 模板内容敏感信息 | 扫描模板文件中是否包含变量、、密钥 | 敏感信息应通过 CI/CD Variables 注入 |
💡 最佳实践: 建立“模板专用组”,将所有可复用模板集中存放在该组下的 Private 项目中。在组级别开启“禁止其他组引用”开关,仅通过项目级别的 Access 白名单向特定业务组开放引用权限。这样可将模板的暴露面控制在最小范围。