7AA7 博客

密钥与配置管理:Vault 与 Sealed Secrets

Vector 陈 UID:125
2026-09-29 19:47
114 2 3

配置与密钥都能改变应用行为,但泄露后果不同。端口、功能开关、重试次数通常可公开评审,适合进入普通配置仓库;数据库密码、签名私钥、访问令牌和加密材料不可公开,需要限制读取、轮换和审计。判断标准不是文件名,而是内容泄露后是否会赋予权限、暴露数据或破坏身份可信度。

密钥不能以明文进入 Git

把密钥从当前分支删除,并不等于它已经消失。Git 对象、历史提交、分支、标签、代码评审缓存、CI 工作区和开发者本地克隆都可能保留副本。重写历史还会影响协作,也无法证明所有副本已被清除。因此一旦发现明文入库,应立即吊销或轮换该凭据,再评估历史清理;只提交一次“删除密码”的修复并不安全。

忽略文件只能防止未来误提交,无法代替扫描与权限控制。提交前钩子可拦截明显模式,服务端扫描负责统一门禁,但两者都可能误报或漏报。更稳妥的做法是让仓库只出现密钥引用或密文,并使开发、CI 和运行环境通过各自身份获取所需值。

Kubernetes Secret 中的 data 默认只是 Base64 编码,不是保密加密。能读取对象、备份或底层存储的人仍可能获得明文。集群需要启用静态加密、严格 RBAC 和审计,同时避免把 Secret 直接导出到工单与聊天记录。

加密即代码与 Sealed Secrets

“加密即代码”允许把密文清单提交仓库,通过常规评审和 GitOps 流程发布。以 Sealed Secrets 模式为例,提交者使用集群控制器的公钥加密秘密,仓库保存 SealedSecret;集群内控制器持有私钥,解密后创建普通 Secret。仓库和 CI 无需接触解密私钥。

apiVersion: example.io/v1
kind: SealedSecret
metadata:
  name: payment-credential
  namespace: checkout
spec:
  encryptedData:
    username: Ag...
    password: Ag...

密文通常可绑定命名空间与名称,防止被复制到另一个位置解密。修改对象名、目标命名空间或作用域时需要重新封装。密文不是永远安全:攻击者若同时获得控制器私钥和仓库历史,仍可解开旧值。私钥应备份、限制访问并建立轮换;恢复集群前要确认解密能力,否则仓库里的密文无法生成运行 Secret。

这种模式适合相对静态、由 Git 驱动交付的秘密。它不天然提供短期凭据、按请求授权或自动撤销,轮换仍需生成新密文并发布。频繁变化的数据库账号或云访问凭据更适合动态密钥系统。

Vault 的动态凭据与租约

Vault 类密钥服务集中保存静态秘密,也可以连接数据库、消息系统或基础设施接口,按应用身份即时生成短期凭据。每份动态凭据带租约和 TTL,到期可回收;应用停止或身份撤销后,租约也能提前终止。泄露影响面被限制在权限范围与有效时间内,而不是依赖一份多年不变的共享密码。

典型流程是工作负载用集群身份向 Vault 认证,策略只允许读取指定路径或申请指定角色,服务返回带租约的凭据,代理或应用在到期前续租。续租失败时不能无限使用旧值,应在租约剩余时间内重试、告警,并在过期前停止接受需要该凭据的新任务。

动态账号会增加下游系统的创建与回收压力。租约太短可能频繁轮换连接,租约太长又扩大泄露窗口。连接池需支持新旧凭据并存:新连接使用新凭据,旧连接在宽限期内完成,再撤销旧租约。

轮换不是简单覆盖

许多应用只在启动时读取一次密钥,后台替换值不会自动生效。直接撤销旧密钥可能让存量实例同时失败。更安全的双密钥过渡过程是:

  1. 创建新密钥,保持旧密钥仍有效;
  2. 发布新版本或通知应用重新加载,使新请求使用新密钥;
  3. 观察所有实例与调用方已切换,并验证新密钥成功率;
  4. 禁用旧密钥,监控失败调用,宽限期后删除。

服务端若只支持单密钥,可通过双账号、版本化密钥集合或分批重启实现过渡。签名密钥轮换还要保留旧公钥,直到旧令牌或旧签名的有效期结束。轮换流程应自动记录版本、责任人和撤销时间,并定期演练失效凭据的紧急轮换。

最小权限与审计

应用身份只应读取自身环境和用途对应的路径,不能因为部署方便获得整个团队的密钥树。写入、读取、轮换、吊销和策略管理要拆分权限;CI 负责发布密文时,不代表它应能读取生产明文。短期身份令牌也要绑定工作负载、命名空间或服务账号,防止被复制到其他环境使用。

审计日志应记录主体、时间、动作、路径、结果和租约标识,但不能记录密钥明文。审计存储本身需要防篡改与访问控制。高风险信号包括批量读取、非预期环境访问、策略扩大、频繁解密失败和长期未轮换。审计若无人查看,只是增加另一份敏感数据。

应用获取密钥的方式

方式 优点 主要泄露面与限制
环境变量 接入简单,多数框架支持 进程环境、崩溃报告、调试输出;难热更新
挂载文件 可设文件权限,可原子更新 节点与容器文件系统、误读备份;应用需监听变化
Sidecar/代理 代办认证、续租和模板渲染 本地共享卷或端口;代理故障与资源开销
应用直取 能精细控制租约与刷新 SDK 复杂度、错误处理进入应用

环境变量不要在启动日志中打印,诊断端点也应过滤。挂载文件要避免复制到镜像层或持久卷,读取后不应写入普通配置缓存。Sidecar 常把秘密渲染到内存卷,并负责续租;主应用仍需支持文件更新或受控重载。应用直取时要设置超时、本地短暂缓存和失败策略,防止密钥服务抖动直接放大为请求风暴。

密钥服务不可用时,已有租约在有效期内通常可继续工作,新实例却可能无法启动。容量与故障演练要覆盖“存量可运行、扩容拿不到密钥”的路径,并监控租约剩余时间、解密失败和轮换进度。把密文放进 Git 只是交付方式之一,完整体系还必须包含身份、最小权限、租约、轮换和可审计的应急撤销。

2.3k浏览量
114赞
2评论
2参与用户
7 分钟阅读时间

评论(2)

  • Elowen · 2026-09-29 22:19

    有个疑问:这个方案在容器里跑会有问题吗?

    回复
  • 朔风 · 2026-09-30 07:01

    看完默默把自己的方案删了。

    回复