极狐GitLab CI/CD 作业令牌

当 CI/CD 流水线作业运行时,极狐GitLab 会生成一个唯一的令牌,并以 CI_JOB_TOKEN 预定义变量的形式为作业所用。仅当作业正在运行时,此令牌才有效。作业完成后,令牌访问被撤销,您将无法使用此令牌。

使用 CI/CD 作业令牌来认证运行作业中的极狐GitLab 功能。令牌会收到和触发流水线用户线通的访问级别,但是和个人访问令牌相比,访问的资源更少。用户可以通过代码推送、触发手动作业或成为定时流水线的拥有者来运行作业。此用户必需具有所需权限的角色才能访问资源。

您可以使用作业令牌来认证极狐GitLab 以访问其他群组或项目的资源(目标项目)。默认情况下,作业令牌的群组或项目必需被添加到目标项目的等候列表中

如果项目是公开的或内部的,您可以无需在等候列表中就能访问有些功能。比如,您可以从项目的公开流水线中拉取产物。此访问还可以被限制

作业令牌功能访问

CI/CD 作业令牌仅能够访问如下功能和 API 端点:

功能 额外详情
容器镜像仓库 API 令牌仅被限制为作业项目的容器镜像仓库。
容器镜像仓库 $CI_REGISTRY_PASSWORD 预定义变量是 CI/CD 作业令牌。都被仅限制为项目的容器镜像仓库。
部署 API 默认情况下,GET 请求是公开的。
环境 API 默认情况下, GET 请求是公开的。
作业产物 API 默认情况下, GET 请求是公开的。
获取作业的作业令牌的 API 端点 获取作业令牌的作业。
软件包仓库  
软件包 API 默认情况下, GET 请求是公开的。
流水线触发器 U使用 token= 参数来触发一个多项目流水线
更新流水线元数据 API 端点 更新流水线元数据。
发布链接 API  
发布 API 默认情况下, GET 请求是公开的。
仓库 API 基于仓库的提交来生成变更日志数据。
安全文件 默认情况下,download-secure-files 工具使用 CI/CD 作业令牌进行认证。
Terraform plan  

使用作业令牌无法访问其他 API 端点。

极狐GitLab CI/CD 作业令牌安全

为确保此令牌不会泄漏:

  • 隐藏作业日志中的作业令牌。
  • 仅在作业运行时授予作业令牌权限。

为确保此令牌不会泄漏,您还应该将 runners 配置安全。避免:

  • 如果机器被重复使用,则使用 Docker 的 privileged 模式。
  • 当作业在同一台机器上运行时使用 shell executor

如果您的极狐GitLab Runner 配置不安全,则会增加有人试图从其他作业窃取令牌的风险。

控制作业令牌来访问您的项目

您可以控制哪些群组或项目可以使用作业令牌来认证并访问您项目的某些资源。

默认情况下,作业令牌访问仅限于在您项目的流水线中运行的 CI/CD 作业。要允许其他群组或项目使用其他项目的流水线中的作业令牌进行认证:

如果项目是公开或内部的,某些公开资源可以通过作业令牌从任何项目访问。这些资源也可以仅限于允许列表中的项目

私有化部署实例的管理员可以覆盖和强制执行此设置。当强制执行此设置时,CI/CD 作业令牌始终受项目的许可名单限制。

将群组或项目添加到作业令牌等候列表

你可以添加群组或项目到作业令牌等候列表中以允许使用作业令牌来访问您项目的资源。默认情况下,任何项目的等候列表仅包括自身。仅当需要跨项目访问时才添加群组或项目到等候列表中。

添加项目到等候列表不能够为等候列表中的项目成员提供额外的权限。他们必须已经拥有权限来访问您项目中的资源才能使用等候列表中的项目中的作业令牌来访问您的项目。

比如,项目 A 可以添加项目 B 到项目 A 的等候列表中。项目 B(允许的项目)中的 CI/CD 作业现在可以使用 CI/CD 作业令牌来认证 API 调用来访问项目 A。

