Оператор согласования прав (permissions operator)
Компонент развёртывается как stp-controller в составе Helm chart shturval-backend. Отдельного Helm chart только для оператора прав нет: вместе с ним в chart входят backend API, Envoy, OPA и Swagger UI.
Содержание
- Обзор
- Архитектура
- Установка / развёртывание
- Диагностика
- Жизненный цикл
- Параметры оператора
- Справочник CRD/API
1. Обзор
Назначение: оператор согласует объекты Permission, Scope, UserRole, GroupRole, Tenant с фактическими правами: агрегирующие и клиентские ClusterRole, привязки субъектов через плагины (RBAC, Argo CD, Kubeflow, tenant), дочерние области для тенантов и in-memory модель для политик. HTTP endpoint /bundle (типовой порт 8082) отдаёт данные для OPA; при включённых webhook выполняется валидация UserRole, GroupRole, Tenant.
Функции
| Контур | Назначение в эксплуатации |
|---|---|
Области (Scope) |
Вычисление путей, аннотаций кластеров, списка имён Permission, статусов привязанных объектов |
Кастомные роли (Permission) |
Агрегирующий ClusterRole на платформе и ClusterRole в клиентских кластерах по granted_cluster_rules (через kubeconfig из Secret на платформе) |
Привязки (UserRole, GroupRole) |
Плагины применяют права субъекта в области; идемпотентность отражается в статусах плагинов |
Тенант (Tenant) |
Создание/обновление дочернего Scope, платформенные Role для прав tenant-get / tenant-edit |
| Admission | Валидация UserRole, GroupRole, Tenant при включённых webhook |
| Bundle HTTP | Выдача revision OPA-bundle; периодическая пересборка по интервалу (по умолчанию 60 с) |
Сценарии инициации
| Что происходит | Кто инициирует | Наблюдаемый эффект |
|---|---|---|
| Согласование CR | Плоскость управления Kubernetes (события CR, relist, watch) | Обновление связанных ClusterRole, статусов, аннотаций, модели для bundle |
| Валидация привязок | API-сервер при Update UserRole / GroupRole |
Отклонение недопустимых изменений ключевых полей spec |
| Валидация тенанта | API-сервер при Create/Update Tenant по пути webhook |
Отклонение недопустимых изменений |
| Пересборка bundle | Таймер и запросы потребителей к HTTP /bundle |
Актуальная revision в ответе |
| Реакция на кластеры | События CAPI Cluster (готовность control plane, удаление, пауза) |
Повторное согласование затронутых Permission, Scope, ролей |
Ограничения и следствия
| Ограничение | Следствие для администратора |
|---|---|
После создания UserRole нельзя менять spec.username |
Изменение блокируется validating webhook при Update |
Удаление Permission при привязанных UserRole / GroupRole |
Финалайзер не снимается до освобождения; повторная попытка с интервалом около 1 минуты |
Удаление Tenant при наличии дочерних tenants |
Согласование удаления завершается ошибкой до устранения иерархии |
Поле open_search_roles в Permission |
Помечено устаревшим (deprecated) в CRD; новые конфигурации лучше не опираться на него |
Место в цепочке управления
Цепочка на высоком уровне: объекты Tenant порождают/обновляют связанный Scope; согласование Scope обновляет модель хранения и статусы (в т.ч. аннотации кластеров); UserRole / GroupRole требуют существования соответствующего Scope и выставляют ссылку владельца; Permission обновляет платформенные и клиентские ClusterRole, изменения Permission через watch влияют на дальнейшее согласование Scope.
Цепочка управления: CR, оператор, клиентские кластеры и bundle

