Help us learn about your current experience with the documentation. Take the survey.

GitLab CI/CD 作业令牌

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

当 CI/CD 管道作业即将运行时,GitLab 会生成一个唯一令牌,并通过 CI_JOB_TOKEN 预定义变量 将其提供给作业。该令牌仅在作业运行期间有效。作业结束后,令牌访问权限将被撤销,您无法再使用该令牌。

使用 CI/CD 作业令牌从运行中的作业向某些 GitLab 功能进行身份验证。该令牌拥有与触发管道的用户相同的访问级别,但比个人访问令牌的 可访问资源更少。用户可通过提交代码推送、触发手动作业或作为计划管道所有者等方式使作业运行。该用户必须拥有 具有所需权限的角色 才能访问资源。

您可以使用作业令牌向 GitLab 身份验证以访问其他组或项目的资源(目标项目)。默认情况下,作业令牌的组或项目必须 添加到目标项目的允许列表

如果项目是公开或内部的,即使不在允许列表中,您也可以访问某些功能。例如,您可以从项目的公开管道中获取制品。此访问也可以 受到限制

作业令牌访问权限

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

资源 说明
容器注册表 用作 $CI_REGISTRY_PASSWORD 预定义变量 向与作业项目关联的容器注册表进行身份验证。
包注册表 用于向注册表进行身份验证。
Terraform 模块注册表 用于向注册表进行身份验证。
安全文件 download-secure-files 工具用于在作业中使用安全文件。
容器注册表 API 仅能向与作业项目关联的容器注册表进行身份验证。
部署 API 可访问此 API 中的所有端点。
环境 API 可访问此 API 中的所有端点。
作业 API 仅能访问 GET /job 端点。
作业制品 API 可访问此 API 中的所有端点。
包 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 端点。

目前存在一个开放的 提案 以实现更细粒度的权限控制。

GitLab CI/CD 作业令牌安全性

如果作业令牌泄露,可能被用于访问触发 CI/CD 作业的用户可访问的私有数据。为帮助防止令牌泄露或滥用,GitLab:

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

您还应配置 运行器 以确保安全:

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

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

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

您可以控制哪些组或项目可以使用作业令牌进行身份验证并访问您项目的部分资源。

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

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

GitLab Self-Managed 管理员可以 覆盖并强制执行此设置。当设置被强制执行时,CI/CD 作业令牌始终限制在项目的允许列表中。

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

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

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

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

先决条件:

  • 您必须拥有当前项目的 Maintainer(维护者)角色。如果允许的项目是内部或私有的,您必须在该项目中拥有至少 Guest(访客)角色。
  • 您不能向允许列表添加超过 200 个组和项目。

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

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

您还可以 通过 API 将组或项目添加到允许列表。

自动填充项目的允许列表

您可以使用 作业令牌身份验证日志 中的数据,通过 UI 或 Rake 任务自动填充项目的允许列表。

无论哪种方式,GitLab 都会使用身份验证日志来确定要添加到允许列表的组或项目,并为您添加这些条目。

此过程最多在项目的允许列表中创建 200 个条目。如果身份验证日志中存在超过 200 个条目,它会 压缩允许列表 以保持在 200 个条目的限制内。

通过 UI 自动填充

通过 UI 自动填充允许列表:

  1. 在左侧边栏,选择 搜索或跳转至 并找到您的项目。
  2. 选择 设置 > CI/CD
  3. 展开 作业令牌权限
  4. 选择 添加 并从下拉列表中选择 身份验证日志中的所有项目
  5. 系统会弹出对话框要求您确认操作,选择 添加条目

操作完成后,允许列表将包含来自身份验证日志的条目。如果尚未设置,授权的组和项目 将设置为 仅此项目以及允许列表中的任何组和项目

通过 Rake 任务

拥有 rails console 访问权限 的 GitLab 管理员可以运行 Rake 任务,为实例上的全部或部分项目自动填充允许列表。此任务还会将 授权的组和项目 设置设置为 仅此项目以及允许列表中的任何组和项目

ci:job_tokens:allowlist:autopopulate_and_enforce Rake 任务具有以下配置选项:

  • PREVIEW:执行试运行并输出将要执行的步骤,但不更改任何数据。
  • ONLY_PROJECT_IDS:仅为提供的项目 ID 执行迁移(最多 1000 个 ID)。
  • EXCLUDE_PROJECT_IDS:为实例上的所有项目执行迁移,但排除提供的项目 ID(最多 1000 个 ID)。

ONLY_PROJECT_IDSEXCLUDE_PROJECT_IDS 不能同时使用。

例如:

  • ci:job_tokens:allowlist:autopopulate_and_enforce PREVIEW=true
  • ci:job_tokens:allowlist:autopopulate_and_enforce PREVIEW=true ONLY_PROJECT_IDS=2,3
  • ci:job_tokens:allowlist:autopopulate_and_enforce PREVIEW=true EXCLUDE_PROJECT_IDS=2,3
  • ci:job_tokens:allowlist:autopopulate_and_enforce
  • ci:job_tokens:allowlist:autopopulate_and_enforce ONLY_PROJECT_IDS=2,3
  • ci:job_tokens:allowlist:autopopulate_and_enforce EXCLUDE_PROJECT_IDS=2,3

为以下环境运行 Rake 任务:

