如何在.gitlab-ci.yml中使用用户无直接访问权限项目的include配置
问题场景
在project A的.gitlab-ci.yml配置中,通过includes语法引用专门存放通用CI配置的project B内的配置文件,基础配置写法如下:
include: - project: pathto/projectb file: - "/pathto/myfile.yml"
当触发流水线的用户同时持有两个项目的访问权限时,配置可正常运行;如果触发用户是仅持有project A有限访问权限的外部开发者,无project B直接访问权限,就会触发如下lint校验错误,导致流水线无法启动:
Found errors in your .gitlab-ci.yml: Project `pathto/projectb` not found or access denied! Make sure any includes in the pipeline configuration are correctly defined.
需要实现的目标是:无需给触发流水线的外部用户开放project B的直接访问权限,跨项目include引用可正常生效,流水线可成功运行。
可落地实现方案
- 方案1:配置CI作业令牌跨项目访问白名单
进入project B的项目设置-CI/CD-令牌访问配置页,将project A添加到允许通过CI作业令牌访问本项目的白名单即可。配置完成后,project A的流水线在拉取include配置时,会自动使用内置的CI作业令牌完成鉴权,完全不依赖触发用户的个人权限。
该方案适配GitLab 13.7及以上版本,不需要修改现有.gitlab-ci.yml的include写法,改造成本最低,且不会给外部开发者暴露project B的任何内容,权限边界最清晰,是优先推荐的方案。 - 方案2:使用项目访问令牌做拉取鉴权
首先在project B中生成具备Reporter及以上权限的项目访问令牌,将令牌以CI变量的形式存储在project A的项目或组级CI变量中,变量要同时开启受保护、掩码属性,避免令牌泄露。之后修改project A的include配置,通过remote方式携带令牌拉取配置,示例配置如下:
该方案不需要调整两个项目的关联权限配置,仅需做好令牌的权限管控和定期轮换,适合没有include: - remote: "https://<你的GitLab实例域名>/pathto/projectb/-/raw/main/pathto/myfile.yml?private-token=$PROJECT_B_CI_TOKEN"project B项目设置修改权限的场景。 - 方案3:将通用CI配置发布为内部可访问的静态资源
在project B的流水线中增加发布步骤,将通用CI配置文件作为流水线制品发布,或者同步到仅内部网络可访问的静态文件服务(比如开启内部访问限制的GitLab Pages、内部对象存储),之后在project A中通过remote方式引用静态地址的配置文件即可。
该方案需要额外维护配置文件的发布、同步流程,适合多项目大规模复用CI配置、需要做配置版本灰度发布的场景。 - 方案4:使用组级共享CI模板
如果project A和project B同属一个顶层组,可以将通用CI配置存放到组级CI模板目录,或者将project B设置为组内可见的模板项目,组内所有项目可以直接引用模板配置,不需要单独给触发用户分配project B的访问权限。
该方案适合同组下多项目统一CI管理的场景,如果project A属于独立的外部组则不适用。
内容的提问来源于stack exchange,提问作者Cord Kaldemeyer
相关产品推荐
相关产品推荐