先决条件

  • 您必须至少具有当前项目的维护者角色。如果允许的项目是内部的或私有的,则您必须至少具有项目的访客角色。
  • 您不能添加超过 200 个群组或项目到等候列表中。

要将群组或项目添加到等候列表:

  1. 在左侧导航栏,选择 搜索或前往 并找到您的项目。
  2. 选择 设置 > CI/CD
  3. 展开 作业令牌权限
  4. 确保 认证的群组和项目 开关已启用。默认情况下,新项目启用此功能。禁用此功能有安全风险,所以项目维护者或所有者应始终启用此设置。
  5. 选择 添加群组或项目
  6. 输入要添加到等候列表的组或项目的路径,然后选择 添加

我们还可以使用 API来添加群组或项目到等候列表。

为公开或内部项目限制作业令牌范围

  • 引入于GitLab 16.6。

不在等候列表中的项目可以使用作业令牌来认证公开或内部项目以:

  • 获取产物。
  • 访问容器镜像仓库。
  • 访问软件包仓库。
  • 访问发布、部署和环境。

您可以将这些操作的访问权限限制为仅等候列表中的项目,方法是将每个功能设置为仅对项目成员可见。

先决条件:

  • 您必须至少是项目的维护者角色。

要想设置功能仅对项目成员可见:

  1. 在左侧导航栏,选择 搜索或前往 并找到您的项目。
  2. 选择 设置 > 通用
  3. 展开 可见性、项目功能、权限
  4. 将您要限制访问权限的特性设置为 仅项目成员
    • 获取产物的能力由 CI/CD 可见性设置控制。
  5. 选择 保存更改

允许任何项目来访问你的项目

  • 在极狐GitLab 16.3 中,允许使用 CI_JOB_TOKEN 访问此项目 设置被重命名为 限制访问此项目
  • 在极狐GitLab 17.2 中,令牌访问 部分被重命名为 作业令牌权限,并且 限制访问此项目 设置被重命名为 认证的群组和项目
caution 禁用令牌访问限制和等候列表有安全风险。恶意用户可能会试图破坏在未经授权的项目中创建的流水线。如果流水线是由项目维护者创建的,那么作业令牌可能会被用来尝试访问您的项目。

如果您禁用了 限制访问此项目 设置,则等候列表会被忽略。如果触发流水线有访问你项目的权限,则项目的任何作业都可以使用作业令牌来访问您的项目。

您应该仅在测试或类似原因禁用此设置,并且您应该尽快重新启用它。

先决条件:

  • 您必须至少具有项目的维护者角色。
  1. 要禁用作业令牌范围等候列表:

  2. 在左侧导航栏,选择 搜索或前往 并找到您的项目。
  3. 选择 设置 > CI/CD
  4. 展开 作业令牌权限
  5. 切换 认证的群组和项目 开关到禁用。在新项目中默认启用。

您还可以使用 GraphQL(inboundJobTokenScopeEnabled) 和 REST API 来启用或禁用此设置。

允许 Git 推送请求到您的项目仓库

  • 引入于极狐GitLab 17.2。使用名为 allow_push_repository_for_job_token 的功能标志。默认禁用。
  • 在极狐GitLab 17.2 中,令牌访问 部分被重命名为 作业令牌权限,且 限制访问此项目 设置被重命名为 认证的群组和项目
此功能的可用性受控于功能标志。更多详情,可以查看历史。此功能仅供测试使用,还未生产就绪。
caution 通过 CI/CD 作业令牌进行认证,进而推送到代码仓库的功能还在开发者,而且性能也还未优化。如果您想测试此功能,您必须彻底测试并实施验证措施,以防止无限循环的“推送”流水线触发更多的流水线。

您可以允许经过 CI/CD 作业令牌认证的 Git 推送请求到您的项目仓库。启用后,仅允许来自在您项目中运行的流水线中生成的令牌的访问权限。默认情况下,此权限被禁用。

先决条件:

  • 您必须至少具有项目的维护者角色。

要给项目中生成的作业令牌赋予推送到项目仓库的权限:

  1. 在左侧导航栏,选择 搜索或前往 并找到您的项目。
  2. 选择 设置 > CI/CD
  3. 展开 作业令牌权限
  4. 权限 部分,选择 允许 Git 推送请求到仓库

