TT Lab
开始
学习 学习路径 课程

CNPE — 云原生平台工程师

审计追踪成立的条件

在 TT Lab 中继续学习

一句话总结

审计追踪需要所运行内容的标识符、可信的生产证据,以及按时间点划分的部署记录。并不是保存的机密值越多,证据就越好。

为什么仅靠一个标签是不够的

标签可以移动到另一个镜像上,而 digest 是内容的标识符。因此,最好用 digest 固定期望的部署,并把它与扫描和签名的对象关联起来。digest 本身并不能证明安全性、作者或源码提交。Kubernetes 镜像

用标签部署,并不意味着完全无法调查当前的镜像。status.containerStatuses[].imageID 中有运行时所识别的镜像信息,它可能与声明的镜像不同。格式和 digest 的含义,要根据运行时和镜像的种类来确认。当前的查询无法还原已经被删除的 Pod 的过去状态,所以还要保存部署当时的标识符和时刻。Kubernetes ContainerStatus 源码

工作原理

把四种证据连接起来

证据 要确认的内容 单独无法证明的内容
镜像 digest 验证对象与部署对象的一致性 没有漏洞、源码提交
镜像签名 符合信任策略的签名者的签名 该签名者确实是实际的构建者
SBOM 组件清单及其与对象的关联 清单的完整性、作者的可信度
构建 provenance 对象、构建者、输入和构建过程 不受信任的构建者的诚实性

镜像签名与 SBOM 签名是两回事。即使镜像签名有效,放在旁边的任意 SBOM 文件也并不因此就得到了认证。例如,对于装有 SBOM 的 attestation,不仅要验证签名,还要确认 subject 的 digest 是否与对象相同,以及 predicateType 是否是期望的类型。构建 provenance 也必须验证受信任的构建者,以及预期的源码和构建条件。SLSA 制品验证

Sigstore 的 cosign verify 和 cosign verify-attestation 验证的对象不同。在无密钥验证中,要具体限制所允许的证书身份和 OIDC 签发者。从密码学上签名是对的,与是我们的发布主体进行了签名,是不同的判断。Sigstore 验证指南

扫描报告要把对象 digest、扫描器和漏洞库的版本、检查时刻以及例外绑定在一起。仅仅报告生成成功,并不能成为部署关卡。要区分违反标准和检查器出错,并确认两者是否都会恰当地阻止部署。发现新漏洞时,同一个镜像也必须重新评估,所以不能把构建当时的通过当作永久安全的判定。

不要把 Secret 正文复制到审计日志中

Metadata 会留下用户、时刻、资源、动作等记录,但不会留下请求和响应的正文。Request 包含请求正文,RequestResponse 包含双方的正文。如果以详细级别记录 Secret,敏感内容就可能被复制到日志中。Kubernetes 审计级别

Secret 的 base64 不是加密,所以编码后的值也是暴露。即使收紧了 Secret 的查询权限,只要日志的读者能看到正文,就会通过其他路径泄露。也应避免把机密直接放进 ConfigMap 或 Pod 规格中。Secret 管理原则

下面是不留下正文的起点示例。它不是要用 kubectl apply 应用的工作负载,而是 API 服务器的审计策略文件。实际启用时,需要配置策略文件以及日志和 Webhook 的存储路径,托管服务则要确认提供商的设置。不要原样替换生产配置。

apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  - level: Metadata
    resources:
      - group: ""
        resources: ["secrets", "configmaps"]
  - level: Metadata

一开始把所有请求都按 Metadata 记录。即使之后添加详细规则,也不要把范围广泛的正文记录规则放在敏感资源保护规则之前。第一个匹配的规则会被应用,所以无法用后面的保护规则覆盖前面的决定。子资源以及其他 API 组中的敏感数据,也要另行审查。审计策略 API 契约

Metadata 也不是公开日志。不要把敏感信息放进请求 URI 或审计注解等处,并要管理日志的查看和导出权限、保留期限、完整性以及采集失败告警。省略正文,并不能保证自动清除整个日志中的机密。

在现场相遇的样子

示例场景:调查负责人不需要机密值,但必须知道是谁读取了生产 Secret。在自己拥有的隔离环境中,用不是真实凭据的合成标记来发出创建、查询、删除请求,并确认相应请求的用户、动作、对象和响应结果是否被留下。同时还要检查是否有 requestObject 和 responseObject,以及合成标记的原文和编码值。如果记录是空的,就只会通过第二个条件,所以必须先确认请求证据是否存在。

采集路径是否正常,也是另一个条件。如果 API 服务器的本地文件中有,而中心存储中没有,就无法通过中心搜索来调查事故。把已知的测试请求一直查找到底,比采集器界面上的绿灯更是直接的证据。

下一项测验要确认什么

判断策略范围的遗漏、NetworkPolicy 与 mTLS 的区别、Secret 的审计级别、digest 与 provenance,以及 SBOM 的关联。

实际确认的范围

2026-09-11,在隔离的 k3s v1.36.4+k3s1 探针上,执行了合成 Secret 的创建、查询、删除,以及未被允许的用户的查询。在 Metadata 下,只留下了四个请求的证据;把详细规则放在前面时,合成正文被暴露了;修改之后,正文又消失了。把 Secret 的记录用 None 关闭时,另外的 /version 对照请求被记录下来,但没有 Secret 的证据,导致验证器失败。

复现和反例检查保存在仓库的 scripts/probe_cnpe_audit.py 和 tests/test_cnpe_audit_probe.py 中。这次确认仅限于单节点的本地审计文件。这并不意味着已经验证或更改了中心采集、日志完整性、所有敏感资源的策略,或者生产集群的审计配置。接下来将在个人 VM 上进行 8 个步骤的实验,亲自复现机密暴露、Metadata 恢复和 None 证据缺失。同时确认采集时刻的摘录与当前 API 的新查询,而这份资料并不能保证中心审计存储的完整性。