2、GitLab CI模板目录结构基础
目录结构是模板权限边界的第一道防线。在GitLab CI中,模板的存放位置决定了谁能读取、谁能引用、谁能覆盖。理解默认路径、自定义配置和层级规范,是后续进行权限评审的前提。
2.1 默认模板目录位置
GitLab官方将内置CI模板统一存放在安装目录下的固定路径:
/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/ci/templates/
该目录包含所有官方维护的模板文件(如 Auto-DevOps.gitlab-ci.yml、Security/SAST.gitlab-ci.yml 等),由GitLab版本发布时打包,普通用户无权修改。下表列出该目录的核心特征:
| 属性 | 说明 |
|---|---|
| 物理路径 | lib/gitlab/ci/templates/(相对于Rails应用根目录) |
| 访问方式 | 通过 include:template 关键字引用,如 template: Jobs/Test.gitlab-ci.yml |
| 权限模型 | 只读,仅GitLab系统管理员可通过升级包更新 |
| 可见范围 | 全局可见,所有项目均可引用 |
评审要点:默认目录中的模板是“可信基础镜像”。评审时需确认是否有非官方文件混入该目录,以及是否有用户通过
include:template意外引用了已被废弃或存在漏洞的旧版本模板。
2.2 自定义模板目录配置
企业通常需要维护私有模板库。GitLab支持通过项目级设置或实例级配置来定义自定义模板目录。常见方式有两种:
- 项目内模板目录:在项目仓库根目录下创建
.gitlab/ci/templates/文件夹,该目录下的.gitlab-ci.yml文件可通过相对路径include:local引用。 - 实例级自定义模板目录:通过
gitlab.rb配置文件中的gitlab_ci['custom_template_dirs']参数指定一个或多个额外目录。
# /etc/gitlab/gitlab.rb 配置示例
gitlab_ci['custom_template_dirs'] = [
"/var/opt/gitlab/custom-ci-templates",
"/data/shared/security-templates"
]
配置生效后,这些目录下的模板文件可通过 include:template 以 Custom/ 前缀引用。下表对比两种自定义方式的差异:
| 维度 | 项目内模板目录 | 实例级自定义模板目录 |
|---|---|---|
| 作用域 | 仅限单个项目 | 整个GitLab实例 |
| 管理方式 | 开发者通过Git提交管理 | 系统管理员通过文件系统管理 |
| 引用语法 | include:local |
include:template + Custom/ 前缀 |
| 权限风险 | 低(受项目权限控制) | 高(需确保目录权限最小化) |
边界风险:实例级自定义模板目录如果权限配置不当(如
777 或属主为非git用户),攻击者可能通过写入恶意模板实现横向移动。评审时必须检查 custom_template_dirs 中每个目录的POSIX权限和SELinux上下文。
2.3 目录层级规范
GitLab CI模板目录遵循一套清晰的层级约定,用于组织不同类别的模板。官方模板的层级结构如下:
templates/
├── Auto-DevOps.gitlab-ci.yml
├── Jobs/
│ ├── Build.gitlab-ci.yml
│ ├── Test.gitlab-ci.yml
│ └── Deploy.gitlab-ci.yml
├── Security/
│ ├── SAST.gitlab-ci.yml
│ ├── Secret-Detection.gitlab-ci.yml
│ └── DAST.gitlab-ci.yml
├── Verify/
│ ├── Browser-Performance.gitlab-ci.yml
│ └── Code-Quality.gitlab-ci.yml
└── Workflows/
├── Merge-Request.gitlab-ci.yml
└── Branch-Pipelines.gitlab-ci.yml
层级规范的核心原则包括:
- 一级目录:按功能领域命名(如
Security/、Jobs/),首字母大写,使用单数形式。 - 模板文件:使用帕斯卡命名法(PascalCase),以
.gitlab-ci.yml为后缀。 - 禁止嵌套过深:官方规范限制最多两级子目录,避免引用路径过长导致维护困难。
- 索引文件:每个目录下可包含
index.md描述该分类的模板清单和使用说明。
评审检查项:在自定义模板目录中,是否遵循了相同的层级规范?是否存在目录名与文件名冲突?是否有模板文件位于非标准位置导致
include:template 解析失败?层级混乱会直接导致权限覆盖逻辑不可预测。
2.4 目录结构与权限的关联
目录层级直接影响模板的引用路径和权限继承关系。在权限评审中,需要关注以下映射:
- 路径即身份:模板的引用路径(如
Security/SAST.gitlab-ci.yml)决定了它在权限模型中的“身份标识”。 - 目录权限继承:文件系统层面,子目录默认继承父目录的权限。如果自定义模板目录的父目录权限过宽,所有子模板都会暴露。
- 覆盖优先级:当默认目录和自定义目录中存在同名模板时,自定义目录中的版本会覆盖默认版本。评审时需确认是否存在非预期的覆盖。
最佳实践:建议为自定义模板目录单独创建系统用户(如
gitlab-ci-templates),并设置 750 权限(属主读写执行、属组读执行、其他无权限)。同时启用GitLab审计日志,记录所有模板文件的变更操作。