作业令牌具有与启动作业的用户同等的权限。其他来自等候列表中项目或群组的作业令牌无法推送到仓库。

您还可以在 projects REST API 端点中通过 ci_push_repository_for_job_token_allowed 参数来控制此设置。

使用作业令牌

git clone 一个私有仓库

您可以使用作业令牌来在 CI/CD 作业中认证并从私有项目克隆仓库。使用 gitlab-ci-token 作为用户,作业令牌的值作为密码。例如:

git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.example.com/<namespace>/<project>

即使 HTTPS 协议在群组、项目或实例设置中被禁用,您也可以使用作业令牌来认证并从私有项目克隆仓库。

认证 REST API 请求

您可以使用作业令牌来认证请求以允许 REST API 端点。比如:

curl --verbose --request POST --form "token=$CI_JOB_TOKEN" --form ref=master "https://gitlab.com/api/v4/projects/1234/trigger/pipeline"

此外,在请求中有多种有效方法来传递作业令牌:

  • --form "token=$CI_JOB_TOKEN"
  • --header "JOB-TOKEN: $CI_JOB_TOKEN"
  • --data "job_token=$CI_JOB_TOKEN"

作业令牌认证日志

  • 引入于极狐GitLab 17.6。

在认证日志中,您可以追踪哪些其他项目使用 CI/CD 作业令牌来认证您的项目。要检查日志:

  1. 在左侧导航栏,选择 搜索或前往 并找到您的项目。
  2. 选择 设置 > CI/CD
  3. 展开 作业令牌权限认证日志 部分显示了其他项目使用作业令牌来认证您的项目的列表。
  4. 可选。选择 下载 CSV 以下载完整的认证日志,格式为 CSV。

认证日志会显示最大 100 个认证事件。如果事件数量超过 100,则下载 CSV 文件以查看日志。

认证日志中显示的认证事件可能需要 5 分钟才能显示在认证日志中。

故障排查

CI 作业令牌失败通常显示为 404 Not Found 或类似的响应:

  • 未授权的 Git clone:

    $ git clone https://gitlab-ci-token:$CI_JOB_TOKEN@gitlab.com/fabiopitino/test2.git
    
    Cloning into 'test2'...
    remote: The project you were looking for could not be found or you don't have permission to view it.
    fatal: repository 'https://gitlab-ci-token:[MASKED]@gitlab.com/<namespace>/<project>.git/' not found
    
  • 未授权的软件包下载:

    $ wget --header="JOB-TOKEN: $CI_JOB_TOKEN" ${CI_API_V4_URL}/projects/1234/packages/generic/my_package/0.0.1/file.txt
    
    --2021-09-23 11:00:13--  https://gitlab.com/api/v4/projects/1234/packages/generic/my_package/0.0.1/file.txt
    Resolving gitlab.com (gitlab.com)... 172.65.251.78, 2606:4700:90:0:f22e:fbec:5bed:a9b9
    Connecting to gitlab.com (gitlab.com)|172.65.251.78|:443... connected.
    HTTP request sent, awaiting response... 404 Not Found
    2021-09-23 11:00:13 ERROR 404: Not Found.
    
  • 未授权的 API 请求:

    $ curl --verbose --request POST --form "token=$CI_JOB_TOKEN" --form ref=master "https://gitlab.com/api/v4/projects/1234/trigger/pipeline"
    
    < HTTP/2 404
    < date: Thu, 23 Sep 2021 11:00:12 GMT
    {"message":"404 Not Found"}
    < content-type: application/json
    

当对 CI/CD 作业令牌认证问题进行故障排查时,请记住:

  • GraphQL 示例变更可用于切换每个项目的范围设置。
  • 此评论厌食了如何使用 GraphQL 和 Bash 和 cURL 来:
    • 启用入站令牌访问范围。
    • 从项目 A 给项目 B 访问权限,或添加 B 到 A 的允许列表中。
    • 删除项目访问。
  • 如果作业不再运行、已经被清除或项目正在被删除,CI 作业令牌将变得无效。