# Core `rt-authz` — Permission engine (runtime)

> 07/7/2026 · Repo: **ws_suns** · Đánh giá: **✅ Thiết kế tốt · ⚠ chưa nối hết** · Bản HTML: [rt-authz.html](rt-authz.html) · [Review tổng core](core-review-2026-07-07.md)

## 1. Vai trò
Engine phân quyền runtime: **`rt_role` (grants JSONB: module/group/feature/action + field + rule-predicate + deny)**, resolve thuần có test được, `rt_permission_epoch` invalidate cache, guard `requirePermission` + accessor row-filter.

## 2. Thành phần chính

| Thành phần | Vai trò |
|---|---|
| **rt_role · rt_role_assignment · rt_permission_epoch** | 3 bảng — một nguồn sự thật grants; epoch bump khi sửa quyền |
| **resolve.js** | Merge grants (inherits ≤2 tầng, deny-wins, OR rule) — hàm thuần, unit-test không cần DB |
| **guard.js · predicate.js** | requirePermission (opt-in) + buildWhere an toàn (parametrized, field allowlist) |
| **authorize.js** | Hybrid UNION CP-cache + engine — giai đoạn chuyển tiếp RT-14 |

## 3. Hiện trạng (đọc từ code)
- Thiết kế grants ngang tầm Casbin/OPA thu nhỏ: deny-wins, inherits, custom action, field & row-level đã chừa sẵn cấu trúc
- Predicate → Sequelize where parametrized + allowlist field — chống injection & leak đúng cách
- ⚠ guard/requirePermission và row-filter **chưa gắn vào route nào** (opt-in, chờ RT-16 di cư role)
- ⚠ Data scope: đã có plan 5 phase (~3 MM) — manifest fields/scopeVars + ctxVars + seed role

## 4. Khuyến nghị — tham chiếu hệ phổ biến

| Tham chiếu | Khuyến nghị |
|---|---|
| **Casbin/OPA — single authority** | Chạy plan data-scope P1→P5, pilot module `student`; sau RT-16 gỡ nhánh CP-cache trong authorize.js — một chỗ duy nhất trả lời 'ai được làm gì thấy gì' |
| **Odoo record rules** | Giữ nguyên hướng rule-predicate trong rt_role (đúng mô hình Odoo ir.rule) — chính sách theo trung tâm nằm ở data, không ở manifest |
| **Test bất biến** | resolve.js là hàm thuần — bổ sung bộ test property (deny thắng allow mọi thứ tự, union không mất quyền) trước khi di cư role thật |

## 5. Liên kết trong core
- **cp-rbac** — sync roles từ CP (origin cp/local)
- **rt-host** — seedRoleTemplates + bump epoch lúc install
- **plan data-scope** — lộ trình nối


## Ma trận tác nhân × năng lực

Core không phải module nghiệp vụ — ma trận theo **tác nhân**, kèm cơ chế/quyền gate. R đọc · W thực hiện · A duyệt.

| Năng lực | Cơ chế / quyền gate | SUPER | OWNER/QTHT | DEV | SVC | USER |
|---|---|:--:|:--:|:--:|:--:|:--:|
| CRUD rt_role (grants/rule) | iam.administration.role-admin | — | W | — | — | — |
| Gán role (rt_role_assignment) | iam.administration.role-admin | — | W | — | — | — |
| Bump epoch khi đổi quyền | tự động trong transaction | — | — | — | W | — |
| Resolve + enforce mỗi request | middleware requirePermission/scopeWhere | — | — | — | W | — |
| Sync role từ CP (origin=cp) | Bearer service | — | — | — | W | — |

SUPER = super admin CP · OWNER/QTHT = quản trị WS · DEV = developer/publisher · SVC = service-to-service · USER = người dùng cuối. Mục **(đích)** = theo khuyến nghị P1–P5.
