Добавлены новые возможности для работы с файловыми логами Docker-сервисов: - Эндпоинты для получения списка логов и хвоста лог-файла. - Очистка лог-файлов с возможностью выбора режима (truncate или delete) и запись в аудит очистки. - Обновлена документация и конфигурация для поддержки новых функций. Co-authored-by: Cursor <[email protected]>
154 lines
11 KiB
Markdown
154 lines
11 KiB
Markdown
# Предоставление доступа
|
||
|
||
Как выдавать доступ к control plane API, веб-клиентам и репликам BIRD (`evobgp-node`). Секреты храните в менеджере секретов, переменных окружения оркестратора или зашифрованных файлах — не коммитьте реальные ключи в Git.
|
||
|
||
## API-ключи (`EVOBGP_API_KEYS`)
|
||
|
||
Формат переменной окружения: список записей через **запятую** без пробелов внутри логики парсера (пробелы вокруг записей допускаются при обрезке). Каждая запись:
|
||
|
||
```text
|
||
<token>|<tenant_id>|<role>
|
||
```
|
||
|
||
- **token** — произвольная строка, передаётся клиентом как `Authorization: Bearer <token>`.
|
||
- **tenant_id** — идентификатор арендатора; все операции store привязываются к этому tenant для данного ключа.
|
||
- **role** — одна из ролей ниже (регистр для проверки уровня в коде приводится к lower case).
|
||
|
||
Пример для двух ключей одного tenant:
|
||
|
||
```text
|
||
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`. |
|
||
|
||
Обратное ограничение: для эндпоинтов ноды требуется именно роль **`node`**; остальные роли получают отказ.
|
||
|
||
### Токен `dev` (локальная разработка)
|
||
|
||
Если в store доступен демо-tenant (`DemoIDs`, обычно `EVOBGP_SEED_DEMO` не равен `0`), заголовок **`Authorization: Bearer dev`** даёт роль **`operator`** для этого tenant. **Не зависит** от `EVOBGP_DEV_INSECURE`.
|
||
|
||
**Запрещено** в продакшене: не оставляйте 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:
|
||
|
||
```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 "<node_token>" -speaker-id "<uuid>"
|
||
```
|
||
|
||
## Panel→Node dispatch (удалённые спикеры)
|
||
|
||
На control plane (prod):
|
||
|
||
```text
|
||
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](remote-speakers.md).
|
||
|
||
## Runtime log-файлы (`EVOBGP_RUNTIME_LOGS_DIR`)
|
||
|
||
Файловые логи Docker-сервисов (sidecar `stack-runtime-logs` в compose) читаются API **только** в процессе **`evobgp-all`**, когда заданы обе переменные:
|
||
|
||
```text
|
||
EVOBGP_SERVICE=evobgp-all
|
||
EVOBGP_RUNTIME_LOGS_DIR=/opt/evobgp/runtime-logs
|
||
```
|
||
|
||
В dev-профиле compose каталог на хосте обычно `./runtime-logs`, в контейнере — mount на `/opt/evobgp/runtime-logs`. Если каталог не задан или роль процесса не `evobgp-all`, эндпоинты `/v1/runtime-logs/*` отвечают **503** (`runtime_logs_unavailable`). Очистка файлов — роль **operator+**; операции пишутся в таблицу `runtime_log_cleanup_audit`.
|
||
|
||
## 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 | нет | нет | да | нет |
|
||
| Управление API-ключами (`/v1/api-keys`) | нет | нет | да | нет |
|
||
| bundle, latest revision, enroll | нет | нет | нет | да |
|
||
|
||
Точные проверки по каждому маршруту — в коде `internal/httpapi` и в схеме безопасности операций в OpenAPI.
|
||
|
||
## Связанные документы
|
||
|
||
- [api.md](api.md) — список групп эндпоинтов.
|
||
- [quickstart.md](quickstart.md) — запуск с примером ключей.
|