安全的 GitOps 工作流:密钥管理实践指南

  • infisical
  • 发布于 2025-01-30 20:26
  • 阅读 84

本文围绕 GitOps 场景下的密钥管理展开,指出传统把密钥加密后写入 Git 的方案虽然保留了版本控制优势,但在轮换、动态更新、多集群管理和运维复杂度上存在明显问题。

Secure GitOps Workflows: A Practical Guide to Secrets Management

发布于 2025 年 1 月 29 日星期三

Blog image

GitOps 是一组实践,它将 Git 作为声明式基础设施和应用程序的唯一事实来源,并通过版本控制自动化部署流程。在这种模型中,对系统的任何更改都通过 Git 提交和自动化流水线进行,从而确保一致性和可追溯性。

在 GitOps 工作流中管理密钥会带来独特的挑战,需要仔细权衡安全性、自动化和开发者体验。本指南探讨了 GitOps 中不同的密钥管理方法,并重点介绍如何将 Infisical 集成到你的工作流中。

为什么现代 Secrets Management 工具很重要

传统的 GitOps 密钥管理方法通常会使用 KubesealSOPS 等工具,来安全地处理 Git 仓库中的敏感数据。这些工具使用公钥加密技术,在机密信息提交到版本控制系统之前对其进行加密。加密后的密钥可以安全地与应用代码一同存储,在保护敏感数据的同时保持 GitOps 原则。

部署时,运行在目标 Kubernetes 集群中的专用密钥控制器(例如 SealedSecrets controller)会解密这些加密文件,并创建相应的 Kubernetes Secret,从而在整个部署流水线中实现安全且自动化的密钥管理。

虽然这保留了版本控制的优势,但也引入了重大的运维挑战:

  • Secret rotation 需要谨慎编排,以防止服务中断
  • 当密钥需要动态更新时,版本控制工作流会与实时运维需求产生冲突
  • 在集群侧运行的 operator 会带来管理开销并增加系统复杂性
  • 当处理多个集群和团队时,管理加密密钥会变得越来越复杂

Challenges in GitOps Secrets Management

现代云原生架构通常需要更动态的密钥管理方法。这就是为什么在达到一定规模后,许多团队开始转向基于引用的方法,例如 External Secrets Operator。这类方法只在 Git 中存储对密钥的引用,并从外部密钥管理系统中获取实际密钥。这种基于引用的架构带来了显著优势:

  • 你可以在不修改部署流水线或触发新构建的情况下,动态更新密钥
  • 团队可以通过统一界面更高效地轮换和管理密钥
  • 中心化的密钥管理器能为整个基础设施提供全面的审计日志和细粒度访问控制
  • 通过将密钥管理从应用工作流中移除,你可以降低维护单独加密和轮换机制所带来的运维复杂性

让我们来看看如何使用 Infisical 实现这些原则。Infisical 是一款专为现代 GitOps 工作流设计的现代密钥管理工具。

使用 Infisical 构建安全的 GitOps Pipeline

让我们使用一些流行工具来构建一个安全的 GitOps 流水线,以展示 Infisical 如何集成到你的工作流中。我们将使用许多团队已经在采用的常见技术栈:

Modern GitOps Pipeline with Infisical

1. 使用 Terraform 进行基础设施 Provisioning

设置 OIDC Authentication

下面的示例工作流使用 OpenID Connect (OIDC) 对 Infisical 进行身份验证,从而无需使用静态Token。要使用这种方式,请为你的项目配置一个使用 “OIDC Auth” 方法的 Machine Identity

