GitLab CI/CD 作业令牌

当流水线作业即将运行时,极狐GitLab 会生成一个唯一的令牌并将其作为 CI_JOB_TOKEN 预定义变量 注入。

您可以使用 GitLab CI/CD 作业令牌对特定 API 端点进行身份验证:

  • 软件包:
    • 软件包库。
    • 容器镜像库($CI_REGISTRY_PASSWORD$CI_JOB_TOKEN)。
    • 容器镜像库 API(当启用 ci_job_token_scope 功能标志时,范围限定于作业的项目)。
  • 获取作业产物。
  • 获取作业令牌的作业。
  • 流水线触发器,使用 token= 参数。
  • 发布。
  • Terraform 方案。
note私有化部署管理版存在已知问题,会阻止您在内部项目中使用作业令牌。

令牌与导致作业运行的用户具有相同的访问 API 的权限。用户可以通过推送提交、触发手动作业、成为计划流水线的所有者等方式使作业运行。因此,必须将此用户分配给具有所需权限的角色。

令牌仅在流水线作业运行时有效。作业完成后,您将无法再使用令牌。

作业令牌无需任何配置即可访问项目的资源,但它可能会授予不必要的额外权限。

您还可以使用作业令牌从 CI/CD 作业中的私有项目中验证和克隆仓库:

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

GitLab CI/CD 作业令牌安全

为确保此令牌不会泄漏:

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

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

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

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

限制 GitLab CI/CD 作业令牌访问

  • 引入于 14.1 版本。部署在 :ci_scoped_job_token 功能标志后默认禁用。
  • 适用于自助管理版于 14.4 版本。
在自助管理实例上,默认情况下此功能可用。要隐藏该功能,请让管理员禁用 ci_scoped_job_token 标志。

您可以限制项目的 CI/CD 作业令牌的访问范围以提高作业令牌的安全性。作业令牌可能会授予访问特定私有资源所不需要的额外权限。 如果作业令牌被泄露,它可能被用于访问作业令牌用户私有的数据。通过限制作业令牌访问范围,除非项目明确授权,否则无法访问私有数据。

通过使用当前项目的作业令牌进行身份验证,通过授权访问的其他项目的许可名单来控制作业令牌访问范围。默认情况下,令牌范围只允许访问令牌来自的同一个项目。 有权访问这两个项目的维护人员可以添加和删除其他项目。

默认情况下,所有新项目都禁用此设置。建议项目维护者或所有者始终启用此设置,并在需要时配置跨项目访问的许可名单。

例如,启用该设置后,项目 A 流水线中的作业的 CI_JOB_TOKEN 范围仅限于项目 A。如果作业需要使用令牌向私有项目 B 发出 API 请求,则必须将 B 添加到 A 的许可名单中。 如果项目 B 是公开的或内部的,则不需要将其添加到许可名单中。 作业令牌范围仅用于控制对私有项目的访问。

配置作业令牌范围限制

  1. 在顶部栏上,选择 主菜单 > 项目 并找到您的项目。
  2. 在左侧边栏上,选择 设置 > CI/CD
  3. 展开 令牌访问
  4. 限制 CI_JOB_TOKEN 访问 切换为启用。
  5. (可选)将现有项目添加到令牌的访问范围。添加项目的用户必须在两个项目中都具有维护者角色。

从不同的流水线下载产物

您可以使用 CI_JOB_TOKEN 从先前流水线创建的作业中访问产物。您必须指定要从中检索产物的作业:

build_submodule:
  stage: test
  script:
    - apt update && apt install -y unzip
    - curl --location --output artifacts.zip "https://gitlab.example.com/api/v4/projects/1/jobs/artifacts/main/download?job=test&job_token=$CI_JOB_TOKEN"
    - unzip artifacts.zip

故障排查

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

  • 未经授权的 Git 克隆:

    $ 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 作业令牌身份验证问题进行故障排查时,请注意:

  • 当启用了 CI/CD 作业令牌限制,并且作业令牌被用于访问不同的项目时:
  • 如果作业不再运行、已被删除或项目正在被删除,则 CI 作业令牌将无效。