Контроль доступа и RBAC в API
1) Зачем контроль доступа в API
Авторизация — это ответ на вопрос «можно ли этому актору выполнить это действие над этим ресурсом сейчас?». Ошибки приводят к BOLA/IDOR-утечкам, эскалации прав и нарушению требований регуляторов. Цель — построить многоуровневую модель: периметр → сервис-мэш → бизнес-правила, с явными политиками и проверками на объектном уровне.
2) Модели авторизации: когда что выбирать
RBAC (Role-Based Access Control) — роли → разрешения. Проста, стабильна, но склонна к «взрыву ролей».
ABAC (Attribute-Based) — решение по атрибутам субъекта/объекта/контекста (страна, KYC-уровень, владелец ресурса, риск).
ReBAC (Relationship-Based) — граф отношений (владелец, член команды, «менеджер проекта»); решает сложные иерархии.
Scopes (OAuth) — договор между клиентом и ресурс-сервером о «зоне доступа» (например, `payments:write`).
Практика: RBAC для базовой матрицы, ABAC для контекста и ограничений, ReBAC для сложных иерархий (папки, организации, лимиты и подаккаунты).
3) Таксономия ресурсов и действий
Иерархии: `org → project → wallet → transaction`. Наследование прав сверху вниз с возможными «ограничителями».
Действия: CRUD + domain-специфичные (`approve`, `refund`, `settle`).
Свойства ресурсов: владелец, регион, статус, риск-тэги (AML/KYC), лимиты.
Мультиарендность: все решения содержат `tenant_id`; запрет кросс-тенантных запросов по умолчанию (deny-by-default).
4) Архитектура: где принимается решение
PEP (Policy Enforcement Point) — место проверки: шлюз/API-гейтвей, sidecar мэша, сам сервис.
PDP (Policy Decision Point) — движок политик: централизованный (OPA-сервис, Cedar-движок) или встроенный библиотечно.
PIP (Policy Information Point) — источники атрибутов: каталог пользователей/ролей, профиль тенанта, KYC/риск, карта владения ресурсами.
PAP (Policy Administration Point) — управление версиями политик, публикация, аудит.
Рекомендация: централизованный PDP + локальный кэш решений в PEP; сложные объектные проверки в сервисе при наличии доменных инвариантов.
5) Токены, клеймы и идентичность
OIDC/OAuth2: `sub` (идентификатор субъекта), `aud` (целевой сервис), `scope`/`roles`, `tenant`, `kyc_level`, `risk_tier`.
JWT: RS/ES-подпись, короткое `exp`, перевыпуск по refresh. Не кладите PII; используйте `jti` для отзыва/трек-аудита.
mTLS/HMAC: сервис-к-сервис и партнеры; клеймы подтягиваются из каталога по `client_id`.
Device/Context: IP/ASN, гео, время суток — вход в ABAC-решение (например, запрет write вне рабочих часов).
6) Объектно-уровневая авторизация (BOLA-first)
Каждая операция должна отвечать на «является ли субъект владельцем/имеет ли право на этот `resource_id`?».
Проверка владения: `resource.owner_id == subject.id` или членство в `org` с ролью.
Фильтрация выборок: всегда накладывайте `WHERE resource.tenant_id =:tenant AND...` (row-level security).
Для ссылочных операций (ID в пути/теле) — нормализуйте и валидируйте до бизнес-логики.
7) Проектирование RBAC: роли, разрешения, наборы
Разрешения (permissions) — атомарные права: `wallet.read`, `wallet.write`, `payment.refund`.
Роли — именованные наборы разрешений: `admin`, `support.read`, `cashier`, `fraud.analyst`.
Scopes — внешний контракт для клиентов (мэппинг scope→permissions).
- базовые роли + «надстройки» (permission packs),
- ограничения ABAC (страна/регион/тенант),
- «временные повышения» (Just-In-Time access, срок действия).
8) ABAC/контекстные ограничения
Гео/юрисдикция: запрет write из запрещенных стран (санкции/регуляторика).
Время/риск: `risk_score < threshold` для крупных операций.
KYC/лимиты: `kyc_level >= 2` для выводов > X; контроль «остывания» между транзакциями.
«Доверенные устройства»: требовать mTLS для партнеров на опасных маршрутах.
9) ReBAC и граф прав
Полезен для сложных бизнес-структур (группы, команды, бренды, филиалы).
Отношения: `member`, `admin`, `owner`, `viewer`.
Производные права: `viewer` ресурса наследуется из `member` проекта, который принадлежит `org`.
Хранилище графа: БД с матрицей отношений, специализированный сервис (в духе Zanzibar-подхода). Кэшируйте ответы `check(subject, relation, object)`.
10) Кэш решений и производительность
Кэш PDP на уровне PEP (например, в шлюзе) ключом по: `sub|tenant|resource|action|policy_version`.
TTL короткий (секунды-минуты) + инвалидация по событиям: изменение ролей/отношений/тенанта.
Batch-проверки (bulk authz) для списков: уменьшают чарджи PDP.
Измеряйте latency решений; при деградации — graceful-degradation только для read (никогда для write/денежных).
11) Примеры политик
11.1 JWT-клеймы → грубый PEP (псевдо-гейтвей)
yaml
- match: { prefix: "/api/v1/wallets" }
authz:
require:
- claim: "aud"
equals: "wallet-service"
- claim: "scope"
includes_any: ["wallet. read", "wallet. write"]
context:
tenant_from: "claim:tenant"
11.2 OPA/Rego (ABAC + BOLA)
rego package authz
default allow = false
allow {
input. action == "wallet. read"
input. subject. tenant == input. resource. tenant some role role:= input. subject. roles[_]
role == "support. read"
}
allow {
input. action == "payment. refund"
input. subject. tenant == input. resource. tenant input. subject. kyc_level >= 2 input. subject. risk_tier <= 2 input. subject. id == input. resource. owner_id # BOLA
}
11.3 Ограничение по юрисдикции (политика deny-list)
rego deny[msg] {
input. action == "withdraw. create"
input. context. country in {"IR","KP","SY"}
msg:= "Jurisdiction not allowed"
}
11.4 Политика ReBAC (псевдо)
allow(subject, "wallet. write", wallet) --
related(subject, "member", wallet. project) ∧ related(subject, "admin", wallet. org) ∧ wallet. tenant == subject. tenant.
12) Управление политиками и версиями
Версионирование политик (`policy_version`) и канареечка для опасных изменений.
«Сухие прогонки» (dry-run/shadow decisions) — логируем `allow/deny` без воздействия.
Каталог политик и миграций: кто, когда и почему изменил; сопоставление с инцидентами.
Тесты на негативные сценарии (запрещенные кейсы) — обязательны в CI.
13) Наблюдаемость и аудит
Логи решений: `trace_id`, `subject`, `tenant`, `action`, `resource_id`, `result`, `policy_version`, причина отказа.
Метрики: `authz_decision_latency`, `authz_denied_total{action}`, доля BOLA-попыток, кэш-hit-rate.
Дашборды: топ-отказы по действиям/тенантам, тренды после релизов политик.
14) Безопасность и устойчивость
Deny-by-default: отсутствие явного разрешения = запрет.
Fail-closed: при недоступности PDP критичные write → запрет (или деградация к «минимальному набору» строго проверенных ролей).
Локальные «guard-проверки» внутри сервисов для критических инвариантов (например, `tenant`/`owner`).
Минимизация клеймов в JWT; чувствительные атрибуты подгружать через PIP по защищенному каналу.
15) Специфика iGaming/финансов
Роли: `cashier`, `kyc.agent`, `aml.officer`, `fraud.analyst`, `vip.manager`, `risk.admin`.
Ограничения: операции выплаты зависят от `kyc_level`, лимитов ответственных платежей, статуса AML/санкций.
Реестры блокировок: `org/brand/device/payment_instrument` — ABAC-фильтры на write.
Аудит-журналы неизменяемые для действий KYC/AML/выводов; хранение согласно регуляторным срокам.
Партнерские API: mTLS + контрактные `scopes` по маршрутам, гео/ASN-фильтры на периметре.
16) Тестирование и верификация
Negative-матрица: перечислите явные «запретные» кейсы и закрепите тестами.
Fuzz авторизации: подмена `tenant_id`, `owner_id`, обход фильтров при пагинации/сортировке.
Load-тест PDP: проверьте латентность и поведение кэшей при p95/p99.
Релиз политик: dry-run + canary + автосверка с ожидаемыми deny/allow.
Инциденты: реплей запросов на стенде с точной версией политик.
17) Антипаттерны
Полагаться только на `scope` без объектных проверок (BOLA).
Смешивать бизнес-логику и проверки прав в каждом хэндлере без централизованной модели.
Хардкодить роли в UI и доверять клиентским решениям.
Отсутствие `tenant`/`owner` фильтров в запросах к БД (leaky reads).
Нет инвалидации кэш-решений при смене ролей/отношений.
Долгоживущие JWT без отзыва/ротации.
18) Чек-лист prod-готовности
- Определены ресурсы/действия, иерархии и многоарендность.
- Базовая RBAC-матрица + ABAC-ограничители, где нужно — ReBAC.
- PDP/PEP спроектированы; есть локальный кэш решений и его инвалидация.
- Политики версионируются, тесты негативных сценариев в CI.
- BOLA-проверки в каждом write/read на конкретный `resource_id`.
- JWT с минимальными клеймами, коротким `exp`; аудит/отзыв по `jti`.
- Метрики/логи решений, дашборды, алерты по deny/latency.
- Fail-closed для критичных write; fallback-режим документирован.
- Документация для клиентов: `scopes`, коды ошибок (401/403/404/409), примеры.
19) TL;DR
Стройте авторизацию BOLA-first: центральный PDP + кэш решений, RBAC как основа, ABAC для контекста, ReBAC для отношений. Все запросы — в контексте `tenant` и конкретного `resource_id`; deny-by-default, короткие JWT, объектные фильтры в БД. Версионируйте и тестируйте политики, меряйте latency/deny, инциденты воспроизводите реплеем. Для iGaming — отдельные роли (KYC/AML/касса), жесткие ABAC-ограничители и неизменяемый аудит.