Пользователь или CI применяет CR через Kubernetes API. API-сервер сохраняет объекты Tenant, Scope, Permission, UserRole и GroupRole, после чего permissions operator читает их, выполняет согласование и обращается к внешним контурам: плагинам RBAC, Argo CD, Kubeflow, клиентским кластерам и объектам CAPI Cluster.
Ключевые характеристики
| Характеристика | Значение |
|---|---|
| API group | permissions.shturval.tech, версия v1beta1 |
| Scope CRD | Namespaced |
| kubectl shortNames | В сгенерированных CRD для перечисленных видов не заданы |
| Namespace типовой установки (Kustomize для разработки) | stp-system, префикс ресурсов stp- |
Namespace процесса при установке chart в shturval-backend |
Совпадает с namespace Helm-релиза; в контейнер пробрасываются namespace и serviceAccountName из полей Pod |
Значение namespace для StorageEngine по умолчанию в бинаре |
shturval-backend (переопределяется переменной окружения) |
| Leader election ID | permissions.shturval.tech |
| Метрики | Параметры задаются патчами развёртывания и флагами процесса (см. §6) |
| Webhook | Порт 9443; отключение через ENABLE_WEBHOOKS=false |
| HTTP/2 | По умолчанию отключён для TLS-серверов метрик и webhook |
| Bundle | Адрес привязки по умолчанию :8082, путь /bundle |
Компоненты и контроллеры
| Имя / роль | Назначение |
|---|---|
| CRD | permissions, scopes, userroles, grouproles, tenants (cluster-wide определения) |
| Deployment менеджера | Один Pod с контейнером manager |
| RBAC | ClusterRole / привязки для доступа менеджера к API |
PermissionReconciler |
Синхронизация Permission с ClusterRole, финалайзер, watch Cluster |
ScopeReconciler |
Модель области, статусы, аннотации; периодические requeue для уровней cluster/namespace |
UserRoleReconciler / GroupRoleReconciler |
Плагины прав в области |
TenantReconciler |
Scope и роли тенанта; ограничения на удаление |
2. Архитектура
Компоненты рабочей нагрузки
| Компонент | Kind | Scope | Описание |
|---|---|---|---|
| CRD | CustomResourceDefinition | Cluster | Ресурсы API группы permissions.shturval.tech |
| Менеджер | Deployment | Namespaced | Один Pod с контейнером manager |
| RBAC | ClusterRole, RoleBinding и др. | По манифестам | Доступ оператора к нужным ресурсам API |
Архитектура runtime: Deployment менеджера, RBAC, webhook, bundle

Схема показывает состав процесса менеджера внутри Pod: контроллеры ресурсов, HTTP endpoint bundle на порту 8082, метрики через kube-rbac-proxy, readiness-пробу на 8081 и admission webhook для UserRole, GroupRole и Tenant. Менеджер работает с Kubernetes API, CRD группы permissions.shturval.tech, сервисным аккаунтом, CAPI-кластерами и потребителями OPA bundle.
Граф связей CR и движка хранения прав

