Skip to content

ADR-0002. RBAC qua Casbin + bảng cạnh PolicyDefinition

TrườngGiá trị
Trạng tháiAccepted
Ngày2026-02-04
Người quyết địnhPhat Nguyen
Thay thế-

Bối cảnh

  • Cần một mô hình RBAC linh hoạt hỗ trợ:
    • Role hệ thống cố định (SUPER_ADMIN, ADMIN, OPERATOR, OWNER, CASHIER, EMPLOYEE, CUSTOMER, GUEST)
    • Role tuỳ chỉnh cho merchant
    • Cấp permission (Role → Permission)
    • Scoping (User có thể là SCOPED_OWNER cho organizer X nhưng EMPLOYEE cho organizer Y)
  • Hai cách tiếp cận tự nhiên:
    1. Ba bảng: User_Role, Role_Permission, cộng thêm scoping riêng
    2. Một bảng cạnh đơn với tính đa hình subject + target

Quyết định

Dùng một bảng cạnh PolicyDefinition duy nhất mà variant chọn một trong tám cạnh. ScopedCasbinAdapter (@venizia/ignis) lọc các row của một principal và emit Casbin line tương ứng cho mô hình scoped-RBAC CASBIN_RBAC_DOMAIN_SCOPED_MODEL.

VariantSubject → TargetCasbinMục đích
grantRole|User → Permissionp"subject này có thể <action> <resource>"
assign_roleUser → Roleg"user có role" (scope theo domain; null ⇒ mọi domain)
join_domainUser → Merchant|Organizerg2membership; cấp năng lượng cho grant ANY_MEMBER
role_inheritsRole → RolegDAG role
domain_inheritsdomain → domaing3Merchant ⊂ Organizer / Branch ⊂ Company
resource_inheritsresource → resourceg4cây obj
action_inheritsaction → actiong5manage ⊃ read/write/execute
merchant_roleRole ↔ Merchant-metadata UI của @nx/core (adapter không đọc)

domain của một grant mang scope - SYSTEM_WIDE, ANY_MEMBER, hoặc <Type>_<id> cụ thể (cũng phủ các child lồng qua g3). Effect là default-DENY với deny tường minh override. Thay đổi từng cạnh có hiệu lực ở lần cache enforcer hết hạn kế tiếp.

Hệ quả

ƯuNhược
Một bảng cho mọi cạnh RBAC; truy vấn đồng nhấtĐa hình - không có FK ở mức DB tới subject/target
Scope domain ANY_MEMBER / <Type>_<id> cho phép một user có role khác nhau theo từng merchant/organizerChi phí đánh giá của Casbin tăng theo số cạnh
Role tuỳ chỉnh của merchant là công dân hạng nhất (không hard-code)Độ trễ kiểm tra permission đòi hỏi cache Redis cho line set theo từng user
Phân cấp resource/action/domain (g3/g4/g5) giữ grant coarse - một grant module cascade xuống mọi subject/operation/child-domainViệc rà soát/so sánh "ai có thể làm X" cần duyệt đồ thị

Phương án đã xem xét

Phương ánƯuNhượcLý do từ chối
Ba bảng (UserRole, RolePermission)Ngữ nghĩa rõ ràngThêm hai migration + đường ghi song songBảo trì kém hơn
Một tập permission jsonb trên mỗi UserĐọc nhanhKhông có lịch sử; không kế thừa nhóm; không thể truy vấn "ai có X"Sai nguyên thuỷ
Spicedb / authz bên ngoàiTiêu chuẩn ngànhChi phí vận hành; độ trễ nhà cung cấpQuá sớm so với quy mô

Tham chiếu

  • core/src/models/schemas/identity/policy-definition/schema.ts
  • @nx/core common/policy-variant.ts (PolicyVariants)
  • services/policy-definition/ - 4 bộ ghi chuyên biệt
  • @venizia/ignis .../enforcers/models/rbac-domain.model.ts (CASBIN_RBAC_DOMAIN_SCOPED_MODEL)

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.