必须启用 level: requestresponse 才能捕获 secret 的实际内容读取行为,因为只有该级别会记录含解码后 data 字段的响应体;metadata 仅记元数据,request 不记录响应,均无法获取明文敏感信息。

必须启用 level: RequestResponse 才能捕获 Secret 的实际内容读取行为;仅用 Metadata 或 Request 级别会漏掉关键字段,比如 data 字段明文值。
为什么 Secret 的 get 操作必须用 RequestResponse 级别
Kubernetes 审计日志中,get 一个 Secret 的响应体(responseObject)才包含解码后的 data 字段(Base64 编码前的原始字节)。如果策略只设为 Metadata,日志里只有用户、时间、资源名和动词;设为 Request 则连响应都没有,根本看不到返回了什么。
常见错误现象:
— 日志里能看到 "verb":"get","resourceName":"my-secret",但查不到 "data":{...}
— 误以为已记录完整操作,实则敏感内容完全缺失
-
level: Metadata:仅记录请求元数据,不记录任何 body -
level: Request:记录请求 body(对get来说通常为空),不记录响应 -
level: RequestResponse:同时记录请求与响应 body —— 这是唯一能拿到 Secret 原始内容的方式
Policy 规则要精确匹配 group 和 resource,不能依赖通配
Secret 属于核心 API 组(group: ""),不是 apiextensions.k8s.io 或 rbac.authorization.k8s.io。写错 group 会导致规则完全不生效。
正确写法示例:
rules:
- level: RequestResponse
resources:
- group: ""
resources: ["secrets"]
verbs: ["get"]
容易踩的坑:
— 写成 group: "core" 或 group: "v1" → 不匹配,无审计事件
— 漏掉 verbs: ["get"],只写了 ["list"] → 单个 Secret 查看被忽略
— 把 resources: ["secrets"] 错写成 ["secret"](少 s)→ 不生效
避免审计日志爆炸:用 omitStages 过滤冗余阶段
RequestResponse 级别默认会为每个请求生成多个阶段(RequestReceived、ResponseComplete 等)的日志条目。对 Secret get 操作,真正需要的是 ResponseComplete 阶段那条含 responseObject 的记录。
建议在规则末尾加:
omitStages: - RequestReceived - ResponseStarted
这样可减少约 2/3 的重复日志量,同时确保关键响应体不丢失。不加的话,同一个 kubectl get secret my-secret -o yaml 可能产生 3 条日志,但只有其中一条含 data。
验证是否真捕获到 Secret 内容的最快方式
执行一次读取后,直接 grep 日志文件:
grep -A5 -B5 'my-secret.*"verb":"get"' /var/log/kubernetes/audit.log | grep -A10 '"responseObject"' | grep '"data"'
如果输出中出现类似 "data":{"password":"cGFzc3dvcmQxMjM="},说明配置成功;若只看到 "responseObject":null 或压根没 responseObject 字段,就是级别或规则没生效。
注意:RequestResponse 对性能有轻微影响,尤其高频读 Secret 场景;生产环境应限制为必要命名空间 + 必要 ServiceAccount,而不是全集群放开。











