极狐 GitLab

CI/CD 作业令牌

Tier: 基础版,专业版,旗舰版

Offering: JihuLab.com,私有化部署

当 CI/CD 流水线作业即将运行时,极狐GitLab 会生成一个唯一令牌,并将其作为 CI_JOB_TOKEN 预定义变量提供给作业。 该令牌仅在作业运行期间有效。作业完成后,令牌访问权限将被撤销,您不能再使用该令牌。

使用 CI/CD 作业令牌可在作业运行期间对某些极狐GitLab 功能进行认证。 该令牌拥有与触发流水线的用户相同的访问级别, 但可访问的资源比个人访问令牌少。用户 可以通过推送提交、运行手动作业或拥有定时流水线来触发作业。 此用户必须具有具有所需权限的角色 才能访问资源。

您可以使用作业令牌向极狐GitLab 进行认证,以访问另一个群组或项目的资源(目标项目)。 默认情况下,作业令牌的群组或项目必须被添加到目标项目的允许列表中

如果项目是公开或内部的,您无需在允许列表中即可访问某些功能。 例如,您可以从项目的公开流水线中获取产物。 此访问权限也可以被限制

作业令牌访问权限#

版本历史
  • 获取单个标签的权限于极狐GitLab 18.8 引入

CI/CD 作业令牌可以访问以下资源:

资源备注
分支 API可以访问 GET /projects/:id/repository/branches 端点。
提交 API可以访问 GET /projects/:id/repository/commits/:shaGET /projects/:id/repository/commits/:sha/merge_requests 端点。
容器镜像仓库用作 $CI_REGISTRY_PASSWORD 预定义变量,用于向与作业项目关联的容器镜像仓库进行认证。
软件包仓库用于向仓库进行认证。
Terraform 模块仓库用于向仓库进行认证。
安全文件glab securefile 命令使用,以便在作业中使用安全文件。
容器镜像仓库 API只能向与作业项目关联的容器镜像仓库进行认证。
部署 API可以访问此 API 中的所有端点。
环境 API可以访问此 API 中的所有端点。
文件 API可以访问 GET /projects/:id/repository/files/:file_path/raw 端点。
作业 API只能访问 GET /job 端点。
作业产物 API只能访问下载端点。
合并请求 API可以访问 GET /projects/:id/merge_requestsGET /projects/:id/merge_requests/:merge_request_iid 端点。
评论 API可以访问 GET /projects/:id/merge_requests/:merge_request_iid/notesGET /projects/:id/merge_requests/:merge_request_iid/notes/:note_id 端点。
软件包 API可以访问此 API 中的所有端点。
流水线触发令牌 API只能访问 POST /projects/:id/trigger/pipeline 端点。
流水线 API只能访问 PUT /projects/:id/pipelines/:pipeline_id/metadata 端点。
发布链接 API可以访问此 API 中的所有端点。
发布 API可以访问此 API 中的所有端点。
仓库 API只能访问公共仓库的 GET /projects/:id/repository/changelog 端点。
标签 API可以访问 GET /projects/:id/repository/tagsGET /projects/:id/repository/tags/:tag_name 端点。

有一个公开的提案旨在使权限 更加细化。

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

如果作业令牌泄露,可能会被用于访问运行 CI/CD 作业的用户可访问的私人数据。为帮助防止此令牌泄露或被滥用, 极狐GitLab:

  • 在作业日志中屏蔽作业令牌。
  • 仅在作业运行时授予作业令牌权限。

您还应该将您的 Runner 配置为安全的:

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

不安全的极狐GitLab Runner 配置会增加有人从其他作业窃取令牌的风险。

控制对您项目的作业令牌访问权限#

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

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

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

私有化部署管理员可以覆盖并强制执行此设置。 当强制执行该设置时,CI/CD 作业令牌将始终限制为项目的允许列表。

将群组或项目添加到作业令牌允许列表#

版本历史

您可以将群组或项目添加到您的作业令牌允许列表,以允许使用作业令牌进行认证来访问您项目的资源。默认情况下,任何项目的允许列表仅包含其自身。仅在需要跨项目访问时,才将群组或项目添加到允许列表。

将项目添加到允许列表并不会授予允许列表中项目的成员额外的权限。他们必须已经拥有访问您项目中资源的权限,才能使用来自允许列表项目的作业令牌访问您的项目。

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

前提条件:

  • 您必须具有当前项目的维护者或所有者角色。如果被允许的项目是内部或私有的,您在目标项目中必须具有访客、计划者、报告者、开发者、维护者或所有者角色。
  • 添加到允许列表的群组和项目不得超过 200 个。

