最快查 serviceaccount rbac 权限用 kubectl auth can-i --list -n ns --serviceaccount=sa,它调用 subjectaccessreview api 真实无缓存;go 中需正确设置 resourceattributes.namespace(集群资源留空,命名空间资源填对),并检查高危动词和 nonresourceurls。

怎么快速查清一个 ServiceAccount 有哪些 RBAC 权限
直接用 kubectl auth can-i --list 最快,但必须指定 --serviceaccount 和命名空间,否则查的是当前用户权限。它背后走的是 K8s 的 subjectaccessreview API,结果真实、无缓存。
常见错误是漏掉 --namespace,比如在 default 里查 monitoring/sa-foo 却不加 -n monitoring,结果返回空——不是没权限,而是查错了地方。
- 必须显式指定命名空间:
kubectl auth can-i --list -n monitoring --serviceaccount=sa-foo - 如果 SA 绑定了多个
RoleBinding或ClusterRoleBinding,can-i会自动聚合所有权限,不用手动拼 - 注意:它只反映当前生效的 RBAC 规则,不包含 PodSecurityPolicy(已废弃)、OPA/Gatekeeper 等外部策略控制
Go 里调用 SubjectAccessReview API 获取精确权限判定
想在 Go 程序里复现 kubectl auth can-i 的逻辑,核心就是构造并提交一个 SubjectAccessReview 对象。K8s 官方 client-go 提供了开箱即用的 builder,但容易忽略 ResourceAttributes 中 Namespace 字段的语义:对集群级资源(如 nodes)必须留空,对命名空间级资源(如 pods)必须填对——填错就永远返回 allowed: false。
示例中常把 Namespace 写死成 "default",结果审计 kube-system 下的 SA 时全报“拒绝”,其实是字段填错导致请求被当成跨命名空间越权检查。
立即学习“go语言免费学习笔记(深入)”;
- 用
authorizationv1.SubjectAccessReview类型,别用旧版v1beta1(1.19+ 已弃用) -
ResourceAttributes.Namespace:查secrets就填对应命名空间;查clusterroles就设为空字符串 - client-go 的
AuthorizationV1().SubjectAccessReviews().Create()返回对象里,只看.Status.Allowed,别依赖.Status.Reason——它可能为空或不准确
一键审计脚本该覆盖哪些典型风险操作
真正在生产环境出事的,往往不是“能不能读 pod”,而是“能不能删 secret”“能不能 bind clusterrole”“能不能 patch node”。所以审计不能只扫 get/list/watch,得重点标出高危动词。
RBAC 中最危险的不是 admin ClusterRole,而是看似普通却带 bind、escalate、impersonate 的细粒度权限。比如一个 SA 能 create rolebindings 在任意命名空间,等于能给自己提权。
- 必须检查的动词:
delete、deletecollection、bind、escalate、impersonate、patch(尤其对serviceaccounts或roles) - 必须检查的资源组:
rbac.authorization.k8s.io(rolebinding/clusterrolebinding)、certificates.k8s.io(certificatesigningrequests)、authentication.k8s.io(tokenreviews) - 别漏掉
nonResourceURLs,比如/api、/healthz—— 这些权限在can-i --list里不显示,但 Go 调用 SAR 时要单独构造NonResourceAttributes
权限聚合后为什么还缺一些实际能力
RBAC 只管“能否发起请求”,不管“请求是否成功”。比如 SA 有 patch nodes 权限,但 K8s 默认禁止 patch node.spec,真正起作用的是 kubelet 的 admission 控制或 NodeRestriction 准入插件。Go 审计脚本如果只查 SAR,就会误判为“可 patch node”,其实发出去必 403。
另一个盲区是 mutating webhook:SA 有 create pods 权限,但若 webhook 拒绝注入 sidecar,Pod 创建仍失败——这和 RBAC 无关,但运维排查时容易归因错误。
- 审计结果里要明确区分“RBAC 允许”和“K8s 实际允许”,后者需结合集群启用的准入控制器(如
NodeRestriction、PodSecurity)判断 - 对
customresourcedefinitions的权限,SAR 能查,但 CRD 自身定义的scope(Namespaced/Cluster)会影响Namespace字段是否必需,容易漏判 - ServiceAccount 的
automountServiceAccountToken: false会导致 token 不挂载,此时哪怕 RBAC 全开,容器内也拿不到 token——Go 脚本查 API 是 OK 的,但实际 Pod 用不了










