Добавлен POST /api/v1/ingest/audit, фильтры source_app/user_id, last_login_at; таблица пользователей по solution-users-1 с журналом в Sheet. Co-authored-by: Cursor <[email protected]>
105 lines
4.2 KiB
Markdown
105 lines
4.2 KiB
Markdown
# Интеграция auth-portal ↔ EvoBGP
|
||
|
||
Единый вход: пользователь логинится на auth-portal, получает JWT, переходит в EvoBGP с токеном в URL fragment. EvoBGP API проверяет JWT и права `bgp:*`. API-ключи EvoBGP (viewer/editor/operator/node) остаются для автоматизации и нод. Firewall-клиенты перенесены в **EvoFirewall** (`fw:*`).
|
||
|
||
## Архитектура
|
||
|
||
```
|
||
Browser → EvoBGP UI (нет token)
|
||
→ redirect AUTH_PORTAL_URL/?return_to=…/auth/callback
|
||
→ login
|
||
→ redirect return_to#access_token=…
|
||
→ EvoBGP /auth/callback сохраняет token
|
||
→ API Authorization: Bearer <JWT>
|
||
```
|
||
|
||
Общий секрет: `JWT_SECRET` / `AUTH_JWT_SECRET` (HS256). Issuer: `ISSUER` / `AUTH_ISSUER`.
|
||
|
||
App id в портале: **`bgp`**.
|
||
|
||
## Permissions ↔ UI
|
||
|
||
| Permission | UI |
|
||
|------------|-----|
|
||
| `bgp:dashboard:read` | `/dashboard` |
|
||
| `bgp:modules:read` / `write` | `/modules` |
|
||
| `bgp:lookup:read` | `/lookup` |
|
||
| `bgp:network:read` / `write` | `/network` (пиры и спикеры) |
|
||
| `bgp:directories:read` / `write` | `/directories` |
|
||
| `bgp:operations:read` / `write` / `admin` | `/operations` (admin = apply/rollback) |
|
||
| `bgp:schedule:read` / `write` | `/schedule` |
|
||
| `bgp:monitoring:read` | `/monitoring` |
|
||
| `bgp:access:admin` | `/access` (API-ключи) |
|
||
| `bgp:tenant_settings:admin` | `/tenant-settings` |
|
||
| `bgp:settings:read` | `/settings` |
|
||
|
||
Иерархия: `admin` ⊃ `write` ⊃ `read` в рамках одной секции.
|
||
|
||
Пример обычного пользователя: app `bgp` + только `bgp:dashboard:read` и `bgp:lookup:read`.
|
||
|
||
### Ownership
|
||
|
||
Ресурсы modules / peers, созданные через JWT, имеют `created_by_user_id`. Видят и редактируют: создатель и portal `is_admin` (или API key `operator`). API keys без user id — tenant-wide scope. Firewall — см. EvoFirewall / `docs/integrate-evofirewall.md`.
|
||
|
||
## Локальный запуск
|
||
|
||
### 1. auth-portal
|
||
|
||
```bash
|
||
cd auth-portal
|
||
pnpm install
|
||
# JWT_SECRET=dev-secret-change-me
|
||
# RETURN_TO_ALLOWLIST=.shnt.top,localhost,http://localhost:5173,…EvoBGP web origin
|
||
pnpm --filter @authportal/api dev # :8080
|
||
pnpm --filter web dev # :5175
|
||
```
|
||
|
||
```env
|
||
# apps/web/.env.local
|
||
VITE_BGP_APP_URL=http://localhost:5176
|
||
```
|
||
|
||
Bootstrap: выдайте app **bgp** и нужные `bgp:*` permissions.
|
||
|
||
### 2. EvoBGP
|
||
|
||
```env
|
||
AUTH_REQUIRED=true
|
||
AUTH_JWT_SECRET=dev-secret-change-me
|
||
AUTH_ISSUER=https://auth.shnt.top
|
||
AUTH_PORTAL_URL=http://localhost:5175
|
||
# Опционально, если tenant не задан в portal /admin/apps для bgp:
|
||
# EVOBGP_PORTAL_TENANT_ID=<uuid tenant>
|
||
```
|
||
|
||
```env
|
||
# apps/web/.env.local
|
||
VITE_AUTH_ENABLED=true
|
||
VITE_AUTH_PORTAL_URL=http://localhost:5175
|
||
```
|
||
|
||
В portal **Админ → Приложения → BGP** укажите **EvoBGP tenant ID** (UUID из БД / лога `DemoIDs` / API-ключа). Он попадёт в JWT как `bgp_tenant_id`. Portal `is_admin` получает полный каталог `bgp:*` в JWT.
|
||
|
||
## App Switcher
|
||
|
||
Публичный конфиг: `GET {AUTH_PORTAL_URL}/api/v1/app-switcher` (без `tenantId`).
|
||
`CURRENT_APP_ID = bgp`. Редактор ссылок и tenant — portal `/admin/apps`.
|
||
|
||
## Logout (SSO)
|
||
|
||
Очистить локальный JWT → `AUTH_PORTAL_URL/logout` (не `/?return_to=`).
|
||
|
||
## Audit ingest
|
||
|
||
Dual-write локального журнала в portal: [`integrate-audit-ingest.md`](./integrate-audit-ingest.md) (`source_app: bgp`).
|
||
|
||
## Troubleshooting
|
||
|
||
| Симптом | Причина |
|
||
|---------|---------|
|
||
| 401 на API | Нет/битый Bearer; разные `JWT_SECRET` |
|
||
| 403 нет доступа к приложению | В portal не выдан app `bgp` |
|
||
| 403 на раздел | Нет `bgp:<section>:…` (у admin после обновления портала — полный каталог; перелогиньтесь) |
|
||
| portal tenant not configured | Нет tenant в JWT и нет `EVOBGP_PORTAL_TENANT_ID` |
|
||
| return_to rejected | origin EvoBGP не в `RETURN_TO_ALLOWLIST` |
|