从流水线变量迁移到流水线输入:提升CI/CD安全性的完整指南

本文详细介绍了如何从传统的GitLab CI/CD流水线变量迁移到更安全的流水线输入功能,包括显式声明、类型安全、内置验证等安全优势,以及具体的迁移步骤和最佳实践。

从流水线变量迁移到流水线输入

为更好的安全性迁移

流水线变量长期以来一直是运行时自定义 GitLab CI/CD 流水线的便捷方式。然而,随着 CI/CD 安全最佳实践的发展,我们认识到需要对流水线自定义进行更强的控制。无限制的流水线变量允许任何具有流水线触发权限的用户在没有验证或类型检查的情况下覆盖值。

除了安全考虑之外,流水线变量缺乏适当的文档和显式声明,使得很难理解需要什么输入以及它们在整个流水线中的使用方式。这可能导致维护挑战,并使得难以对 CI/CD 流程建立适当的治理。

引入流水线输入

我们强烈建议使用 GitLab 的流水线输入功能,而不是依赖流水线变量。流水线输入提供:

  • 显式声明:输入必须在 .gitlab-ci.yml 中显式声明,并且是自文档化的
  • 类型安全:支持不同的输入类型(字符串、布尔值、数字、数组)
  • 内置验证:自动验证输入值
  • 更好的安全性:没有变量注入攻击的风险——只有声明的输入可以从外部传递

基础示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
spec:
  inputs:
    deployment_env:
      description: "目标部署环境"
      type: string
      options: ["staging", "production"]
      default: "staging"
    enable_tests:
      description: "运行测试套件"
      type: boolean
      default: true

test:
  script:
    - echo "运行测试"
  rules:
    - if: $[[ inputs.enable_tests ]] == true

deploy:
  script:
    - echo "部署到 $[[ inputs.deployment_env ]]"

限制流水线变量

要有效迁移到流水线输入并远离流水线变量,您应该配置"使用流水线变量的最低角色"设置。此设置提供了对哪个角色在触发流水线时可以使用流水线变量的细粒度控制。

在项目级别:导航到项目的设置 > CI/CD > 变量 > 使用流水线变量的最低角色来配置设置。

可用选项包括:

  • 不允许任何人 (no_one_allowed) - 推荐且最安全的选项。防止所有变量覆盖
  • 开发者 (developer) - 允许开发者及以上角色覆盖变量
  • 维护者 (maintainer) - 需要维护者角色或更高
  • 所有者 (owner) - 只有项目所有者可以覆盖变量

在群组级别:群组维护者可以转到设置 > CI/CD > 变量 > 使用流水线变量的默认角色,为其群组内所有新项目建立安全默认值,确保整个组织的一致安全策略。这里我们再次建议使用不允许任何人作为默认值——这样,此群组中的新项目将以安全默认设置创建。请注意,这仍然允许项目所有者更改设置。

当流水线变量被完全限制时(使用"不允许任何人"),预填充的变量将不会出现在"新流水线 UI"表单中。

如何从流水线变量迁移

填补空白

您的群组可能有一些项目默认启用了流水线变量,尽管在触发流水线时从未使用过它们。这些项目可以迁移到更安全的设置,而不会中断风险。GitLab 通过群组设置提供迁移功能:

  1. 转到设置 > CI/CD > 变量
  2. 在"在不使用流水线变量的项目中禁用流水线变量"中,选择开始迁移

此迁移是一个后台作业,它会安全地通过项目设置对所有历史上未使用流水线变量的项目禁用流水线变量。

将流水线变量转换为输入

为每个已识别的流水线变量创建相应的流水线输入。

之前(使用流水线变量)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
variables:
  DEPLOY_ENV:
    description: "部署环境"
    value: "staging"
  ENABLE_CACHE:
    description: "启用部署缓存"
    value: "true"
  VERSION:
    description: "应用程序版本"
    value: "1.0.0"

deploy:
  script:
    - echo "将版本 $VERSION 部署到 $DEPLOY_ENV"
    - |
      if [ "$ENABLE_CACHE" = "true" ]; then
        echo "缓存已启用"
      fi

之后(使用流水线输入)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
spec:
  inputs:
    deploy_env:
      description: "部署环境"
      type: string
      default: "staging"
      options: ["dev", "staging", "production"]

    enable_cache:
      description: "启用部署缓存"
      type: boolean
      default: true
    
    version:
      description: "应用程序版本"
      type: string
      default: "1.0.0"
      regex: '^[0-9]+\.[0-9]+\.[0-9]+$'

deploy:
  script:
    - echo "将版本 $[[ inputs.version ]] 部署到 $[[ inputs.deploy_env ]]"
    - |
      if [ "$[[ inputs.enable_cache ]]" = "true" ]; then
        echo "缓存已启用"
      fi

迁移触发作业

如果您使用带有 trigger 关键字的触发作业,请确保它们没有定义作业级变量或禁用从顶级变量、extends 或 include 继承变量,因为变量可能隐式地作为流水线变量传递到下游。如果下游项目限制了流水线变量,流水线创建将失败。

考虑更新您的 CI 配置以使用流水线输入而不是流水线变量。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
variables:
  FOO: bar

deploy-staging:
  inherit:
    variables: false # 否则 FOO 将作为流水线变量发送到下游
  trigger:
    project: myorg/deployer
    inputs:
      deployment_env: staging
      enable_tests: true

总结

从流水线变量迁移到流水线输入是一项安全增强措施,可以保护您的 CI/CD 基础设施免受变量注入攻击,同时提供更好的文档、类型安全和验证。通过实施这些限制并采用流水线输入,您不仅提高了安全性,还使您的流水线更易于维护、自文档化和具有弹性。

过渡需要一些初始努力,但长期收益远远超过迁移成本。首先在群组级别为新项目限制流水线变量,然后使用上述逐步方法系统地迁移现有流水线。

安全不是目的地,而是一段旅程。流水线输入是创建更安全的 CI/CD 环境的重要一步,补充了 GitLab 的其他安全功能,如受保护分支、作业令牌允许列表和容器注册表保护。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计