feat(dds): добавлен публичный контракт события
Зачем: - Показать слой DDS как договор данных, которому не нужна физическая копия. - Сохранить простой учебный стенд без отдельного маршрута ради узких прав. Что: - Добавлено кластерное представление dds.event_v с явными 44 колонками. - Роли bi_reader разрешено чтение ODS, DDS и DM при договоре чтения через _v. - Согласованы мастер-спека, ADR, справочники архитектуры и живые тикеты этапа. - Зафиксировано исследование поведения DEFINER поверх Distributed. Проверка: - make config-test - make smoke - make check-clickhouse - Приёмочные запросы: равенство ODS/DDS, состав колонок, коды устройств и права bi.
This commit is contained in:
1 parent
4ea9591a16
commit
9ea361d199
11 files changed
+288
-76
No files matched your search
@@ -1,11 +1,12 @@
|
||||
# ADR 0007. Доступ к ClickHouse: пользователи файлом, доверие нод секретом
|
||||
|
||||
Дата: 9 августа 2026 года. Статус: принято; роль `monitoring_reader`
|
||||
и пользователь `grafana` добавлены 21 августа 2026 года (#114).
|
||||
и пользователь `grafana` добавлены 21 августа 2026 года (#114), права
|
||||
`bi_reader` расширены до ODS, DDS и DM 25 августа 2026 года (#150).
|
||||
|
||||
## Решение
|
||||
|
||||
У кластера шесть пользователей и пять ролей.
|
||||
У кластера семь пользователей и шесть ролей.
|
||||
|
||||
- `default` — с паролем, только служебный: проверки здоровья нод и работа
|
||||
изнутри контейнеров. Приложения им не ходят.
|
||||
@@ -14,8 +15,9 @@
|
||||
- `lifecycle` с ролью `lifecycle_owner` — создание и удаление только
|
||||
прикладных баз и объектов. Им даги жизненного цикла применяют DDL и
|
||||
пересоздают мир ([ADR 0013](0013-world-lifecycle.md)).
|
||||
- `bi` с ролью `bi_reader` — чтение витрин DM, слоя DDS и справочников `dic`.
|
||||
Им ходит Superset.
|
||||
- `bi` с ролью `bi_reader` — чтение слоёв ODS, DDS и DM, а также справочников
|
||||
`dic`. Им ходит Superset; его запросы обращаются к публичным `_v`, хотя права
|
||||
шире.
|
||||
- `analyst` с ролью `analyst_reader` — чтение всех слоёв и справочников. Им
|
||||
человек подключается снаружи, из своего клиента.
|
||||
- `grafana` с ролью `monitoring_reader` — чтение слоёв, таблиц базы `dic` и
|
||||
@@ -41,24 +43,26 @@
|
||||
Сетевых ограничений на `default` нет: порты стенда и так открыты только на
|
||||
`127.0.0.1`, а внутри сети Compose дверь заперта паролем.
|
||||
|
||||
Устройство модели — кто каким пользователем ходит и где живут пароли —
|
||||
опишет раздел README «Состав и доступ»; здесь только решение и доводы.
|
||||
Отдельного справочника по доступу в `docs/architecture/` не заводим: своего
|
||||
содержания сверх этих двух документов у него сегодня нет, а дом ему
|
||||
понадобится, когда появятся слои DDS и DM и гранты размножатся. Абзац README
|
||||
«У локального учебного кластера нет пароля» этим решением отменяется.
|
||||
Раздел README «Состав и доступ» описывает, кто каким пользователем ходит и где
|
||||
живут пароли; здесь остаются решение и доводы. Отдельного справочника по
|
||||
доступу в `docs/architecture/` нет: точные права видны в `access.xml`, конвенция
|
||||
чтения через `_v` описана в доке хранилища.
|
||||
|
||||
## Почему
|
||||
|
||||
Стенд учит не администрированию доступа, а чтению отказа в правах: человек
|
||||
должен узнать в бою картину, которую видел здесь, и понимать, чего просить.
|
||||
Отсюда критерий отбора — модель должна читаться из текста ошибки, а не из
|
||||
описания. Поэтому пользователей мало, имена у них говорящие, а границы
|
||||
проходят там, где их обычно проводят в компаниях: `bi` видит витрины и слой
|
||||
DDS под ними, потому что так чаще всего и бывает; заодно расхождение витрины
|
||||
со слоем ниже остаётся проверяемым одним и тем же пользователем. Справочники
|
||||
видны всем читателям и никому на запись: зона входит в хранилище сбоку, и её
|
||||
содержимым владеет файл репозитория, а не слой.
|
||||
описания. Поэтому пользователей мало, имена у них говорящие, а `bi` отделён от
|
||||
STG и от записи. Один пользователь может сверить всю цепочку DM → DDS → ODS,
|
||||
не получая доступа к сырью и изменению данных. Справочники видны всем читателям
|
||||
и никому на запись: зона входит в хранилище сбоку, и её содержимым владеет файл
|
||||
репозитория, а не слой.
|
||||
|
||||
Ограничить `bi` одними `_v` поверх `Distributed` можно только отдельным
|
||||
маршрутом, учётной записью или копией данных. Эта механика не даёт нового урока.
|
||||
Публичное представление остаётся договором чтения; границу прав оно не задаёт
|
||||
([исследование](../research/2026-08-25-clickhouse-distributed-view-security.md)).
|
||||
|
||||
**Беспарольный `dict`.** Пароль пришлось бы вписать в текст DDL словаря, то
|
||||
есть положить секрет в git. Ходить этой учёткой некуда: право у неё одно —
|
||||
@@ -124,11 +128,9 @@ DDS под ними, потому что так чаще всего и быва
|
||||
|
||||
## Следствия
|
||||
|
||||
До появления слоёв DDS и DM читать `bi` почти нечего, и это намеренно.
|
||||
Дашборды рисуются поверх модели данных, а не поверх типизированных событий,
|
||||
поэтому доступ Superset к ODS не планировался и правами не выдаётся.
|
||||
Единственное, что ему доступно сегодня, — справочники: с ними зона `dic`
|
||||
пришла раньше своих потребителей.
|
||||
Новые таблицы ODS, DDS и DM не требуют отдельного гранта для `bi_reader`.
|
||||
Явный договор `_v` защищает потребителя от устройства хранения и случайных
|
||||
новых колонок.
|
||||
|
||||
DDL для матвью приёма выполняется от имени `lifecycle`. Это видно в журнале
|
||||
запросов, а при создании ClickHouse проверяет у этой учётки чтение источника и
|
||||
@@ -194,3 +196,12 @@ ClickHouse через MCP Context7 (#114).
|
||||
- Права на отсутствующие базы `dds` и `dm` приняты. До создания баз они видны
|
||||
в `SHOW GRANTS FOR etl_writer`; временная таблица в `dm` подтвердила право
|
||||
`bi` на чтение после появления базы.
|
||||
|
||||
Расширение `bi_reader` проверено на живом стенде 25 августа 2026 года (#150):
|
||||
|
||||
- `SHOW GRANTS FOR bi_reader` содержит `SELECT` на ODS, DDS и DM;
|
||||
- `bi` прочитал одинаковые 401185 строк из `ods.event_v` и `dds.event_v`;
|
||||
- чтение `stg.hits_raw_rep` завершилось ошибкой `ACCESS_DENIED`;
|
||||
- представление над `Distributed` с `SQL SECURITY DEFINER` на удалённой ноде
|
||||
сохранило исходного пользователя `bi`. Причина и отклонённые варианты
|
||||
разобраны в [исследовании](../research/2026-08-25-clickhouse-distributed-view-security.md).
|
||||
Reference in new issue
Block a user