Аудитория: суперадминистратор, ИБ-служба. Закрывает вопрос: №8 («кто и что может менять, как выдать доступ?»). Сценарий: S8 — выдать доступ новому инженеру / понять, кто что видит.
В продукте 5 пользовательских ролей и одна служебная (collector, без интерфейса). Доступ к разделам определяется единой картой ROUTE_ROLES — она же управляет и видимостью пунктов в меню, и проверкой на бэкенде (require_role). Публичный демо-арендатор доступен только на чтение. Вход — по логину вида роль@арендатор и паролю; пароли хешируются Argon2id (не Стрибог, см. статью 01).
| Роль | Кто это | Назначение |
|---|---|---|
viewer | Наблюдатель | Только чтение общедоступных разделов (дашборд, системы, эффективность, риски, каталог…) |
it_manager | ИТ-менеджер | + работа с заявками на ПО (создание заявки) |
it_admin | ИТ-администратор | + «железо», ЖЦ, провижининг, коллекторы (эксплуатация ИТ) |
dpo | Ответственный за ПДн | + аудит ФЗ-152 и Identity Vault (раскрытие соответствий) |
superadmin | Суперадминистратор | Полный доступ, включая /settings |
collector | Агент сбора телеметрии | Служебная, без UI — только приём телеметрии по сети |
Карта ROUTE_ROLES: маршруты, которых нет в карте, доступны всем ролям (дашборд, /systems, /efficiency, /risks, /catalog, /requests, /finops и т.п.). Ограниченные:
| Раздел | Кто видит |
|---|---|
/hardware | it_admin, superadmin |
/lifecycle | it_admin, superadmin |
/provisioning | it_admin, superadmin |
/collectors | it_admin, superadmin |
/audit | dpo, superadmin |
/identity (Vault) | dpo, superadmin |
/settings | superadmin |
Принцип: canAccess(route, role) — нет ограничения → доступно; есть → роль должна быть в списке. Меню и проверка доступа используют одну и ту же карту — пункт не показывается, и прямой заход на URL тоже отдаёт «доступ запрещён» (403). То есть скрытие в меню — не косметика.
RBAC распространяется и на действия (require_role/require_auth на бэкенде):
| Действие | Кто может |
|---|---|
Создать заявку на ПО (POST /requests) | it_manager, it_admin |
Перевести заявку по статусам (/transition) | требует аутентификации (require_auth) |
| Grace-sweep (отзыв по простою) | it_admin |
Приём телеметрии (/ingest/activity) | collector, it_admin |
Раскрыть соответствие в Vault (/vault/resolve) | dpo (+ обязательное основание) |
Любая запись в demo_public | запрещена всем (read-only) |
Роль определяет что можно делать; арендатор определяет над какими данными. Изоляция встроена в СУБД через Row-Level Security (RLS FORCE) с первой миграции, а роль приложения licenziar_app — не суперпользователь, поэтому RLS реально применяется. Даже superadmin одного арендатора не видит данные другого: SELECT * FROM sam.systems под контекстом demo отдаёт только demo (доказано тестом приёмки). При логине арендатор берётся из учётной записи (роль@арендатор) → запрос в чужой арендатор при входе отвергается (401).
На стенде операторы засеяны автоматически для каждого customer-арендатора в виде роль@арендатор с паролем licenziar. Примеры:
it_admin@artek / licenziar # ИТ-админ Артека
dpo@artek / licenziar # ответственный за ПДн Артека
superadmin@rggu / licenziar # суперадмин РГГУ- Выбор роли = выбор объёма доступа. Инженеру эксплуатации —
it_admin; тому, кто работает
с ПДн, — dpo; руководителю для просмотра — viewer/it_manager; полный доступ — только superadmin (минимизируйте число суперадминов).
- Учётные записи операторов живут в
sam.app_users(под RLS, заводятся при сиде/онбординге).
Листинг пользователей в UI сознательно не выносится; матрицу «роли × разделы» можно посмотреть на /settings → вкладка «Пользователи и роли».
- Заведение нового арендатора целиком — отдельная процедура онбординга (вне этой статьи).
- Прод: JWT в httpOnly-cookie same-origin через nginx + CSRF (double-submit). Токен
недоступен из JS — устойчивее для гос-контекста. Включается AUTH_COOKIE_MODE=1.
- Dev-стенд: фолбэк на localStorage (
AUTH_MODE=token) — удобнее для отладки. - Это решение зафиксировано осознанно (оценка 10×10: cookie 72 vs localStorage 62 для
гос-контекста). Переключение — переменными окружения, без правок кода экранов.
- Скрытый пункт меню ≠ защищённый ресурс только на фронте. Защита дублируется на бэкенде
(require_role); не полагайтесь на то, что «раздел не виден» — он ещё и закрыт по API.
- `superadmin` не всемогущ между арендаторами. RLS изолирует данные по арендатору всегда;
это не настройка, а инвариант СУБД.
- `collector` — не для людей. Это служебная роль приёма телеметрии; не выдавайте её
сотрудникам и не ждите для неё интерфейса.
- demo_public — витрина. Любая попытка записи туда — 403 by design; для реальной работы
используйте customer-арендатора.
Связанные статьи: 02 — ПДн и Vault · 05 — Автономность и стек.