Files
EvoBGP/docs/access.md
T
Denozordec b871d62de6 feat(auth): add environment variables for portal SSO integration
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.
2026-07-19 00:55:35 +07:00

14 KiB
Raw Blame History

Предоставление доступа

Как выдавать доступ к 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 (requiredAUTH_REQUIRED, portal_urlAUTH_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 — запуск с примером ключей.