01 overview
Auth Center — тонкий фасад: JWT, KYC-оркестрация, PII и прокси к Payment Manager.
Роль в системе¶
Auth Center отвечает ровно за пять областей — всё остальное делегируется:
- JWT — выдача и ротация токенов (accessToken 30 мин, refreshToken 14 дней), OTP при регистрации
- KYC-оркестрация — координирует kyc-service (OCR, верификация документов), хранит статусы и аудит
- PII шифрование at rest — AES-256-GCM через
PiiCryptoService; в DB никогда не попадает открытый текст - Тонкий фасад к Payment Manager — HMAC-подписанные HTTP вызовы; бизнес-логика платежей остаётся в PM
- nginx auth_request —
/nginx/authи/nginx/auth/adminвозвращают 200/401/403 +X-User-*заголовки
Inbound / Outbound¶
flowchart LR
subgraph apps[Flutter Apps]
loop[one_loop_app]
merchant[one_merchant_app]
end
subgraph ac[Auth Center :8080]
ep[Endpoints × 16]
svc[Services]
db[(PostgreSQL\npublic.*)]
end
loop -->|Serverpod RPC| ep
merchant -->|Serverpod RPC| ep
ep <--> svc
svc <--> db
svc -->|HMAC POST /intents| pm[Payment Manager :3000]
svc -->|HTTP| kycsvc[kyc-service :3003]
svc -->|S3 PUT/GET| garage[Garage S3]
svc -->|Redis XADD| redis[(Redis\nstream.notifications.jobs)]
nginx[nginx] -->|auth_request GET /nginx/auth| ep
Жизненный цикл запроса¶
- Flutter-приложение вызывает сгенерированный Serverpod-клиент (
onewallet_base_client/) - Запрос идёт через nginx (публичный ingress, TLS-терминация)
- nginx проксирует на Auth Center
:8080 - Serverpod проверяет accessToken → заполняет
session.authenticated - Endpoint вызывает
requireAccountType(session, [...])— guard изlib/src/util/endpoint_guard.dart - Endpoint делегирует бизнес-логику соответствующему Service
- Service читает/пишет в
public.*(PostgreSQL) и/или вызывает внешние системы - При платёжных операциях —
PspHmacClientформирует HMAC и делает HTTP POST в PM
Ключевые инварианты¶
| # | Инвариант | Последствие нарушения |
|---|---|---|
| 1 | PII только через PiiProfileWriter |
Данные без шифрования/хеша в DB |
| 2 | PM только через PspHmacClient |
Неподписанные запросы (403 от PM) |
| 3 | TigerBeetle только через PM | Прямой write в финансовый ledger |
| 4 | pm.* только чтение |
Запись в чужую схему — нарушение изоляции |
| 5 | requireAccountType() обязателен |
Доступ не того типа аккаунта |
Запрещённые паттерны¶
- Прямой вызов TigerBeetle Node SDK из Dart-кода
- Запись (
INSERT/UPDATE) вpm.*схему - HTTP вызов к PM без HMAC заголовков (
X-Service-Id,X-Timestamp,X-Signature,X-User-Id) - PII (имя, телефон, номер документа) в открытом виде в логах или колонках DB
- Custom REST endpoints — только Serverpod RPC (сгенерированный клиент)
- Прямое редактирование файлов в
onewallet_base_client/— только черезserverpod generate
Tech stack¶
| Технология | Версия | Зачем |
|---|---|---|
| Dart SDK | ^3.8.0 | Язык сервера |
| Serverpod | 3.4.8 | RPC-фреймворк, ORM, миграции, JWT auth |
| PostgreSQL | 17 | Основная DB (public.* схема) |
| Redis | ^4.0.0 | XADD в stream.notifications.jobs |
| Minio (Dart) | 3.5.8 | S3-клиент для Garage (KYC документы) |
| Dio | ^5.4.0 | HTTP-клиент для вызовов в PM и kyc-service |
| Crypto | ^3.0.7 | HMAC-SHA256 подпись запросов к PM |