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

GitOps 是一组实践,它将 Git 作为声明式基础设施和应用程序的唯一事实来源,并通过版本控制自动化部署流程。在这种模型中,对系统的任何更改都通过 Git 提交和自动化流水线进行,从而确保一致性和可追溯性。
在 GitOps 工作流中管理密钥会带来独特的挑战,需要仔细权衡安全性、自动化和开发者体验。本指南探讨了 GitOps 中不同的密钥管理方法,并重点介绍如何将 Infisical 集成到你的工作流中。
传统的 GitOps 密钥管理方法通常会使用 Kubeseal 和 SOPS 等工具,来安全地处理 Git 仓库中的敏感数据。这些工具使用公钥加密技术,在机密信息提交到版本控制系统之前对其进行加密。加密后的密钥可以安全地与应用代码一同存储,在保护敏感数据的同时保持 GitOps 原则。
部署时,运行在目标 Kubernetes 集群中的专用密钥控制器(例如 SealedSecrets controller)会解密这些加密文件,并创建相应的 Kubernetes Secret,从而在整个部署流水线中实现安全且自动化的密钥管理。
虽然这保留了版本控制的优势,但也引入了重大的运维挑战:

现代云原生架构通常需要更动态的密钥管理方法。这就是为什么在达到一定规模后,许多团队开始转向基于引用的方法,例如 External Secrets Operator。这类方法只在 Git 中存储对密钥的引用,并从外部密钥管理系统中获取实际密钥。这种基于引用的架构带来了显著优势:
让我们来看看如何使用 Infisical 实现这些原则。Infisical 是一款专为现代 GitOps 工作流设计的现代密钥管理工具。
让我们使用一些流行工具来构建一个安全的 GitOps 流水线,以展示 Infisical 如何集成到你的工作流中。我们将使用许多团队已经在采用的常见技术栈:

下面的示例工作流使用 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 配置中,你可以使用这些注入的凭证,通过 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
这套基础设施配置为密钥管理打下了坚实基础。接下来,我们看看如何将这些原则应用到应用程序流水线中。
接下来,我们使用 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 平台,例如 CircleCI、Jenkins 或 Azure DevOps,其原则都是一样的:安装 Infisical CLI,并在流水线执行期间使用它来注入密钥。
在使用 Argo CD 的 GitOps 工作流中实现密钥管理时,有三种主要方式可以将 Infisical 集成进去,每种方式在声明式配置和安全性方面都有不同的权衡。这些选项允许团队在保持 GitOps 原则的同时,用更安全、更灵活的方法替代普通的 Kubernetes Secret。
Infisical Operator 是一种原生方案,提供三个具有不同能力的 Custom Resource Definitions (CRD):
InfisicalSecret - 将密钥从 Infisical 同步到 KubernetesInfisicalPushSecret - 将新的密钥从 Kubernetes 推送到 InfisicalInfisicalDynamicSecret - 使用自动的时限租约管理动态密钥下面是 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 工作流中。
优点:
最适合:
在 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 后端的安全性。
优点:
最适合:
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 状态会更难追踪。
优点:
最适合:
另请阅读:Kubernetes Secrets Management in 2025 - A Complete Guide
原生密钥管理解决方案,如 GitHub Secrets、AWS Parameter Store 和 AWS Secrets Manager,在各自的生态系统中都能很好地工作。然而,将专用的密钥管理服务作为唯一事实来源,可以强化你的架构,并在更新密钥、集成新组件、团队成员入职,或在不同供应商之间迁移等常见场景中节省大量时间:
重要原因: 安全漏洞通常会因权限过大而不断扩大。最小权限访问可以最小化攻击面,并限制潜在安全事件的影响。
关键考虑:
重要原因: 静态密钥会随着时间推移,因为暴露和凭证共享而变得更加脆弱。定期轮换可以降低潜在泄露带来的影响。
关键考虑:
重要原因: 如果没有适当的审计轨迹,检测和响应安全事件几乎是不可能的。审计日志有助于满足合规要求,并支持事件调查。
关键考虑:
重要原因: CI/CD 流水线同时可以访问源代码和生产环境,因此对攻击者极具吸引力。
关键考虑:
这些实践是保护 GitOps 工作流的良好起点。关键在于为你的具体环境找到安全控制与开发者生产力之间的正确平衡。
在 Infisical,我们非常重视“eat your own dog food”!我们很快会发布一篇详细的博客文章,准确说明我们如何在生产环境中管理自己的密钥。
先剧透一下:这套方案相当不错!我们通过自己的 web app 处理一切(当然!),并且已经自动化了与 AWS Parameter Store 和 GitHub Secrets 的同步,因此一切都能保持协调:在部署方面,我们让 GitHub Actions 和 Argo CD 承担主要工作,而我们自己的 Infisical Secrets Operator 则在 Kubernetes 集群中负责管理密钥。
当然,我们也会跟踪每一次访问和变更。毕竟,当你在构建安全工具时,就必须以身作则!
无论你是刚开始使用 GitOps,还是正在管理一个复杂的多集群环境,这里讨论的原则和模式都将帮助你构建一个更安全、更易维护的系统。
我们正在看到 GitOps 自动化、开发者体验和安全控制方面一些非常有意思的趋势,这也正是我们按今天这种方式构建 Infisical 的原因。我们想打造一个真正好用的产品——一个存放所有密钥的中心位置,配备开发者真正愿意使用的工具,并且可以按你想要的方式、在你想要的任何地方运行。
无论你的团队有五个人还是五百个人,无论你是全面上云还是坚持本地部署,通过在 GitOps 工作流中引入 Infisical,你都在为安全、可扩展且对开发者友好的密钥管理打下基础,而这一基础也会随着你的组织一同成长。

技术作者,Infisical
开始使用 Infisical 很简单、快速,而且免费。
- 原文链接: infisical.com/blog/gitop...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!
作者暂未设置收款二维码