Добавлены пользователи etl, bi, analyst и роли etl_writer, bi_reader, analyst_reader в файловой конфигурации ClickHouse.
Межнодовые запросы переведены на общий секрет кластера; учётные данные из описания реплик убраны.
Airflow переключён на etl, Superset — на bi; служебному default задан пароль.
README, мастер-спека и ADR 0007 приведены к фактическому устройству стенда и результатам замеров.
Ручная проверка границ
Проверка
Результат
bi читает stg.hits_raw_dist и ods.event_dist
ACCESS_DENIED, код 497; ошибка называет пользователя и объект
analyst читает те же таблицы
Успешно, 401185 строк
analyst пишет в ods.event_rep
ACCESS_DENIED
etl читает stg и ods, пишет в stg
Успешно
etl выполняет CREATE DATABASE, CREATE TABLE и DROP ON CLUSTER
Успешно
default подключается по HTTP без пароля
Ошибка аутентификации
analyst подключается по HTTP с паролем
Успешно
При распределённом запросе от analyst на второй ноде измерено user = analyst, initial_user = analyst, is_initial_query = 0: соседний шард применяет права пользователя-инициатора. Результат записан в ADR 0007.
Повторный make up на существующих томах и чистый make clean && make up дали одинаковые наборы пользователей, ролей и прав. Доступ хранится в файлах, а не в SQL-хранилище.
Пароль Superset
Пароль bi берётся из CLICKHOUSE_BI_PASSWORD штатной функцией SQLALCHEMY_CUSTOM_PASSWORD_STORE. Для текущего стенда источник данных один; это допущение названо рядом с настройкой. Дополнительное хранилище секретов для учебного локального стенда не вводилось.
Перед запуском владельцу существующего стенда нужно перенести в свой .env новые переменные из .env.example: CLICKHOUSE_CLUSTER_SECRET, CLICKHOUSE_DEFAULT_PASSWORD, CLICKHOUSE_ETL_PASSWORD, CLICKHOUSE_BI_PASSWORD, CLICKHOUSE_ANALYST_PASSWORD. Иначе обязательная подстановка Compose остановит make up.
## Что сделано
- Добавлены пользователи `etl`, `bi`, `analyst` и роли `etl_writer`, `bi_reader`, `analyst_reader` в файловой конфигурации ClickHouse.
- Межнодовые запросы переведены на общий секрет кластера; учётные данные из описания реплик убраны.
- Airflow переключён на `etl`, Superset — на `bi`; служебному `default` задан пароль.
- README, мастер-спека и ADR 0007 приведены к фактическому устройству стенда и результатам замеров.
## Ручная проверка границ
| Проверка | Результат |
| --- | --- |
| `bi` читает `stg.hits_raw_dist` и `ods.event_dist` | `ACCESS_DENIED`, код 497; ошибка называет пользователя и объект |
| `analyst` читает те же таблицы | Успешно, 401185 строк |
| `analyst` пишет в `ods.event_rep` | `ACCESS_DENIED` |
| `etl` читает `stg` и `ods`, пишет в `stg` | Успешно |
| `etl` выполняет `CREATE DATABASE`, `CREATE TABLE` и `DROP ON CLUSTER` | Успешно |
| `default` подключается по HTTP без пароля | Ошибка аутентификации |
| `analyst` подключается по HTTP с паролем | Успешно |
При распределённом запросе от `analyst` на второй ноде измерено `user = analyst`, `initial_user = analyst`, `is_initial_query = 0`: соседний шард применяет права пользователя-инициатора. Результат записан в ADR 0007.
Повторный `make up` на существующих томах и чистый `make clean && make up` дали одинаковые наборы пользователей, ролей и прав. Доступ хранится в файлах, а не в SQL-хранилище.
## Пароль Superset
Пароль `bi` берётся из `CLICKHOUSE_BI_PASSWORD` штатной функцией `SQLALCHEMY_CUSTOM_PASSWORD_STORE`. Для текущего стенда источник данных один; это допущение названо рядом с настройкой. Дополнительное хранилище секретов для учебного локального стенда не вводилось.
Перед запуском владельцу существующего стенда нужно перенести в свой `.env` новые переменные из `.env.example`: `CLICKHOUSE_CLUSTER_SECRET`, `CLICKHOUSE_DEFAULT_PASSWORD`, `CLICKHOUSE_ETL_PASSWORD`, `CLICKHOUSE_BI_PASSWORD`, `CLICKHOUSE_ANALYST_PASSWORD`. Иначе обязательная подстановка Compose остановит `make up`.
## Проверка
- `make config-test`
- `make lint`
- `make smoke` — 20/20
- `make check-clickhouse` — 9/9
- `make check-services` — 7/7
- повторный `make up` на существующих томах
- `make clean && make up`
Closes #78
- Зачем:
- менти должен увидеть разделение доступа без состояния в томах.
- Что:
- пользователи и роли объявлены файлом с паролями из окружения.
- межшардовые запросы передают пользователя через общий секрет.
- четыре допущения реализации подтверждены в ADR живыми замерами.
- Проверка:
- make config-test, make smoke, make check-clickhouse, make check-services.
- Зачем:
- DDL, Airflow и Superset не должны работать с правами default.
- Что:
- DDL и Airflow переведены на etl, включая явный доступ remote().
- Superset переведён на bi с паролем из окружения.
- etl получил право KAFKA, которое ClickHouse 26.3 требует для движка.
- Проверка:
- make config-test, make lint, make up, make smoke, make check-services.
- Зачем:
- default должен остаться только учёткой локальных служебных вызовов.
- Что:
- пароль default подставлен из окружения на обеих нодах.
- healthcheck и служебные скрипты передают его внутри контейнера.
- Проверка:
- make config-test, make up, make smoke, make check-clickhouse, make check-services.
- Зачем:
- читателю нужна честная граница между учебными ролями и боевой защитой.
- Что:
- README описывает пользователей, роли и место хранения паролей.
- мастер-спека явно откладывает эксплуатационные меры защиты.
- устаревшие комментарии Compose и пробника приведены к реализации.
- Проверка:
- make config-test, make lint.
- Зачем:
- документация и конфигурация доступа должны говорить только подтверждённое.
- Что:
- ADR приведён к результату межшардового замера.
- объяснены служебный грант и учебный компромисс remote().
- удалены избыточные профили, README связан с ADR.
- Проверка:
- make config-test, make lint, make smoke, make check-clickhouse, make check-services.
ddmitry
merged commit 9d43ff5489 into main2026-08-13 11:39:32 +03:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Что сделано
etl,bi,analystи ролиetl_writer,bi_reader,analyst_readerв файловой конфигурации ClickHouse.etl, Superset — наbi; служебномуdefaultзадан пароль.Ручная проверка границ
biчитаетstg.hits_raw_distиods.event_distACCESS_DENIED, код 497; ошибка называет пользователя и объектanalystчитает те же таблицыanalystпишет вods.event_repACCESS_DENIEDetlчитаетstgиods, пишет вstgetlвыполняетCREATE DATABASE,CREATE TABLEиDROP ON CLUSTERdefaultподключается по HTTP без пароляanalystподключается по HTTP с паролемПри распределённом запросе от
analystна второй ноде измереноuser = analyst,initial_user = analyst,is_initial_query = 0: соседний шард применяет права пользователя-инициатора. Результат записан в ADR 0007.Повторный
make upна существующих томах и чистыйmake clean && make upдали одинаковые наборы пользователей, ролей и прав. Доступ хранится в файлах, а не в SQL-хранилище.Пароль Superset
Пароль
biберётся изCLICKHOUSE_BI_PASSWORDштатной функциейSQLALCHEMY_CUSTOM_PASSWORD_STORE. Для текущего стенда источник данных один; это допущение названо рядом с настройкой. Дополнительное хранилище секретов для учебного локального стенда не вводилось.Перед запуском владельцу существующего стенда нужно перенести в свой
.envновые переменные из.env.example:CLICKHOUSE_CLUSTER_SECRET,CLICKHOUSE_DEFAULT_PASSWORD,CLICKHOUSE_ETL_PASSWORD,CLICKHOUSE_BI_PASSWORD,CLICKHOUSE_ANALYST_PASSWORD. Иначе обязательная подстановка Compose остановитmake up.Проверка
make config-testmake lintmake smoke— 20/20make check-clickhouse— 9/9make check-services— 7/7make upна существующих томахmake clean && make upCloses #78