Диаграмма описывает, как CR связаны между собой и с in-memory StorageEngine. Tenant владеет связанным Scope и создаёт роли tenant-get / tenant-edit; UserRole и GroupRole ссылаются на Scope и имена Permission; Permission наполняет модель прав и порождает ClusterRole на платформе и в клиентских кластерах.
Связь с внешними объектами
| Объект / система | Роль |
|---|---|
CAPI Cluster |
Определение клиентских кластеров и событий готовности / удаления |
| Secret kubeconfig | Имя <имя-кластера>-kubeconfig, ключ value — ожидаемый формат для доступа к API клиентских кластеров |
| Потребители OPA | HTTP GET (и связанная логика ожидания обновления bundle) к /bundle |
| Плагины интеграций | Argo CD, Kubeflow, RBAC Kubernetes, tenant — по типу прав в spec |
RBAC детализируется манифестами поставки; перечень точных правил в данном документе не дублируется.
3. Установка / развёртывание
Платформа и Helm
Компонент входит в chart shturval-backend: Deployment stp-controller, сервис для bundle и связанные объекты задаются шаблонами chart. Отдельного Helm chart только для permissions-operator нет — используется общий chart backend.
Типовая установка на management-кластер выполняется через cluster-manager: создаются и обновляются объекты ShturvalServiceConfig (SSC) с указанием имени чарта shturval-backend, namespace shturval-backend, зависимостей от shturval-backend-crds и shturval-ingress-controller, версии chart из параметров релиза платформы и пользовательских values.
Локальная установка CRD/RBAC через Kustomize для разработки использует namespace stp-system; в эксплуатации через платформу типичен namespace релиза shturval-backend — это должно согласовываться с переменной окружения namespace процесса.
Зависимости для клиентских правил
Для Permission с granted_cluster_rules (политики в клиентских кластерах) на платформе должны существовать Secret’ы kubeconfig по соглашению имени и ключа (см. §2). Отдельные SSH-ключи к узлам в описанной цепочке getter не используются.
Настройка через SSP
Любые изменения Helm values.yaml для компонента оператора в продакшене должны подаваться через ShturvalServicePatch (SSP) поверх соответствующего SSC, без прямого редактирования релиза в обход платформенных практик.
При необходимости тонкой настройки аргументов контейнера и ресурсов сверяйте фактический chart и документацию релиза платформы для используемой версии.
4. Диагностика
Типовые проверки (namespace подставьте фактический для релиза, обычно shturval-backend):
- состояние Pod’ов Deployment
stp-controller; - события Pod’ов и логи контейнера
managerпри ошибках согласования или webhook; - доступность пробы здоровья на адресе, заданном аргументами (типово
:8081); - для политик OPA — доступность сервиса bundle (порт 8082 в типовой конфигурации флагов).
Готовность и статусы (Ready, плагины)
| Ресурс | Поле / конструкция | Интерпретация |
|---|---|---|
Permission |
status.ready |
Сводный статус применения правил |
Scope |
status.ready, status.objectsStatus |
Готовность области и состояние объектов |
UserRole, GroupRole |
status (RoleStatus) |
Карта permissions → кластеры/платформа → плагины → PluginObject |
Tenant |
status.condition |
См. таблицу условий ниже |
Статусы плагинов (PluginApplyStatus)
| Значение | Смысл для эксплуатации |
|---|---|
applied |
Плагин успешно применён |
not applied |
Ещё не применён |
not required |
Не требуется (например, при удалении) |
undefined |
Сетевая или иная ошибка; записи могут очищаться при успешном проходе |
Условия Tenant (status.condition)
| Condition | True | False / причины |
|---|---|---|
TenantSynced |
— | Ошибка создания/patch Scope, получения Scope (CreateOrPatchTenantFailed, GetScopeFailed) |
TenantCreated |
Тенант и scope синхронизированы (Created) |
— |
TenantRoleCreated |
— | Ошибка создания Role tenant-get / tenant-edit |
TenantDeleted |
— | Дочерние tenants или ошибка удаления Scope/Role/родительского scope |
Типичные симптомы
| Симптом | Возможная причина | Действие |
|---|---|---|
Permission «завис» в удалении |
Существуют UserRole/GroupRole, ссылающиеся на имя permission |
Удалить или изменить привязки; ожидать повторного согласования (~1 мин) |
| Нет прав в клиентском кластере | Нет/битый kubeconfig Secret, пауза/удаление CAPI Cluster |
Проверить Secret <cluster>-kubeconfig, ключ value, состояние Cluster |
| Webhook не отвечает | Нет сертификатов / неправильная конфигурация при ENABLE_WEBHOOKS включён |
Проверить TLS и конфигурацию webhook; при аварийной диагностике — режим отключения webhook (см. §6) |
| Долгое обновление scope уровня cluster/namespace | Задланные интервалы повторного входа в reconcile | Учитывать периодичность (до ~30 мин для cluster, ~5 мин для namespace в описанной логике) |
Ошибка удаления Tenant |
Дочерние tenants | Сначала удалить/перенести дочерние объекты |
5. Жизненный цикл
Общая схема взаимодействия контуров:
| Шаг | Актор | Действие |
|---|---|---|
| 1 | Согласование Tenant |
Создаётся или обновляется Scope с тем же именем, owner reference на Tenant |
| 2 | Согласование Scope |
Обновляется модель хранения и статусы; аннотации кластеров |
| 3 | Согласование UserRole / GroupRole |
Требуется существующий Scope; выставляется controller reference |
| 4 | Согласование Permission |
Обновляются кластерные роли; изменения Permission инициируют дальнейшее согласование Scope через watch |
Упрощённый сквозной контур: API Kubernetes и согласование ресурсов

