В kube-аудите фронтенд-ServiceAccount перечисляет секреты по всему кластеру — найдите пробел в RBAC
Ревью аудита кластера подняло запись ниже. Фронтенд-сервис читает только один ConfigMap в своём namespace и больше ни для чего API Kubernetes не использует.
Ограничения:
- нагрузка фронтенда должна сохранить чтение того самого ConfigMap в namespace
web - в получившихся правилах не должно остаться wildcard ни в ресурсах, ни в глаголах
- исправление не должно опираться на добропорядочность самой нагрузки
[audit] stage=ResponseComplete verb=list resource=secrets scope=cluster-wide
user=system:serviceaccount:web:frontend-sa
sourceIP=10.42.7.19 (pod frontend-7d9c) decision=allow responseStatus=200
[rbac] ClusterRoleBinding frontend-sa-binding -> ClusterRole frontend-reader
rules apiGroups [""] resources ["*"] verbs ["get","list","watch"]
[pod] frontend-7d9c automountServiceAccountToken not set
Найдите и исправьте мисконфигурацию.
ClusterRoleBinding на роль с wildcard в ресурсах позволяет фронтенду из одного namespace читать любые секреты кластера. Замените её на Role в пределах namespace с явными ресурсами и глаголами, привяжите через RoleBinding и отключите automount токена.
- ✗Читать ClusterRoleBinding так, будто она ограничена одним namespace
- ✗Считать, что глаголы только на чтение делают широкую роль безобидной
- ✗Считать дефектом подробность аудита, а не саму выданную привилегию
- →Как найти в кластере все остальные привязки такой же формы?
- →Какое правило детекта добавить, чтобы этот шаблон в следующий раз алертил?
Причина не в аудите, а в самой привилегии. ClusterRoleBinding распространяет права роли на весь кластер, а resources ["*"] включает и secrets, поэтому фронтенд легитимно, с точки зрения RBAC, перечислил секреты всех namespace. Глаголы только на чтение здесь ничего не смягчают — чтение секрета и есть его утечка.
Исправление — свести привилегию к тому, что нагрузке реально нужно, и убрать лишний токен.
kind: Role
metadata:
namespace: web
name: frontend-config-reader
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["frontend-config"]
verbs: ["get", "watch"]
---
kind: RoleBinding
metadata:
namespace: web
name: frontend-sa-binding
subjects:
- kind: ServiceAccount
name: frontend-sa
roleRef:
kind: Role
name: frontend-config-reader
Старую ClusterRoleBinding и ClusterRole нужно удалить, а в спецификации пода выставить automountServiceAccountToken: false, если под в API не ходит. Отдельно стоит завести правило детекта на list secrets от рабочих ServiceAccount — такая запись должна быть алертом.