要将群组或项目添加到允许列表:

  1. 在顶部栏中,选择 搜索或跳转到 并找到您的项目。
  2. 在左侧边栏中,选择 设置 > CI/CD
  3. 展开 作业令牌权限
  4. CI/CD 作业令牌允许列表 右侧,选择 添加
  5. 选择 群组或项目
  6. 输入要添加到允许列表的群组或项目的路径,然后选择 添加

您也可以使用 API 将群组或项目添加到允许列表。

限制公共或内部项目的作业令牌范围#

版本历史
  • 于极狐GitLab 16.6 引入
  • 对仓库的访问于极狐GitLab 17.0 引入

不在允许列表中的项目可以使用作业令牌向公共或内部项目进行认证,以:

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

您可以通过将每个功能设置为仅对项目成员可见,来将这些操作的访问权限限制为仅限允许列表中的项目。

前提条件:

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

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

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

允许任何项目访问您的项目#

Offering: 私有化部署

版本历史

禁用令牌访问限制和允许列表存在安全风险。恶意用户可能试图破坏在未经授权的项目中创建的流水线。如果该流水线是由您的某个维护者创建的,那么作业令牌可能会被用于尝试访问您的项目。

如果您禁用了 CI/CD 作业令牌允许列表,来自任何项目的作业都可以使用作业令牌访问您的项目。触发该流水线的用户必须拥有访问您项目的权限。您应该仅在测试或类似原因下禁用此设置,并应尽快重新启用。

此选项仅在为所有项目启用并强制执行作业令牌允许列表 设置被禁用的私有化部署实例上可用。

前提条件:

  • 您必须具有项目的维护者或所有者角色。

要禁用作业令牌允许列表:

  1. 在顶部栏中,选择 搜索或跳转到 并找到您的项目。
  2. 在左侧边栏中,选择 设置 > CI/CD
  3. 展开 作业令牌权限
  4. 选择 所有群组和项目
  5. 建议。测试完成后,选择 此项目及允许列表中的任何群组和项目 以重新启用作业令牌允许列表。

您也可以使用 GraphQL (inboundJobTokenScopeEnabled) 或 REST API 修改此设置。

允许对您的项目仓库发起 Git 推送请求#

版本历史

您可以配置您的项目,以允许使用 CI/CD 作业令牌认证的 Git 推送请求。此设置默认关闭。

当您开启此设置时,只有在项目流水线中运行的 CI/CD 作业生成的作业令牌才能推送到该项目。来自其他 允许列表中的项目或群组的作业令牌不能推送到您的项目。

当您使用作业令牌推送到项目时,不会触发任何 CI/CD 流水线。 该作业令牌具有与启动作业的用户相同的访问权限。

如果您使用 semantic-release 工具,此设置可能会阻止创建流水线

不要对配置为拉取镜像的项目启用此设置, 尤其是当已为镜像更新配置了流水线运行时。 上游仓库所有者可能会尝试使用 CI_JOB_TOKEN 向镜像项目推送提交。

前提条件:

  • 您必须具有项目的维护者或所有者角色。

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

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

您也可以使用 项目 API 中的 ci_push_repository_for_job_token_allowed 参数来控制此设置。

作业令牌的细粒度权限#

您可以使用细粒度权限来显式地允许访问一组有限的 REST API 端点。

更多信息,请参看CI/CD 作业令牌的细粒度权限

Git 仓库克隆#

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

例如:

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

即使 HTTPS 协议被群组、项目或实例设置禁用,您也可以使用此作业令牌来克隆仓库。

REST API 认证#

您可以使用作业令牌通过以下方法对特定的 REST API 端点请求进行认证:

  • 请求头:--header "JOB-TOKEN: $CI_JOB_TOKEN" (推荐)
  • 表单:--form "token=$CI_JOB_TOKEN"
  • 数据:--data "job_token=$CI_JOB_TOKEN"
  • URL 中的查询字符串:?job_token=$CI_JOB_TOKEN (不推荐)

例如,使用推荐的请求头方法:

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

关于令牌安全指南,请参看安全注意事项

您不能使用作业令牌来认证 GraphQL 请求。

作业令牌认证日志#