Схема показывает типовую последовательность: пользователь или CI применяет Scope, Permission и UserRole; API-сервер запускает соответствующие reconcile-проходы. ScopeReconciler обновляет статус и аннотации, PermissionReconciler создаёт или обновляет ClusterRole, а UserRoleReconciler читает Scope, выставляет owner reference, применяет плагины интеграций и обновляет статус роли.
Permission
- Финалайзер:
permissions.shturval.tech/finalizer. - Создание / обновление: очистка
status.applied_to_clusters, запись в модель; при платформенных правилах — обновление агрегирующегоClusterRole; при клиентских — выборка кластеров и обновлениеClusterRoleв каждом; выставлениеReadyпри успехе. - Удаление: если есть привязки ролей к данному permission — перенос повторной попытки примерно через минуту; иначе удаление платформенных и клиентских
ClusterRole, снятие финалайзера. - События CAPI: при готовности control plane или удалении кластера — повторное согласование затронутых
Permission(с фильтром по применённым кластерам).
Scope
- Удаление: если в модели ещё есть пользователи/группы для имени scope — повтор через ~5 с; иначе удаление из модели и снятие финалайзера.
- Обновление: пересчёт кластеров, аннотации, статусы namespace; для уровня namespace — проверки существования namespace в целевых кластерах; периодические повторы для уровней cluster (до ~30 мин) и namespace (~5 мин) при необходимости.
UserRole и GroupRole
- Удаление: сброс статусов плагинов, вызов удаления у всех плагинов, расчёт готовности, снятие финалайзера и удаление из модели.
- Обновление: финалайзер, привязка к
Scope, обновление модели, последовательное применение плагинов; при ошибках — немедленный requeue; при успехе — очистка «неопределённых» статусов плагинов. - Наблюдение: изменения связанного
Scope; дляUserRole— также изменениеCluster.Spec.Paused.
Tenant
- Создание / обновление: при первом добавлении финалайзера — немедленный повтор входа; генерация и применение
Scope, создание ролейtenant-get/tenant-edit, регистрация в модели, условиеTenantCreated. - Удаление: проверка отсутствия дочерних tenants; удаление
Scope; покаScopeсуществует — повтор через ~5 с; затем удаление ролей и записей в модели, очистка родительского scope, снятие финалайзера.
Префиксы имён создаваемых ClusterRole: shturval: для пользовательских ролей, platform: для платформенных.
Диаграммы переходов при согласовании
Ниже — схемы, ориентированные на понимание состояний объекта в кластере: готовность, удаление и финалайзеры.
Согласование Permission: создание/обновление ClusterRole, удаление

Если объект Permission отсутствует, reconcile завершается пустым результатом. Для существующего объекта оператор разделяет путь удаления и путь обновления: при удалении ждёт, пока UserRole и GroupRole перестанут ссылаться на permission, затем удаляет платформенные и клиентские ClusterRole, запись из движка и финалайзер; при обновлении добавляет финалайзер, обновляет модель, синхронизирует нужные ClusterRole и выставляет успешную готовность.
Согласование UserRole: привязка к Scope, плагины, готовность

При обновлении UserRole оператор добавляет финалайзер, получает Scope, устанавливает controller reference, обновляет запись в движке и применяет права через плагины. Затем пересчитывается готовность: при незавершённом применении объект ставится в повторную обработку, а при успехе очищаются неопределённые результаты и reconcile завершается без повторного запуска; при удалении плагины вызываются на очистку, пересчитывается готовность удаления и снимается финалайзер.
Согласование GroupRole: симметрично UserRole

Поток для GroupRole повторяет логику UserRole, но субъектом является claim группы. Оператор добавляет финалайзер, читает связанный Scope, выставляет owner reference, обновляет модель и применяет разрешения через плагины; при удалении удаляет плагиновые права, проверяет готовность очистки и только после этого снимает финалайзер.
Согласование Scope: кластеры, namespace, повторные попытки

Для активного Scope оператор добавляет финалайзер, фильтрует кластеры по идентификаторам и аннотациям, обновляет пути в StorageEngine, записывает в статус permissions, paths и objectsStatus, после чего выставляет готовность. Если scope уровня platform или cluster/namespace требует повторной проверки, reconcile планируется повторно с интервалами для cluster и namespace; при удалении оператор ждёт, пока в движке не останется пользователей или групп, затем удаляет scope из модели и снимает финалайзер.
Согласование Tenant: дочерний Scope, роли tenant-get / tenant-edit

