API-ключи, токены и мандаты доступа: безопасная аутентификация
Полный текст статьи
1) Зачем всё это: модель угроз для iGaming
Деньги и PII: компрометация ключа → фрод, утечки, штрафы.
Сетевые интеграции: десятки внешних провайдеров, разные регионы/лицензии.
Высокие ставки SLA: простой или дубль платежа — репутационные и юридические риски.
Вывод: аутентификация и авторизация должны быть «по умолчанию безопасны», с минимальными привилегиями и жёсткой наблюдаемостью.
2) Инструменты: что у нас есть в арсенале
API-ключи: статические идентификаторы клиента. Проста интеграция, высокий риск утечек.
OAuth2 (Client Credentials): краткоживущие Bearer-токены со scope/audience.
mTLS: взаимная TLS-проверка, сильная привязка клиента к каналу.
HMAC/EdDSA подписи: криптографическая целостность тела запроса и защита от реплеев (timestamp + nonce).
Proof-of-Possession: MTLS-bound токены или DPoP (подпись HTTP-запроса ключом клиента).
JWT/PASETO: самоописывающиеся токены (желательно с коротким TTL).
RBAC/ABAC: роль/атрибут-бэйзд авторизация (OPA/решения политик).
Временные мандаты доступа (delegation/STS): ограниченные по времени и целям билеты, выдаваемые на конкретный сценарий.
3) Базовые принципы («стоп-знаки»)
1. Least Privilege: каждому ключу/токену — минимально возможные права.
2. Short-lived by default: TTL минутами, не днями. Ротация — автоматическая.
3. Bind to channel: привязка токенов к mTLS/DPoP → бесполезны при утечке.
4. Per-brand/region: ключи/сертификаты и разрешения — на бренд/лицензию/регион.
5. No shared secrets в коде: секреты только через Vault/HSM/KMS, ни в Git/логах.
6. WORM-аудит: неизменяемые логи всех операций/выдач/ротаций.
7. Идемпотентность на write-путах: любой повтор с тем же ключом не меняет деньги второй раз.
4) Когда использовать что (iGaming-контекст)
5) Дизайн мандатов доступа (scopes, audience, условия)
Scope-ы (примеры):- `bets:write`, `settlements:write`, `wallet:credit`, `wallet:debit`, `rg:read`, `rg:enforce`, `jackpot:trigger`.
Audience: кому адресован токен (например, `aud: wallet.api`).
Constraints (fine-grained):- `brand_id`, `region`, `ip/cidr`, `time_of_day`, `rate_limit`, `max_amount`.
- Хранятся в токене (JWT claims) или в выписанном «мандате» в Vault/STS.
6) Эталонные флоу
6.1 Платформа ⇄ RGS: деньги по RPC
1. mTLS handshake (сертификаты per brand/region).
2. OAuth2 CC: RGS получает `access_token` (TTL 2–5 мин, `aud=wallet.api`, `scope=bets:write settlements:write`).
3. Запрос `POST /v1/bets/authorize` с заголовками:- `Authorization: Bearer `, `X-Idempotency-Key`, `X-Trace-Id`. 
- 4. Ответ + запись в WORM-аудит (кто/что/когда/откуда).
- 5. Ротация токена бесшовная, по истечении — повтор CC.
6.2 Вебхуки платформа → провайдер
Заголовок `X-Signature: eddsa=
Провайдер проверяет: окно валидности (±5 мин), одноразовость `nonce`, подпись тела.
При недоступности — ретрай c backoff, дедуп по `event_id`.
6.3 Делегирование (джекпот-сервис → кошелёк)
JP вызывает STS: «дай временный токен на `wallet:credit` для `player_id=p_…`, сумма ≤ X, TTL 2 мин».
STS проверяет политику/лимиты → выдаёт мандат (узкий токен).
JP кредитует кошелёк с этим токеном. Компрометировать такой токен бессмысленно: короткий TTL, узкие права, привязка к mTLS.
7) Конструкции запросов
7.1 Идемпотентность (обязательно)
POST /v1/bets/settle
Authorization: Bearer <MTLS-bound>
X-Idempotency-Key: settle_r_8c12_1
X-Trace-Id: tr_a1b2
{
"bet_id":"b_001",  "round_id":"r_8c12",  "win":{"amount":1460,"currency":"EUR"}
}
→ 200 { "status":"credited", "settlement_id":"st_77" }
(повтор с тем же ключом → тот же ответ)7.2 Подпись вебхука (HMAC)
X-Signature: sha256=BASE64(HMAC(secret, timestamp + "." + nonce + "." + body))
X-Timestamp: 1730000000
X-Nonce: 1f7a...8) Управление секретами и ключами
Vault/HSM/KMS: генерация, хранение, ротация, отзыв.
Пер-окружение: sandbox/prod — разные корни доверия.
Пер-бренд/регион: отдельные ключи и сертификаты.
Авто-ротация: cron/оповещения; overlap-периоды для бесшовных замен.
Запрет в коде/логах: секреты не пишутся в stdout, не попадают в crash-репорты.
Device/Workload identity: SPIFFE/SPIRE, K8s ServiceAccount → mTLS без ручных секретов.
9) Политики авторизации (RBAC/ABAC) и OPA
RBAC: роли «rgs», «wallet», «jackpot», «reporting».
ABAC: правила «если `region=EU` и `brand=A` → разрешить `wallet:credit` ≤ 10k».
OPA/REGO или аналоги: централизованное принятие решений, версионирование политик, сухие тесты.
10) Наблюдаемость и аудит
Сквозные `trace_id` и `client_id` в каждом запросе/событии.
Метрики: p50/p95/p99 latency по эндпоинтам, error-rate по кодам (`AUTH_FAILED`, `SCOPE_DENIED`, `IDEMPOTENCY_MISMATCH`), частота ротаций, доля просроченных токенов.
WORM-журнал: выдачи/отзывы токенов, смена ключей, изменение политик.
Алерты: всплеск `AUTH_FAILED`, аномалии по гео/ASN, рост «просрочен/отозван» > порога.
11) Региональная резидентность и сегментация
Токены/сертификаты привязаны к региону (EU/UK/BR/…).
В клеймах — `region`, платформенные шлюзы запрещают кросс-региональные вызовы.
Раздельные KMS и Vault-кластера на регион; ключи не «ездят» между регионами.
12) Инциденты и отзыв
Compromise playbook: мгновенный revoke ключей/токенов, блок сетей/ASN, закрытие scope.
Kill-switch на уровне шлюза: «no new sessions / funds».
Постмортем: «как попало в логи/репозиторий», «почему не сработала DLP/сканер секретов».
13) Чек-листы
A. Для платформы
- Все write-пути: mTLS + OAuth2 CC (TTL ≤ 5 мин), `X-Idempotency-Key`, `X-Trace-Id`.
- Вебхуки: HMAC/EdDSA + timestamp + nonce, дедуп по `event_id`.
- Кейстор: Vault/HSM/KMS, ротация и отзыв, разделение per brand/region.
- OPA/политики: RBAC/ABAC, журналы изменений, тесты.
- WORM-аудит и SLO-дашборды (latency, error, revoke/rotate).
- DR/хаос-учения: истёкшие токены, подмена подписи, MITM без mTLS.
B. Для провайдера (RGS/live/JP)
- Не храню секреты в коде; использую Vault/подмену через переменные среды.
- Авто-ротация токенов; handle 401/403 с обновлением.
- Подписываю вебхуки/проверяю окна валидности и одноразовость.
- Веду аудит ключевых действий и реагирую на Deprecation/Sunset заголовки.
- Идемпотентность на всех write-вызовах, дедуп по `Idempotency-Key`.
14) Анти-паттерны (красные флаги)
Статические API-ключи без срока годности в проде.
Bearer-токены без привязки к каналу (нет MTLS/DPoP).
Хранение секретов в Git/CI-логе/конфиге фронтенда.
Общий ключ/сертификат для нескольких брендов/регионов.
Вебхуки без подписи и временного окна → реплеи.
Отсутствие централизованного отзыва и WORM-журнала.
Отсутствие идемпотентности → дубли дебетов/кредитов.
15) Мини-шаблоны политики (пример, человекочитаемо)
Мандат `rgs→wallet` (EU, brand A):- `aud=wallet.api`, `scope=["bets:write","settlements:write"]`
- `constraints: region=EU, brand=A, ip in {asn:…}, max_amount=5000 EUR, ttl=300s`
- `binding: mTLS(cert_hash=sha256:…)`
- `alg=Ed25519`, окно `±300s`, `nonce` уникален, дедуп `event_id` 24 часа.
Безопасная аутентификация в iGaming — это комбинация практик: краткоживущие мандаты, привязка к каналу (mTLS/DPoP), узкие scope/audience, строгая идемпотентность, Vault/HSM и WORM-аудит, региональная сегментация и наблюдаемость. Такой стек не мешает скорости интеграций, но радикально снижает риск утечек и финансовых инцидентов — деньги и данные остаются под контролем, апгрейды проходят предсказуемо, а комплаенс выполняется «из коробки».
