# Предоставление доступа Как выдавать доступ к control plane API, веб-клиентам и репликам BIRD (`evobgp-node`). Секреты храните в менеджере секретов, переменных окружения оркестратора или зашифрованных файлах — не коммитьте реальные ключи в Git. ## API-ключи (`EVOBGP_API_KEYS`) Формат переменной окружения: список записей через **запятую** без пробелов внутри логики парсера (пробелы вокруг записей допускаются при обрезке). Каждая запись: ```text || ``` - **token** — произвольная строка, передаётся клиентом как `Authorization: Bearer `. - **tenant_id** — идентификатор арендатора; все операции store привязываются к этому tenant для данного ключа. - **role** — одна из ролей ниже (регистр для проверки уровня в коде приводится к lower case). Пример для двух ключей одного tenant: ```text opkey|01ARZ3NDEKTSV4RRFFQ69G5FAV|operator,nodekey|01ARZ3NDEKTSV4RRFFQ69G5FAV|node ``` При включённом демо-сиде сервер при старте может вывести в лог готовую подсказку с реальным `tenant_id` из БД — см. лог `evobgp-api` / `evobgp-all`. ### Роли | Роль | Уровень | Назначение | |------|---------|------------| | `viewer` | 1 | Только чтение (списки, GET сущностей) там, где это разрешено политикой обработчиков. | | `editor` | 2 | Чтение + создание/изменение CRUD (модули, записи, peers и т.д.), без опасных операций уровня оператора. | | `operator` | 3 | Полный операторский доступ: apply, rollback, настройки, отмена задач и т.п. (как задано в handlers). | | `node` | отдельная | Только API для реплики: latest revision, скачивание бандла, enroll. Роль **`node` запрещена** для обычного CRUD — ответ `403 Forbidden`. | Обратное ограничение: для эндпоинтов ноды требуется именно роль **`node`**; остальные роли получают отказ. ### Режим разработки `EVOBGP_DEV_INSECURE` Если установлено `EVOBGP_DEV_INSECURE=1` и в store доступен демо-tenant (`DemoIDs`), то запрос с заголовком **`Authorization: Bearer dev`** получает контекст **`operator`** для этого tenant. **Запрещено** в продакшене: любой, кто знает заголовок, получает полные права оператора на демо-данные. В reference Compose (`deploy/compose/docker-compose.yaml`) флаг включён только для локальной разработки. ### Синхронные «тяжёлые» GET (control plane) - `POST /v1/modules/{module_id}/cdn-sources/preview` — загрузка CDN в том же HTTP-запросе (лимит тела ~8 MiB, см. OpenAPI). - `GET /v1/bird/status` (если маршрут включён в деплое) — опрос локального `birdc`, таймаут сервера ~12 с. ### Детерминированный ключ подписи бандлов (тесты) `EVOBGP_BUNDLE_SEED_HEX` — необязательная hex-строка для инициализации ключа подписи бандлов (удобно в CI и локальных прогонах). В проде обычно используется случайная генерация при старте, если seed не задан. ## Публичный ключ бандла для нод При старте API в лог печатается строка **bundle signing public key (base64)**. Её нужно передать администратору реплики и использовать в `evobgp-node`: ```text evobgp-node verify-bundle -f bundle.tar.gz -pubkey-base64 "<из_лога_API>" evobgp-node apply-bundle -f bundle.tar.gz -extract-dir /path/to/dir -pubkey-base64 "<...>" ``` Команда `pull-bundle` использует **тот же Bearer-токен**, что зарегистрирован с ролью **`node`**: ```text evobgp-node pull-bundle -base-url http://control.example:8080 -token "" -speaker-id "" ``` ## CORS для веб-интерфейса Браузерные запросы с другого origin требуют заголовков CORS на API. Задайте список разрешённых origin через **`EVOBGP_CORS_ORIGINS`** (через запятую), например: ```text http://localhost:5173,http://127.0.0.1:5173,https://ui.example.com ``` Разрешённые заголовки включают `Authorization`, `Content-Type`, `Idempotency-Key`, `Accept`, `X-Tenant-Id` (см. `internal/httpapi/cors.go`). ## Заголовок `X-Tenant-Id` (спецификация vs реализация) В [openapi.yaml](openapi.yaml) описано использование **`X-Tenant-Id`** для супер-ролей при работе от имени разных арендаторов. В **текущем коде** после аутентификации tenant берётся **только из записи API-ключа**; заголовок `X-Tenant-Id` **не переопределяет** tenant в обработчиках. До появления поддержки в коде не рассчитывайте на переключение tenant через этот заголовок. ## Доступ к репозиторию и CI Чтобы коллега мог читать код, открывать PR и видеть результаты Gitea Actions: - Выдайте права на репозиторий в вашей forge (Gitea/GitHub/GitLab): как минимум **Read** для просмотра, **Write** для веток и PR. - Требования к runner и описание workflow — [.gitea/README.md](../.gitea/README.md). Секреты для публикации образов или внешних сервисов в базовом CI не обязательны; добавляйте их отдельно под свои workflow. ## Краткая матрица (ориентир) | Действие | viewer | editor | operator | node | |----------|--------|--------|----------|------| | GET модули, ревизии, peers, speakers | да | да | да | нет | | POST/PATCH/DELETE CRUD сущностей | нет | да | да | нет | | apply, rollback, PATCH settings | нет | нет | да | нет | | bundle, latest revision, enroll | нет | нет | нет | да | Точные проверки по каждому маршруту — в коде `internal/httpapi` и в схеме безопасности операций в OpenAPI. ## Связанные документы - [api.md](api.md) — список групп эндпоинтов. - [quickstart.md](quickstart.md) — запуск с примером ключей.