При создании или обновлении Tenant оператор добавляет финалайзер, генерирует и применяет связанный Scope, создаёт роли tenant-get и tenant-edit, добавляет tenant в движок и выставляет условие TenantCreated=True. При удалении сначала проверяется отсутствие дочерних tenants; затем оператор удаляет Scope, ждёт его исчезновения, удаляет роли, удаляет tenant из модели, очищает ссылку в родительском scope и снимает финалайзер.
6. Параметры оператора
Аргументы процесса задаются флагами в точке входа. В поставке они передаются через шаблон Deployment chart и SSP; администратор может переопределять их только через согласованные с платформой механизмы, без импровизации имён:
| Флаг | По умолчанию | Назначение |
|---|---|---|
--metrics-bind-address |
0 (отключено в коде; в патче может быть 127.0.0.1:8080) |
Адрес метрик |
--health-probe-bind-address |
:8081 |
Проба здоровья |
--leader-elect |
false |
Лидер-выборы (в типовом деплое включается аргументами) |
--metrics-secure |
true |
TLS для метрик |
--enable-http2 |
false |
HTTP/2 |
--bundle-bind-address |
:8082 |
Прослушивание bundle |
--bundle-path |
/bundle |
HTTP-путь bundle |
--bundle-rebuild-duration |
60 (секунды) |
Период пересборки bundle |
--max-reconciles |
5 |
Параллельность согласований |
--webhook-port |
9443 |
Порт webhook |
--webhook-cert-dir |
/tmp/k8s-webhook-server/serving-certs/ |
Каталог сертификатов webhook |
Опции логгера zap также пробрасываются через стандартный механизм флагов.
Переменные окружения
| Переменная | Назначение |
|---|---|
ENABLE_WEBHOOKS |
При значении false отключается регистрация webhook (полезно для отладки без согласованных сертификатов) |
namespace |
Namespace области хранения модели (override значения по умолчанию shturval-backend) |
serviceAccountName |
Учётная запись для tenant webhook (по умолчанию stp-tenant-webhook) |
oidcClientRef |
Ссылка на auth client (по умолчанию shturval-backend/backend) |
DEBUG |
При true — режим логов разработки |
Обратите внимание! при ENABLE_WEBHOOKS=false валидация на admission для перечисленных типов не выполняется на стороне оператора; использование только в контролируемых сценариях диагностики.
7. Справочник CRD/API
Общие сведения: group permissions.shturval.tech, version v1beta1, scope всех CR — Namespaced.
Permission
spec
| Путь | Тип | Обязательно | Описание |
|---|---|---|---|
scope_level |
string (ScopeLevel) |
Да | Уровень области для определения Permission |
granted_cluster_rules |
[]PolicyRule |
Нет | Правила RBAC для ClusterRole в клиентских кластерах |
granted_platform_permissions |
[]string |
Нет | Имена платформенных разрешений для агрегирующего ClusterRole |
argo_cd_roles |
[]string |
Нет | Роль Argo CD |
kubeflow_roles |
[]string |
Нет | Роль для доступа в Kubeflow |
open_search_roles |
[]string |
Нет | Устарело (deprecated) |
status
| Путь | Тип | Описание |
|---|---|---|
applied_to_clusters |
[]string |
Кластеры, где выставлен клиентский ClusterRole |
ready |
Ready |
Сводный статус (ready, status, reason, message) |
Отдельных условий типа metav1.Condition нет — только поле ready.
Scope
spec
| Путь | Обязательно | Описание |
|---|---|---|
spec.objects |
Да | Карта уровней → имена (ScopeObjects): platform, clustergroups, clusters, namespaces, tenants, custom |
status
| Путь | Описание |
|---|---|
paths |
Пути scope |
permissions |
Имена Permission, доступные на уровне scope |
ready |
Ready |
objectsStatus |
Состояние кластеров и namespace |
UserRole
spec
| Путь | Обязательно |
|---|---|
spec.scope |
Да |
status: RoleStatus — ready, вложенная карта permissions → кластеры/платформа → плагины → PluginObject.
GroupRole
spec
| Путь | Обязательно |
|---|---|
spec.scope |
Да |
status: как у UserRole.
Tenant
spec
| Путь | Описание |
|---|---|
spec.objects |
ScopeObjects границ тенанта |
spec.parentRef |
Родительский tenant (name, namespace) |
spec.immutable |
Запрет изменений spec |
status
| Путь | Описание |
|---|---|
objectsStatus |
Копия из связанного Scope при успешном согласовании |
condition |
Одна metav1.Condition (см. §4) |