4. 凭据生命周期管理:创建、存储、分发、使用、轮换、吊销

凭据这东西,说白了就是一把钥匙。钥匙从造出来到最后扔掉,每一步都得有规矩。我见过不少团队,上来就搞自动化轮换,结果发现最根本的阶段——比如创建、存储——全是漏洞,轮换再快也没用。

今天咱们就把凭据的整个生命周期拆开揉碎。一共六个阶段:创建 → 存储 → 分发 → 使用 → 轮换 → 吊销。每个阶段我都踩过坑,咱们一个一个来。

4.1 创建:别让烂种子长出歪树

凭据创建是第一关,也是最容易被忽视的一关。我记得有个项目,开发图省事,直接在代码里写死了静态口令,结果上线第一天就被爬虫扫出来了。

好的创建策略应该满足三条:

  • 随机性足够:用安全的伪随机数生成器(比如 /dev/urandom),别用时间戳取模。
  • 长度和复杂度达标: 至少 32 字节,密钥至少 256 位。不要为了好记缩短。
  • 唯一标识:每条凭据都要有 ID,方便后续追踪吊销。
我的习惯:创建时顺便生成一个版本号(如 v1、v2),轮换时直接递增版本。这样看日志就知道哪条凭据在干活。

4.2 存储:别把钥匙挂门把手上

凭据存哪儿?我曾经见过把数据库密码写在配置文件里,还提交到 Git 仓库的——这相当于把家门钥匙挂在门把手上,还贴了张纸条写着“钥匙在这”。

推荐的存储方式:

存储方式 适用场景 注意
专用凭据管理服务 所有生产环境 如 AWS Secrets Manager、HashiCorp Vault
平台内置的 Secret Store Kubernetes、云厂商 记得开启加密,默认不加密
环境变量+加密文件 本地开发、CI/CD 必须用工具如 sops、git-crypt 加密
禁止:把凭据硬编码在代码里、明文写在配置文件、或放在公共网盘。我在代码审计时见过太多这种案例,没有一个有好下场。

4.3 分发:安全送到,不被劫持

凭据从存储系统到使用者手里的过程,叫分发。这个阶段最容易出问题。你想想看,如果存储挺安全,但传输时被中间人截获了,那前面的努力全白费。

分发要遵循两个原则:

  • 最小权限:谁要用才给谁,而且只给所需的那一条,别整库给。
  • 安全通道:必须使用 TLS 1.2+,或者通过 SDK 内部 API 直接注入,不走中间环节。

避坑指南:我曾经把一个 AWS Secrets Manager 的 GetSecretValue 权限配得太宽,结果 Jenkins 构建节点能读到生产数据库密码。幸好那次只是在测试环境,否则就是重大事故。

4.4 使用:用了就要留下痕迹

凭据被应用进程加载后,开始干活。这个阶段的核心是审计和短时使用。

我建议每次使用都要记录:谁、在什么时间、用了哪条凭据、干了什么。别等到出事了才去翻日志,那时候往往已经晚了。

另外,尽量让凭据在内存中存活时间短一点。用完就释放或置零。像 Go 的 runtime.KeepAlive + memclr 可以主动擦除敏感内存。

小技巧:SDK 集成时,让凭据只在请求作用域内存在,别挂到全局变量上。我之前一个项目就因为全局缓存凭据,导致轮换后旧的还在跑,整整排查了一下午。

4.5 轮换:自动换锁,别等丢了才换

轮换是这个课程的核心主题。说白了就是定期换密码/密钥/。但手动换?那还不如不换,因为人一定会忘、会出岔子。

轮换策略分两种:

  1. 主动轮换:基于时间,比如每 90 天自动生成新凭据并切换。
  2. 事件驱动轮换:泄露告警触发,立即吊销旧凭据并生成新的。

我建议两套都上。只要轮换过程完全自动化、零 downtime,就可以放心大胆地缩短周期。

经验之谈:轮换时要确保“旧凭据平滑过渡”。我的做法是让新旧凭据并存一小段时间(比如 5 分钟),等所有连接都切换到新凭据后,再吊销旧的。直接一刀切,肯定会有客户端报 401。

4.6 吊销:钥匙丢了,必须废掉

吊销是生命周期的终点。但很多人的做法是:直接删除。这很危险。为啥?因为删除后可能还有延迟使用的连接,或者审计记录丢失。

正确的吊销流程:

  • 标记为吊销(不可用),而不是物理删除。
  • 记录吊销时间、原因、操作人,形成审计线索。
  • 保留一段时间(比如 30 天),之后再归档或彻底清除。
注意:吊销不能影响正在进行的业务。一定要先确认所有使用者都切换到了新凭据,才能执行吊销。我见过一个项目,轮换完了但忘了吊销旧凭据,结果旧 被黑客利用了三个星期才发现。

凭据生命周期六阶段流程图 凭据生命周期流程图 创建 存储 分发 使用 轮换 吊销 生命周期持续迭代 说明: 凭据按顺序从左到右流动,每个阶段都有对应的安全措施。吊销完成后重新回到创建阶段,形成闭环。

六个阶段看起来很简单吧?但实际落地时,每个阶段都可能变成事故现场。我个人习惯是先把这六个阶段画成看板贴在团队墙面上,每次改凭据相关代码都对照一遍,看漏了哪个环节。