相同的账户名称,不同的凭据
一句话总结
撤销权限会改变主体能做什么;服务账户 UID 改变,则会改变旧令牌指向的身份。即使以同名重建账户,旧令牌和现有 RoleBinding 也不会受到相同处理。
为什么需要它
假设收到 reader 令牌泄露的报告。运维人员删除账户,再以同名重建;看到旧令牌返回 401 后,便认为响应完成。但用新令牌查询时,仍能看到相同数据。难道令牌吊销失败了吗?
不要急于下结论,先确认删除了什么、保留了什么。账户虽已重建,面向该名称的 RoleBinding 可能仍在。只有理解权限重新连接到新身份的现象,才能正确定义事故响应的结束条件。
工作原理
名称相同,UID 不同
本实验保留现有 Pod 和 RoleBinding,只重建 SA。原令牌的 sub 是 system:serviceaccount:kcsa-identity:reader,新令牌的 sub 也相同,但两个令牌的服务账户 UID 不同。只比较人眼可见的名称,会把不同对象误认为同一对象。
探针在旧令牌过期前重建 SA。TokenReview 的认证结果变为 false,API 查询返回 401。由于同时记录了 exp 与观察时间,可以排除只是等待过久、令牌自然过期的解释。还确认了原有 Pod UID,以免把结果归因于重建 Pod。
绑定指向怎样的主体
RoleBinding 的 ServiceAccount 主体使用名称和命名空间。本实验绑定指向 kcsa-identity 的 reader,不会保存 SA 的旧 UID 并永久只允许该对象。请从每一列理解结果为何不同。
| 状态 | 旧令牌 | 新令牌 | 绑定 |
|---|---|---|---|
| 原账户、最小读取权限 | 自己的 ConfigMap 200 | 尚无 | 原绑定存在 |
| 清空 Role 的 rules | 认证 true,查询 403 | 尚无 | 仍然存在 |
| 恢复 Role 后重建 SA | 认证 false,查询 401 | 签发后查询 200 | 继续指向同一名称 |
| 删除绑定 | 继续 401 | 认证 true,查询 403 | 已删除 |
该表整理自个人集群中的真实观察。新令牌返回 200,并不证明旧令牌复活,而是新 UID 的认证结果与基于名称的授权相结合。绑定删除后的 403 也不表示新令牌失效;认证仍为 true 这一独立观察支持该解释。
删除时也不能只相信名称
先读取当前 UID 并与基线比较,再使用 UID、resourceVersion 前置条件请求删除。如果调查期间有人替换了对象,应停止并重新确认,而不是删除另一个对象。本工具只应修改原账户与绑定,不能因为名称相同就删除之后产生的其他对象。
实际现场中的情况
事故响应首先要同时调查泄露凭据、可用 API、相连工作负载和其他绑定。删除 SA 可能影响使用该账户的其他任务,不要把本实验的删除与重建原样复制到生产环境。应协调最小权限撤销、业务中断范围、凭据重发与重新部署、再次泄露原因的消除,再检查结束条件。
同时发送其他团队请求也有原因。如果只确认自己的请求被拒绝,即使破坏整个集群也可能看似成功。本实验确认另一个命名空间 reader 的认证 UID、合成 ConfigMap UID 和正常 200 响应保持不变。这只是两个命名空间的影响范围验证,并非整个平台隔离或所有用户业务零停机的证明。
还要区分离线 JWT 验证与在线检查。服务在本地验证签名和有效期,无法自动知道绑定的 API 对象当前是否仍存在。如果当前绑定状态很重要,需要 TokenReview 等在线验证。反之,本单元的声明解码并不是离线签名验证实现,不能报告成两种方式都已实现并比较。
不要混淆处于删除等待中的对象的宽限规则,与已经消失或 UID 改变对象的检查。本实验共同观察真实 UID 变化与 API 结果。只等待固定时间就判定成功,无法留下身份切换的证据。
下一项实验要做什么
先清空再恢复权限,准确地以同名重建原 SA,并签发新令牌。最后只撤销原绑定,区分旧令牌 401、新令牌 403、其他团队 200。每次观察记录时间、UID、认证结果和 HTTP 状态,分开解释过去成功的记录与当前状态。不要删除前一步文件来迁就记录;任务是说明何时发生了什么变化。