name: Terraform Apply
on:
  push:
    branches: [main]
    paths: ['terraform/**']

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v3

      - name: Request OIDC Token
        run: |
          echo "Requesting OIDC token..."
          TOKEN=$(curl -s -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL" | jq -r '.value')
          echo "INFISICAL_AUTH_JWT=$TOKEN" >> $GITHUB_ENV

      - name: Apply Terraform
        run: terraform apply -auto-approve

OIDC 会在运行时生成短期凭证,从而将长期有效的密钥移出 CI/CD 流水线。在这个工作流中,我们需要显式地向 GitHub Actions 请求 OIDC Token,并将其设置为环境变量(INFISICAL_AUTH_JWT),供 Infisical Terraform provider 用于身份验证。这个额外步骤确保了 GitHub 工作流与 Infisical 之间能够安全完成身份验证,而无需存储任何静态凭证。

请求到的 OIDC Token仅在工作流运行期间临时存在,不会在两次运行之间持久化到 GitHub Actions 的环境存储中,从而显著提升你的安全性。

在 Terraform 中使用 Secrets

在 Terraform 配置中,你可以使用这些注入的凭证,通过 Infisical provider 安全地访问密钥:

 terraform {
  required_providers {
    infisical = {
      source = "infisical/infisical"
    }
  }
}

provider "infisical" {
  auth {
    oidc {
      identity_id = "your-machine-identity-id"
      # The provider will use the INFISICAL_AUTH_JWT environment variable
      # that we set in the GitHub Action workflow
    }
  }
}

ephemeral "infisical_secret" "db_creds" {
  name         = "DB_PASSWORD"
  env_slug     = "prod"
  workspace_id = var.infisical_workspace_id
  folder_path  = "/"
}

## 在其他资源中使用该 secret
resource "aws_db_instance" "example" {
  password = ephemeral.infisical_secret.db_creds.value
  # ...
}

ephemeral 资源类型确保密钥只在 Terraform 操作期间被访问,并且不会存储在 state 文件中,从而降低整个基础设施生命周期中的攻击面。阅读我们关于 ephemeral resources 的深度指南:Everything You Need to Know About Terraform's Ephemeral Resources

这套基础设施配置为密钥管理打下了坚实基础。接下来,我们看看如何将这些原则应用到应用程序流水线中。

2. 应用程序 Secrets Provisioning

接下来,我们使用 Infisical Secrets Action 在应用构建流水线中安全地注入密钥:

name: Build Container
on:
  push:
    branches: [main]
    paths: ['app/**']

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v3

      - uses: Infisical/secrets-action@v1.0.7
        with:
          method: oidc
          identity-id: "your-machine-identity-id"
          project-slug: "your-project-slug"
          env-slug: "prod"

      - name: Build application
        run: |
          docker build -t myapp:latest .

虽然我们的示例使用的是 GitHub Actions,但在其他 CI/CD 平台上,集成模式也基本相同。无论你使用的是 GitLab CI 还是其他 CI/CD 平台,例如 CircleCIJenkinsAzure DevOps,其原则都是一样的:安装 Infisical CLI,并在流水线执行期间使用它来注入密钥。

3. 使用 ArgoCD 进行 Kubernetes 部署

在使用 Argo CD 的 GitOps 工作流中实现密钥管理时,有三种主要方式可以将 Infisical 集成进去,每种方式在声明式配置和安全性方面都有不同的权衡。这些选项允许团队在保持 GitOps 原则的同时,用更安全、更灵活的方法替代普通的 Kubernetes Secret。

选项 1:Infisical Kubernetes Operator(最符合 GitOps 原生模式)

Infisical Operator 是一种原生方案,提供三个具有不同能力的 Custom Resource Definitions (CRD):

  1. InfisicalSecret - 将密钥从 Infisical 同步到 Kubernetes
  2. InfisicalPushSecret - 将新的密钥从 Kubernetes 推送到 Infisical
  3. InfisicalDynamicSecret - 使用自动的时限租约管理动态密钥

下面是 InfisicalSecret CRD 的示例 manifest:

apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalSecret
metadata:
  name: infisicalsecret-sample
  labels:
    label-to-be-passed-to-managed-secret: sample-value
  annotations:
    example.com/annotation-to-be-passed-to-managed-secret: "sample-value"
spec:
  hostAPI: https://app.infisical.com/api
  resyncInterval: 10
  authentication:
    kubernetesAuth:
      identityId: <machine-identity-id>
      serviceAccountRef:
        name: <service-account-name>
        namespace: <service-account-namespace>

这将生成一个受管理的 Kubernetes Secret:

apiVersion: v1
kind: Secret
metadata:
  annotations:
    example.com/annotation-to-be-passed-to-managed-secret: sample-value
    secrets.infisical.com/version: W/"3f1-ZyOSsrCLGSkAhhCkY2USPu2ivRw"
  labels:
    label-to-be-passed-to-managed-secret: sample-value
  name: managed-token
  namespace: default
type: Opaque
data: ...

该 operator 会持续监控变更,并自动更新 Kubernetes Secret 以保持同步。它还可以在相关密钥更新时,自动重新加载依赖的 Deployment 资源。安装通过 Helm 完成,因此很容易集成到现有 Kubernetes 工作流中。

优点:

  • 完全声明式
  • 双向同步
  • 支持动态密钥
  • 所有密钥配置都与其他 manifest 一起纳入版本控制
  • 自动重新加载部署
  • 与 ArgoCD 的 auto-sync 和 health checking 功能自然集成

最适合:

  • 需要双向密钥同步的环境
  • 涉及动态密钥的用例
  • 更偏好原生集成而非第三方 operator 的团队
选项 2:External Secrets Operator

在 External Secrets Operator 架构中,ExternalSecrets 用于声明要获取哪些数据。随后,controller 会从 secret store 中获取密钥,并将这些值注入到 Kubernetes Secret 中。

下面的示例 manifest 将 Infisical SecretStore 定义为存放 service token 的后端,并定义了一个引用敏感 DATABASE_URL 的 ExternalSecret:

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: infisical-store
spec:
  provider:
    infisical:
      serviceToken:
        secretRef:
          name: infisical-credentials
          key: serviceToken
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: application-secrets
spec:
  secretStoreRef:
    name: infisical-store
    kind: SecretStore
  target:
    name: app-secrets
  data:
    - secretKey: DATABASE_URL
      remoteRef:
        key: database_url

ExternalSecrets 本身不会执行任何密码学操作,例如加密或解密密钥,而是完全依赖 Secret Store 后端的安全性。

优点:

  • 原生 Kubernetes 资源管理
  • 自动同步密钥
  • 支持多个密钥后端
  • 内置密钥轮换能力
  • 非常适合 GitOps 工作流

最适合:

  • 已经在使用 Kubernetes operator 的团队
  • 需要自动密钥轮换的环境
  • 多集群部署
选项 3:Secrets Store CSI Driver

Secrets Store CSI driver(顾名思义)并不是作为一个 controller 来将数据协调到 Secret 资源中,而是使用一个单独的卷挂载到 Kubernetes pod 中,以承载这些密钥:

apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: infisical-secrets
spec:
  provider: infisical
  parameters:
    serviceToken: "${SERVICE_TOKEN}"
    projectId: "${PROJECT_ID}"
    secrets: |
      - secretPath: "database_url"
        version: "latest"

了解如何安装 Infisical CSI provider

这种方法的优点在于它完全绕过了 Kubernetes Secret。另一方面,在上述三种方案中,它更侧重于运行时的密钥挂载,而不是声明式配置,因此整体 GitOps 状态会更难追踪。

优点:

  • 直接在 pod 级别挂载密钥
  • 没有中间的 Kubernetes Secret
  • 无需重启 pod 即可自动更新密钥
  • 运维开销更低

最适合:

  • 需要直接挂载密钥的应用
  • 高安全环境
  • 密钥不可变性很重要的场景
  • 对性能要求较高的应用

另请阅读:Kubernetes Secrets Management in 2025 - A Complete Guide

为什么使用专用的 Secrets Management Service?

原生密钥管理解决方案,如 GitHub Secrets、AWS Parameter Store 和 AWS Secrets Manager,在各自的生态系统中都能很好地工作。然而,将专用的密钥管理服务作为唯一事实来源,可以强化你的架构,并在更新密钥、集成新组件、团队成员入职,或在不同供应商之间迁移等常见场景中节省大量时间:

  1. 你不再将密钥分散在不同工具和平台中,而是有一个地方统一管理一切。这意味着你可以使用策略和访问控制轻松控制谁可以访问哪些密钥Just-in-time accessRBAC,再加上授予额外权限的能力,支持最小权限原则,同时兼顾紧急需求下的灵活性。
  2. 当安全工具难以使用时,团队往往会绕开它们,从而制造漏洞。一个统一的解决方案,配合直观的控制面板、全面的 API 和功能完善的 CLI,能够确保在整个组织内持续执行一致的策略。这种安全性与易用性的结合,有助于团队自然而然地遵循最佳实践。
  3. 灵活性:你可以根据安全需求和基础设施策略,在 self-hosted 和 cloud deployment 之间进行选择。这种灵活性帮助你在适应不断变化的需求时,依然保持对密钥管理基础设施的控制。
  4. 专用的密钥管理服务充当整个技术栈的通用适配器。这一抽象层简化了在不同供应商或服务之间的迁移,降低了锁定风险和技术债务。
  5. 通过详细的 audit logs 跟踪所有密钥访问和修改。这种可见性通常是合规要求所必需的,同时在你需要调查安全事件时也具有明显优势。
  6. 持续的 secret scanning 或安全的 secret sharing 等功能,有助于防止意外泄露,例如将密钥提交到版本控制系统中。这种主动式方法可以在风险演变为安全事件之前将其降低。

GitOps Secrets Management 的安全最佳实践

1. 实施最小权限访问

重要原因: 安全漏洞通常会因权限过大而不断扩大。最小权限访问可以最小化攻击面,并限制潜在安全事件的影响。
关键考虑:

  • 为不同组件创建细粒度的 service account
  • 在维护时使用临时提升的访问权限
  • 定期审计并撤销未使用的权限
  • 实施清晰的访问申请流程

2. 定期轮换 Secrets

重要原因: 静态密钥会随着时间推移,因为暴露和凭证共享而变得更加脆弱。定期轮换可以降低潜在泄露带来的影响。

关键考虑:

  • 使用原生平台身份验证(如 OIDC),以避免管理 “secret zero” 凭证
  • 实施自动轮换计划
  • 尽可能使用短期凭证
  • 保持密钥版本管理
  • 为紧急轮换流程做好规划

3. 启用审计轨迹

重要原因: 如果没有适当的审计轨迹,检测和响应安全事件几乎是不可能的。审计日志有助于满足合规要求,并支持事件调查。

关键考虑:

  • 在 Infisical 中启用详细日志记录:
    • 跟踪所有密钥访问
    • 监控配置变更
    • 记录管理操作
  • 在 Kubernetes 集群中实施日志记录
  • 设置日志聚合和分析:
    • 使用 ELK stack 或 CloudWatch 等工具
    • 为可疑活动设置告警
    • 保持日志保留策略

4. 安全配置 CI/CD Pipeline

重要原因: CI/CD 流水线同时可以访问源代码和生产环境,因此对攻击者极具吸引力。

关键考虑:

  • 保护 GitHub Actions 工作流
  • 实施分支保护
  • 使用 OIDC 进行云服务提供商身份验证
  • 对敏感变更实施强制审查
  • 扫描依赖和容器
  • 为预发布环境和生产环境维护独立环境

这些实践是保护 GitOps 工作流的良好起点。关键在于为你的具体环境找到安全控制与开发者生产力之间的正确平衡。

我们在 Infisical 如何处理自己的 Secrets

在 Infisical,我们非常重视“eat your own dog food”!我们很快会发布一篇详细的博客文章,准确说明我们如何在生产环境中管理自己的密钥。

先剧透一下:这套方案相当不错!我们通过自己的 web app 处理一切(当然!),并且已经自动化了与 AWS Parameter Store 和 GitHub Secrets 的同步,因此一切都能保持协调:在部署方面,我们让 GitHub Actions 和 Argo CD 承担主要工作,而我们自己的 Infisical Secrets Operator 则在 Kubernetes 集群中负责管理密钥。

当然,我们也会跟踪每一次访问和变更。毕竟,当你在构建安全工具时,就必须以身作则!

展望未来:GitOps Secrets Management 的未来

无论你是刚开始使用 GitOps,还是正在管理一个复杂的多集群环境,这里讨论的原则和模式都将帮助你构建一个更安全、更易维护的系统。

我们正在看到 GitOps 自动化、开发者体验和安全控制方面一些非常有意思的趋势,这也正是我们按今天这种方式构建 Infisical 的原因。我们想打造一个真正好用的产品——一个存放所有密钥的中心位置,配备开发者真正愿意使用的工具,并且可以按你想要的方式、在你想要的任何地方运行。

无论你的团队有五个人还是五百个人,无论你是全面上云还是坚持本地部署,通过在 GitOps 工作流中引入 Infisical,你都在为安全、可扩展且对开发者友好的密钥管理打下基础,而这一基础也会随着你的组织一同成长。

Thomas Segura avatar

Thomas Segura

技术作者,Infisical

开始使用 Infisical 很简单、快速,而且免费。

  • 原文链接: infisical.com/blog/gitop...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
infisical
infisical
江湖只有他的大名,没有他的介绍。