Перейти к основному содержимому

Для нас: как выдан доступ и как выдать ещё

Не для менеджеров. Здесь то, что делается с нашей стороны и что придётся повторить при добавлении человека.

Что открыто

ЧтоПорт на релеКуда ведётКому
Просмотрщик базы (Adminer)801110.0.1.7:801010.77.0.12, .13, .14
Data API801410.0.1.7:8014те же три адреса

10.77.0.12 — Лиза, .13 — Аня, .14 — Аля.

⚠️ Порт 8012 занят контейнером mcp-server-sse, и занят он на 0.0.0.0. Выкладка 11.08.2026 отказала на запуске контейнера («port is already allocated») и оставила сайт лежать: docker считает конфликтом чужую привязку к 0.0.0.0 на том же номере, даже когда своя привязка идёт к 10.0.1.7. Свободный порт сверять на сервере до правки compose.

⚠️ Осторожно с числом 8010. На 10.0.1.7:8010 висит просмотрщик, а на 127.0.0.1:8010 — Data API. Один и тот же номер порта на разных адресах привязки; перепутать легко, и тогда наружу уедет не то.

Как объявлен порт Data API

В docker-compose.s3-next.yml, у службы gwptd-data-api, второй привязкой:

ports:
- "127.0.0.1:8010:8088" # для самого сайта
- "10.0.1.7:8014:8088" # для бренд-менеджеров по WireGuard

Наружу это не выходит: 10.0.1.7 — внутренний адрес, и попасть на него можно только через реле, где стоит правило только на три адреса.

Ключи

Живут в /opt/gwptd-analytics/env/data-api.env, переменная DATA_API_TOKENS. Формат: ключ:полномочие|полномочие, записи через запятую.

Гостевой ключ выдаётся с тремя полномочиями:

data:read|status:read|guest

guest — не полномочие доступа, а метка. По ней действует предел частоты (см. ниже). Служебные ключи её не несут и не ограничиваются.

Выдать ключ

Ключ порождается на сервере и в чат не попадает — так требует правило о секретах. Порядок:

  1. sudo на s3, породить случайный ключ, дописать его в DATA_API_TOKENS;
  2. записать, кому он выдан, в /etc/gwptd/secrets/brand-tokens.txt (права 600);
  3. перезапустить gwptd-data-api — служба читает окружение при старте;
  4. отдать ключ человеку тем же способом, что пароль просмотрщика.

⚠️ Файл окружения перед правкой копировать. Строка DATA_API_TOKENS одна и длинная; неудачная правка отнимает доступ и у боевого сайта, а не только у гостя.

Отозвать ключ

Убрать запись из DATA_API_TOKENS и перезапустить службу. Ключи персональные именно ради этого: отзыв одного не трогает остальных.

Предел частоты

data_api/rate_limit.py, включается переменной DATA_API_RATE_LIMIT_PER_MIN (по умолчанию 60).

Ограничиваются только ключи с меткой guest. Служебные проходят без счёта — у боевого сайта всплески законны: открытая страница с десятком таблиц шлёт десяток запросов разом, и предел на нём означал бы отказы там, где отказывать нельзя. Это закреплено тестом: ни один служебный ключ не должен нести метку.

Окно минутное, счётчик в памяти процесса. Перезапуск обнуляет — осознанно: общее хранилище ради «гость получит лишнюю минуту квоты» не окупается.

Значение 0 выключает счёт совсем, а не запрещает всё. Тоже под тестом: иначе забытая в нуле переменная отрубила бы гостей и выглядела бы как поломка службы.

Чего ещё нет

  • журнала обращений по ключу. Ключ в запросе есть, отдельного журнала «кто что читал» пока нет. Понадобится, когда гостей станет больше трёх;
  • отрисовщика описаний — шаг 3 замысла. Каталоги и пункты меню построены 12.08 (шаги 1–2), страница пока честно говорит, что показывать нечем;
  • библиотеки элементов /brand-lib/ — описана в UI-BIBLIOTEKA.md, не построена.

UI-BIBLIOTEKA.md написан как справка и опережает код: библиотеки ещё нет. UI-STRANICA.md описывал папки со своей разметкой — этот замысел ОТМЕНЁН решением владельца 12.08: страница не программируется, а описывается YAML'ом, и рисует её наш код. Файл переписан.

Что построено 12.08 (шаги 1–2)

/opt/gwptd-brand/
├── chernoviki/ ← сюда кладут агенты, в меню не попадает
└── opublikovano/ ← отсюда строится меню, видно по правам

Смонтировано в контейнер как /var/www/html/brand только на чтение. Публикация — перенос файла между каталогами; выкладка сайта не нужна.

Разбор: app/Services/BrandPages/BrandPageRegistry.php. Негодное описание пропускается с названной причиной (rejected()), меню не роняет. Пункт получает пометку «БМ» и ведёт на /new/brand-page?stranica=<имя>.

Добавить четвёртого человека

  1. Адрес в WireGuard — как у первых трёх.
  2. Правило на реле: тот же порт, новый адрес источника.
  3. Ключ по порядку выше.
  4. Строку в brand-tokens.txt — кому выдан.

Правило на реле объявляется по каждому адресу отдельно; забыть один — значит получить «у меня не открывается» ровно у одного человека, и выглядеть это будет как проблема на его стороне.