版本历史
  • 于极狐GitLab 17.6 引入

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

  1. 在顶部栏中,选择 搜索或跳转到 并找到您的项目。
  2. 在左侧边栏中,选择 设置 > CI/CD
  3. 展开 作业令牌权限认证日志 部分将显示通过作业令牌认证访问了您项目的其他项目列表。
  4. 可选。选择 下载 CSV 以下载 CSV 格式的完整认证日志。

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

对项目的新认证最多可能需要 5 分钟才能在认证日志中显示。

为 CI/CD 令牌使用旧版格式#

版本历史
  • 于极狐GitLab 17.10 引入

从极狐GitLab 19.0 开始,CI/CD 作业令牌默认使用 JWT 标准。项目可以通过为其顶级群组进行配置来继续使用旧版格式。此设置仅在极狐GitLab 20.0 版本发布之前可用。

要为您的 CI/CD 令牌使用旧版格式:

  1. 在顶部栏中,选择 搜索或跳转到 并找到您的群组。
  2. 在左侧边栏中,选择 设置 > CI/CD
  3. 展开 通用流水线
  4. 关闭 为 CI/CD 作业令牌启用 JWT 格式

您的 CI/CD 令牌现在使用旧版格式。如果您想稍后再次使用 JWT 格式,可以重新启用此设置。

故障排除#

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

  • 未经授权的 Git 克隆:

    plaintext
    $ git clone https://gitlab-ci-token:$CI_JOB_TOKEN@gitlab.com/fabiopitino/test2.git 正在克隆到 'test2'... remote: 您要查找的项目可能未找到,或者您没有查看它的权限。 fatal: 未找到仓库 'https://gitlab-ci-token:[MASKED]@gitlab.com/<namespace>/<project>.git/'
  • 未经授权的软件包下载:

    plaintext
    1$ wget --header="JOB-TOKEN: $CI_JOB_TOKEN" ${CI_API_V4_URL}/projects/1234/packages/generic/my_package/0.0.1/file.txt 2 3--2021-09-23 11:00:13-- https://gitlab.com/api/v4/projects/1234/packages/generic/my_package/0.0.1/file.txt 4正在解析主机 gitlab.com (gitlab.com)... 172.65.251.78, 2606:4700:90:0:f22e:fbec:5bed:a9b9 5正在连接 gitlab.com (gitlab.com)|172.65.251.78|:443... 已连接。 6已发出 HTTP 请求,正在等待回应... 404 Not Found 72021-09-23 11:00:13 错误 404:未找到。
  • 未经授权的 API 请求:

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

在排查 CI/CD 作业令牌认证问题时,请注意:

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

semantic-release 工具和作业令牌#

如果您在启用 允许对仓库发起 Git 推送请求 设置的情况下使用 semantic-release 工具,则存在一个已知问题。 启用时:

  • 该工具会使用作业令牌进行认证,即使该工具被配置为使用个人访问令牌也是如此。
  • 作业令牌不会触发新的流水线,因此发布流水线可能无法运行。

更多信息,请参看 issue 891

JWT 格式作业令牌错误#

CI/CD 作业令牌的 JWT 格式存在一些已知问题。

使用 EC2 Fargate Runner 自定义执行器时出现 Error when persisting the task ARN. 错误#

EC2 Fargate 自定义执行器的 0.5.0 及更早版本中存在一个错误。此问题会导致以下错误:

  • Error when persisting the task ARN. Will stop the task for cleanup

要解决此问题,请升级到 Fargate 自定义执行器的 0.5.1 或更高版本。

使用 base64 编码时出现 invalid character '\n' in string literal 错误#

如果您使用 base64 对作业令牌进行编码,可能会收到 invalid character '\n' 错误。

base64 命令的默认行为会换行超过 79 个字符的字符串。 在作业执行期间对 JWT 格式的作业令牌进行 base64 编码时(例如使用 echo $CI_JOB_TOKEN | base64),令牌会变得无效。

要解决此问题,请使用 base64 -w0 来禁用自动换行。

长时间运行的作业中出现 403 Forbidden 错误#

在极狐GitLab 18.8 及更早版本中使用 JWT 格式的作业令牌时,作业可能会失败并出现 403 Forbidden 错误。这可能会发生在:

  • 使用了 needs 的作业中。
  • 子流水线 中的作业。
  • 运行时间超过约 6 分钟且未产生控制台输出的作业。

该错误通常出现在 Runner 日志中,如下所示:

plaintext
WARNING: Submitting job to coordinator... job failed code=403 job=<job_id> status=PUT https://gitlab.com/api/v4/jobs/<job_id>: 403 Forbidden

请更新至极狐GitLab 18.9 以避免此问题。