Authorization Models concept page covering ACL, RBAC, ABAC, ReBAC (Google Zanzibar), Policy-as-Code (OPA Rego, Cedar), tenancy isolation, Postgres RLS, with tool comparison (SpiceDB, Permify, OpenFGA, Cerbos, Oso, Casbin). Includes 5 scenarios: RBAC role check, ABAC context-aware policy with time/location/MFA, ReBAC graph traversal Google Drive style, Postgres RLS tenant isolation, and tools comparison decision tree. Two ADRs on RBAC vs ABAC vs ReBAC choice and app-authz vs RLS defense in depth.
AuthZ — это функция can(user, action, resource) -> bool. Модели authz — разные способы её организовать: ACL (список per resource), RBAC (через роли), ABAC (через атрибуты + context), ReBAC (через граф связей). Выбор модели — long-term архитектурное решение: миграция между ними болезненная, и неверный выбор либо overengineering, либо невозможно выразить требования продукта.
«Authz = decision point + enforcement point. PDP (Policy Decision Point) отвечает allow/deny. PEP (Policy Enforcement Point) ловит request и спрашивает PDP. Где живёт логика — определяется моделью. RBAC хранит её в таблице ролей, ABAC — в полиси-движке, ReBAC — в графе relations.»
Четыре основных модели и их «когда»:
[user:perms] на каждый ресурс. Подходит для файлов (POSIX, NTFS, S3 bucket policy). Не масштабируется на сложные сценарии (N×M storage).user.dept == resource.dept AND time IN business_hours. Fine-grained, учитывает context (время, локацию, MFA recency). Нужен policy engine (OPA Rego, Cedar, Cerbos).doc:42#viewer@team:eng#member. То, что нужно для Drive, Notion, GitHub: shared folders, group inheritance, transitive permissions.Шесть групп показывают весь ландшафт authz:
user_roles таблицу) → permissions, middleware requireRole("editor") || 403.SET LOCAL app.current_tenant, policy auto-filters любой SELECT.RBAC-flow: alice (editor) делает POST /posts/789/publish. Middleware смотрит user_roles[42] → editor, затем role_permissions[editor] → [post:read, post:write, post:publish], проверяет наличие нужного permission, форвардит request. Простая, аудитабильная, масштабируемая модель — добавление новой роли = два INSERT. Anti-pattern: проверка только в UI через JWT claim — обходится через DevTools за 5 секунд.
ABAC через OPA: dr_bob (cardiology) запрашивает medical record. PDP загружает healthcare.rego, fetches user attrs (dept, clearance), context (time=14
opa eval --explain=full).
ReBAC (Zanzibar): alice запрашивает doc:42, она НЕ direct viewer. SpiceDB обходит граф: нет direct viewer alice → смотрит schema (viewer = ... or parent->viewer) → находит document:42#parent@folder:eng-projects → folder#viewer@team:eng#member → team:eng#member@user:alice → ALLOW (transitive). Zookies гарантируют consistency: после revoke alice сразу не видит документ. Это работает только в графе — RBAC бы потребовал N×M строк permission per user per doc.
Postgres RLS как defense-in-depth: middleware делает BEGIN; SET LOCAL app.current_tenant = '<uuid>'. Разработчик пишет SELECT * FROM orders БЕЗ WHERE tenant_id (забыл, новый endpoint, ad-hoc query). RLS policy USING (tenant_id = current_setting('app.current_tenant')::uuid) автоматически фильтрует — cross-tenant leak предотвращён на уровне БД. Overhead ~5-15% query latency, требует индекс на tenant_id. Не заменяет app-level authz — RLS делает coarse-grained tenant boundary, app делает fine-grained user permissions.
Decision tree по продукту: (1) internal B2B SaaS с ролями — RBAC через Cerbos/Casbin/две таблицы; (2) document/file sharing с group inheritance — ReBAC через SpiceDB/OpenFGA/Permify; (3) compliance с context — ABAC через OPA/Cedar; (4) K8s admission — OPA (industry standard); (5) AWS-native — Cedar (Verified Permissions, formal verification на Lean); (6) embedded в монолит — Oso/Casbin; (7) multi-tenant SaaS — любое из выше + Postgres RLS для tenant boundary. Match tool to model.
ADR-001: RBAC vs ABAC vs ReBAC — когда что выбирать.
RBAC решает 90% B2B-кейсов: предсказуемая иерархия ролей (admin/editor/viewer), легко аудитить, легко администрировать через org chart. Слабость: роль = bundle, не работает для «owner of THIS document». ReBAC (Zanzibar) — для collaboration products (Drive-analog, Notion-analog): shared folders с group inheritance, transitive permissions, sharing с external users. ABAC — для compliance-heavy случаев (government, healthcare, finance) где нужен context (time, location, classification level). Решение: начинать с RBAC и мигрировать на ReBAC когда appears request «share with external», «transitive group membership», «owner of THIS resource». Не выбирать ReBAC заранее «на всякий случай» — overhead не окупится. Реальные продукты комбинируют: Slack = RBAC (workspace) + ReBAC (channels) + ABAC (guest restrictions). AWS IAM = RBAC (managed policies) + ABAC (conditions). GitHub = RBAC (repo roles) + ReBAC (team inheritance).
ADR-002: app-level authz vs Postgres RLS.
Multi-tenant SaaS: tenant isolation полагается ТОЛЬКО на app-level WHERE tenant_id = ? — самая частая ошибка (GitLab 2017, Mongo Atlas misconfig 2019). Один забытый WHERE в 5000-строчном репозитории = data leak. Решение: RLS как нижний слой defense-in-depth ВСЕГДА, но НЕ как единственный. (1) каждая tenant-scoped таблица: tenant_id NOT NULL + index; (2) RLS policy USING (tenant_id = current_setting('app.current_tenant')::uuid); (3) middleware: BEGIN; SET LOCAL app.current_tenant = '<id>'; (4) background jobs — bypass role с явным WHERE; (5) unit tests на cross-tenant SELECT возвращает 0 rows; (6) app authz (RBAC/ReBAC) поверх для intra-tenant permissions. Pgbouncer transaction mode требует SET LOCAL внутри транзакции — SET утечёт между requests. Supabase сделал этот pattern mainstream для frontend-first apps.
aws:CurrentTime, aws:SourceIp, aws:MultiFactorAuthAge). Cedar (2023) — formal verification policies.Role, ClusterRole, RoleBinding) + OPA Gatekeeper для admission control (ABAC policies на pod specs).if (user.role !== 'admin') hideButton(), API не проверяет. Bypass через DevTools/curl за 5 секунд.req.body.userId вместо req.user.id из session. OWASP API1./users без filter возвращает всех. Optus 2022 — 10M Australians leaked через unauthenticated API endpoint (OWASP API5).user_roles + role_permissions таблицы.