sudo gitlab-rake ci:job_tokens:allowlist:autopopulate_and_enforce
sudo -u git -H bundle exec rake ci:job_tokens:allowlist:autopopulate_and_enforce

允许列表压缩

允许列表压缩算法:

  1. 扫描授权日志以识别项目的最近公共组。
  2. 将多个项目级条目合并为单个组级条目。
  3. 使用这些合并的条目更新允许列表。

例如,具有类似以下内容的允许列表:

group1/group2/group3/project1
group1/group2/group3/project2
group1/group2/group4/project3
group1/group2/group4/project4
group1/group5/group6/project5

压缩算法:

  1. 将列表压缩为:

    group1/group2/group3
    group1/group2/group4
    group1/group5/group6
  2. 如果允许列表超过 200 个条目的限制,算法会再次压缩:

    group1/group2
    group1/group5
  3. 如果允许列表仍然超过 200 个条目的限制,算法会继续:

    group1

此过程会持续执行,直到允许列表中的条目数量为 200 或更少。

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

不在允许列表中的项目可以使用作业令牌向公开或内部项目进行身份验证以:

  • 获取制品。
  • 访问容器注册表。
  • 访问包注册表。
  • 访问发布、部署和环境。

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

先决条件:

  • 您必须拥有项目的 Maintainer(维护者)角色。

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

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

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

  • Offering: GitLab Self-Managed, GitLab Dedicated

禁用令牌访问限制和允许列表存在安全风险。恶意用户可能尝试破坏在未授权项目中创建的管道。如果管道由您的维护者之一创建,作业令牌可能被用于尝试访问您的项目。

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

此选项仅在 GitLab Self-Managed 或 GitLab Dedicated 实例上可用,且 为所有项目启用并强制执行作业令牌允许列表 设置 已禁用时。

先决条件:

  • 您必须拥有项目的 Maintainer(维护者)角色。

禁用作业令牌允许列表:

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

您还可以通过 GraphQL (inboundJobTokenScopeEnabled) 或 REST API 修改此设置。

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

此功能的可用性由功能标志控制。有关详细信息,请参阅历史记录。 此功能可用于测试,但尚未准备好用于生产环境。

通过 CI/CD 作业令牌身份验证推送项目仓库仍在开发中,尚未针对性能进行优化。如果您为测试启用此功能,必须彻底测试并实施验证措施,以防止“推送”管道触发更多管道的无限循环。

您可以允许使用 CI/CD 作业令牌进行身份验证的 Git 推送请求访问您的项目仓库。启用后,仅允许在您项目管道中运行的 CI/CD 作业生成的令牌进行访问。此权限默认禁用。

先决条件:

  • 您必须拥有项目的 Maintainer(维护者)角色。

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

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

作业令牌拥有与启动作业的用户相同的访问权限。来自其他 允许列表中的项目或组 的作业令牌无法推送到您项目中的仓库。

您还可以使用 projects REST API 端点中的 ci_push_repository_for_job_token_allowed 参数控制此设置。

作业令牌的细粒度权限

作业令牌的细粒度权限是一项 实验性功能。有关此功能和可用资源的信息,请参阅 CI/CD 作业令牌的细粒度权限。欢迎在 此问题 上提供反馈。

使用作业令牌

克隆私有项目仓库

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

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

即使 HTTPS 协议被 通过组、项目或实例设置禁用,您也可以使用此作业令牌克隆仓库。您不能使用作业令牌推送仓库,但 问题 389060 提议更改此行为。

身份验证 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"
  • URL 中的查询字符串:?job_token=$CI_JOB_TOKEN

限制您项目的作业令牌访问(已移除)

限制从此项目访问 设置默认对所有新项目禁用,并在 GitLab 18.0 中被移除。项目维护者或所有者可以配置 限制对此项目的访问 设置。

通过创建可被您项目作业令牌访问的项目允许列表来控制您项目的作业令牌范围。

默认情况下,允许列表包含您当前项目。其他项目可由拥有两个项目访问权限的维护者添加和移除。

当设置禁用时,所有项目都被视为在允许列表中,作业令牌仅受用户访问权限的限制。

例如,当设置启用时,项目 A 中管道的作业具有限制在项目 A 范围内的 CI_JOB_TOKEN。如果作业需要使用令牌向项目 B 发出 API 请求,则必须将 B 添加到 A 的允许列表中。

配置作业令牌范围(已移除)

先决条件:

  • 您不能向令牌范围添加超过 200 个项目。

配置作业令牌范围:

  1. 在左侧边栏,选择 搜索或跳转至 并找到您的项目。
  2. 选择 设置 > CI/CD
  3. 展开 作业令牌权限
  4. 切换 限制从此项目访问 为启用状态。
  5. 可选。将现有项目添加到令牌的访问范围。添加项目的用户必须在两个项目中拥有 Maintainer 角色。

作业令牌身份验证日志

您可以在身份验证日志中跟踪哪些其他项目使用 CI/CD 作业令牌向您的项目进行身份验证。要检查日志:

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

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

对新项目的身份验证可能需要最多 5 分钟才会出现在身份验证日志中。

使用 CI/CD 令牌的旧格式

从 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 克隆:

    $ git clone https://gitlab-ci-token:[email protected]/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 作业令牌将失效。

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 个字符的字符串换行。在作业执行期间使用 base64 编码 JWT 格式作业令牌时,例如使用 echo $CI_JOB_TOKEN | base64,令牌将变为无效。

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