Introduced new environment variables for the authentication portal in the production and microvps configurations. Updated the documentation to clarify the necessity of passing these variables to the evobgp-all service. This change enhances the authentication flow by enabling single sign-on (SSO) capabilities through JWT, ensuring a more secure and streamlined user experience.
14 KiB
Предоставление доступа
Как выдавать доступ к control plane API, веб-клиентам и репликам BIRD (evobgp-node). Секреты храните в менеджере секретов, переменных окружения оркестратора или зашифрованных файлах — не коммитьте реальные ключи в Git.
Portal SSO (JWT)
Единый вход через auth-portal (app id bgp). См. integrate-evobgp.md в репозитории auth-portal.
| Переменная | Назначение |
|---|---|
AUTH_REQUIRED / EVOBGP_AUTH_REQUIRED |
Включить проверку portal JWT для UI |
AUTH_JWT_SECRET / EVOBGP_AUTH_JWT_SECRET |
Тот же секрет, что JWT_SECRET портала (HS256) |
AUTH_ISSUER |
Issuer JWT (как на портале) |
AUTH_PORTAL_URL |
URL портала (также GET /v1/auth/config) |
EVOBGP_PORTAL_TENANT_ID |
Tenant для всех portal JWT (обязателен при JWT) |
Compose: переменные AUTH_* / EVOBGP_PORTAL_TENANT_ID должны быть в environment: сервиса evobgp-all (см. deploy/compose/stack.microvps-full.yaml). Просто положить их в .env без проброса в контейнер недостаточно.
VITE_AUTH_* в runtime .env не меняют уже собранный evobgp-web образ. UI берёт режим из GET /v1/auth/config (required ← AUTH_REQUIRED, portal_url ← AUTH_PORTAL_URL).
Проверка после рестарта:
curl -sS https://bgp.shnt.top/v1/auth/config
# {"required":true,"portal_url":"https://auth.shnt.top"}
Права — строки bgp:<section>:<action> из каталога портала (dashboard, modules, lookup, network, …). Apply/rollback требуют bgp:operations:admin.
Ownership: modules, peers, firewall clients/rules с created_by_user_id видны создателю и portal is_admin (API keys — весь tenant).
UI: VITE_AUTH_ENABLED, VITE_AUTH_PORTAL_URL. App Switcher: CURRENT_APP_ID=bgp, конфиг с GET {portal}/api/v1/app-switcher.
API-ключи (EVOBGP_API_KEYS)
Формат переменной окружения: список записей через запятую без пробелов внутри логики парсера (пробелы вокруг записей допускаются при обрезке). Каждая запись:
<token>|<tenant_id>|<role>
- token — произвольная строка, передаётся клиентом как
Authorization: Bearer <token>. - tenant_id — идентификатор арендатора; все операции store привязываются к этому tenant для данного ключа.
- role — одна из ролей ниже (регистр для проверки уровня в коде приводится к lower case).
Пример для двух ключей одного tenant:
opkey|01ARZ3NDEKTSV4RRFFQ69G5FAV|operator,nodekey|01ARZ3NDEKTSV4RRFFQ69G5FAV|node
При включённом демо-сиде сервер при старте может вывести в лог готовую подсказку с реальным tenant_id из БД — см. лог evobgp-api / evobgp-all.
Ключи из EVOBGP_API_KEYS загружаются при старте и дополняют ключи из таблицы api_key в БД (break-glass / bootstrap). После первого operator-ключа можно создавать остальные через API или веб-настройки.
Управление через API и UI
При подключённой БД operator может:
GET|POST /v1/api-keys,GET|PATCH|DELETE /v1/api-keys/{id},POST /v1/api-keys/{id}/rotate— см. OpenAPI, тег API keys.- В веб-панели: Права доступа (
/access) → блок «API-ключи» (только для ролиoperator). Токен для браузера — в Настройки (/settings).
Полный токен возвращается один раз в ответе 201 (создание) и 200 (ротация). В списках — только prefix (первые 8 символов). В БД хранится SHA-256 токена, не plaintext.
GET /v1/auth/session — текущие tenant_id и role (для UI).
Роли
| Роль | Уровень | Назначение |
|---|---|---|
viewer |
1 | Только чтение (списки, GET сущностей) там, где это разрешено политикой обработчиков. |
editor |
2 | Чтение + создание/изменение CRUD (модули, записи, peers и т.д.), без опасных операций уровня оператора. |
operator |
3 | Полный операторский доступ: apply, rollback, настройки, отмена задач и т.п. (как задано в handlers). |
node |
отдельная | Только API для реплики: latest revision, скачивание бандла, enroll. Роль node запрещена для обычного CRUD — ответ 403 Forbidden. |
firewall |
отдельная | Только data-plane firewall-клиента: GET /v1/firewall/blocklist, POST /v1/firewall/apply-report, POST /v1/firewall/heartbeat. Токен в таблице firewall_client, не в api_key. См. firewall.md. |
Обратное ограничение: для эндпоинтов ноды требуется именно роль node; остальные роли получают отказ.
Токен dev (локальная разработка)
Если в store доступен демо-tenant (DemoIDs, обычно EVOBGP_SEED_DEMO не равен 0), заголовок Authorization: Bearer dev даёт роль operator для этого tenant. Не зависит от EVOBGP_DEV_INSECURE.
Без demo-tenant токен dev может быть задан в EVOBGP_API_KEYS (break-glass).
Запрещено в продакшене: не оставляйте demo-seed с известным токеном dev на боевых данных. Переменная EVOBGP_DEV_INSECURE в текущей версии не влияет на аутентификацию (оставлена в compose для совместимости; не включайте в production — см. SEC-02 в инженерных правилах).
PostgreSQL monitoring и maintenance (control plane)
При EVOBGP_DATABASE_URL (не memory backend):
| Операция | Минимальная роль |
|---|---|
GET /v1/monitoring/postgres/*, GET /v1/monitoring/correlation |
viewer |
POST /v1/postgres/vacuum, vacuum-analyze, analyze, reindex, cleanup |
operator (async job, rate limit 60s на kind) |
GET /v1/postgres/maintenance/logs |
viewer |
Метрики instance-level (не per-tenant). CLI: evobgp-api db … / evobgp-all db ….
Синхронные «тяжёлые» 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). Альтернатива для operator: GET /v1/bundle/signing-public-key → поле public_key_base64 для EVOBGP_BUNDLE_PUBKEY_BASE64 на реплике.
Использование в evobgp-node / agent:
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:
evobgp-node pull-bundle -base-url http://control.example:8080 -token "<node_token>" -speaker-id "<uuid>"
Panel→Node dispatch (удалённые спикеры)
На control plane (prod):
EVOBGP_NODE_DISPATCH_ENABLED=1
EVOBGP_BUNDLE_SEED_HEX=<32 bytes hex, стабильный>
После deploy_apply CP шлёт POST https://AGENT_DOMAIN/v1/agent/sync с Authorization: Bearer <agent_secret>. На реплике — EVOBGP_AGENT_SECRET, Traefik PANEL_IP_WHITELIST. Подробнее: remote-speakers.md.
Runtime log-файлы (EVOBGP_RUNTIME_LOGS_DIR)
Файловые логи Docker-сервисов (sidecar stack-runtime-logs в compose) читаются API только в процессе evobgp-all, когда заданы обе переменные:
EVOBGP_SERVICE=evobgp-all
EVOBGP_RUNTIME_LOGS_DIR=/opt/evobgp/runtime-logs
В dev-профиле compose каталог на хосте обычно ./runtime-logs, в контейнере — mount на /opt/evobgp/runtime-logs. Если каталог не задан или роль процесса не evobgp-all, FS-эндпоинты (/files, /auto-*) отвечают 503 (runtime_logs_unavailable). GET /v1/runtime-logs/cleanup-audit доступен без volume.
Очистка файлов — роль operator+; операции пишутся в runtime_log_cleanup_audit. Автоочистка настраивается в tenant settings (runtime_logs_auto_enabled, runtime_logs_max_file_mb, runtime_logs_auto_schedule, runtime_logs_auto_mode); scheduler — только в evobgp-all. Опционально: EVOBGP_RUNTIME_LOGS_POLICY_TENANT — tenant, чьи settings читает scheduler (иначе первый tenant с включённой автоочисткой).
Retention строк audit: пресет maintenance policy runtime_log_cleanup_audit (90d) в Monitoring → PostgreSQL → Политики.
CORS для веб-интерфейса
Браузерные запросы с другого origin требуют заголовков CORS на API. Задайте список разрешённых origin через EVOBGP_CORS_ORIGINS (через запятую), например:
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 описано использование 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.
Секреты для публикации образов или внешних сервисов в базовом CI не обязательны; добавляйте их отдельно под свои workflow.
Краткая матрица (ориентир)
| Действие | viewer | editor | operator | node |
|---|---|---|---|---|
| GET модули, ревизии, peers, speakers | да | да | да | нет |
| POST/PATCH/DELETE CRUD сущностей | нет | да | да | нет |
| apply, rollback, PATCH settings | нет | нет | да | нет |
Управление API-ключами (/v1/api-keys) |
нет | нет | да | нет |
| bundle, latest revision, enroll | нет | нет | нет | да |
Точные проверки по каждому маршруту — в коде internal/httpapi и в схеме безопасности операций в OpenAPI.
Связанные документы
- api.md — список групп эндпоинтов.
- quickstart.md — запуск с примером ключей.