# KẾ HOẠCH 14 — RBAC & Quản trị đa dự án (Multi-tenant governance)
> Status 2026-07-06: **� core implemented + tested (harness-owned).**
> RBAC decision engine đã dời/đặt trong harness: `packages/casan-harness/scripts/bash/rbac-check.py`
> (role×resource:action, scope org/project, deny-by-default fail-closed, tenant
> isolation, sensitive-settings-write chỉ org-admin, SoD chống tự duyệt). Test
> `packages/casan-harness/tests/phase-rbac-tests.sh` **10/0 (WSL)**, nối CI (`phase-rbac`).
> Còn lại: ánh xạ IdP claim → role thật (nối 07-C4), enforcement point trong web app
> Control Plane (Plan-13), audit mọi quyết định RBAC vào H5, quản lý role qua UI.
>
> Nhãn trạng thái: xem legend ở `CASAN_BACKLOG_STATUS.md`.
> Phụ thuộc: **07 C4** (IdP/OIDC — nguồn danh tính) · **13** (Control Plane tiêu thụ
> RBAC) · **06** (đa dự án — phạm vi tenant). **Chặn mềm** phần quản lý của 13.
## 1. Bối cảnh
- **Đã có:** IdP/OIDC JWT (RS256) chứng minh `sub`/`role`/`exp` + bind request
(Plan-07 C4); `reviewers.registry`; `project-registry.json` (project + domain).
- **Chưa có:** ma trận quyền (role × resource × action), phạm vi tenant (org →
project), kế thừa quyền, và điểm thực thi (enforcement point) thống nhất.
## 2. Nguyên tắc
- **Least privilege mặc định:** không role → không quyền; quyền phải cấp tường minh.
- **Deny-by-default + fail-closed:** thiếu/không rõ quyền → DENY, không "cho tạm".
- **Tenant isolation:** dữ liệu/domain/telemetry của dự án A không lộ sang dự án B.
- **Separation of Duties (SoD):** người đề xuất ≠ người duyệt (kế thừa C4).
- **Mọi quyết định RBAC ghi audit (H5):** ai, tài nguyên nào, cho/từ chối, vì sao.
- **Nguồn danh tính là IdP (C4), không tự chế:** RBAC chỉ ánh xạ identity→quyền.
## 3. Mô hình quyền (đề xuất)
```mermaid
flowchart LR
ORG["Org (tenant gốc)"] --> PROJ["Project (OKR, dự án 2…)"]
PROJ --> RES["Resource: settings / telemetry / approval / kill-switch / domain-data"]
ROLE["Role: org-admin · project-admin · approver · operator · viewer · auditor"] --> PERM{"Permission
role × resource × action"}
RES --> PERM
PERM --> ENF["Enforcement point
(Control-Plane API + harness gate)"]
ENF --> AUDIT["H5 audit"]
style ENF fill:#d0e8ff,stroke:#2c3e91,stroke-width:2px
style AUDIT fill:#fff3cd,stroke:#8a6d3b,stroke-width:2px
```
### 3.1 Role gợi ý
| Role | Xem | Đổi setting | Duyệt | Kill-switch | Phạm vi |
|---|:--:|:--:|:--:|:--:|---|
| org-admin | ✓ | ✓ | ✓ | ✓ | toàn org |
| project-admin | ✓ | ✓ (không nhạy cảm) | – | project scope | 1 project |
| approver | ✓ | – | ✓ | – | được gán |
| operator | ✓ | – | – | engage (báo cáo) | 1 project |
| viewer | ✓ | – | – | – | được gán |
| auditor | ✓ (+audit log) | – | – | – | toàn org (read) |
## 4. Tasks
| Task | Việc | File/Đối tượng | Verify | Done |
|---|---|---|---|---|
| 14.1 | Định nghĩa schema `rbac-policy.yaml` (role × resource × action + scope) | mới `config/rbac-policy.yaml` | policy load hợp lệ | schema chốt |
| 14.2 | Ánh xạ IdP claim (`role`, `groups`) → role RBAC | nối Plan-07 C4 | JWT role → RBAC role đúng | mapping chạy |
| 14.3 | Enforcement point thống nhất: mọi API/gate gọi `rbac-check` trước hành động | mới `rbac-check.sh`/service | thiếu quyền → DENY fail-closed | 1 điểm thực thi |
| 14.4 | Tenant isolation: telemetry/domain-data theo project scope | Control-Plane API | user project A không đọc B | cách ly tenant |
| 14.5 | SoD: người đề xuất ≠ người duyệt (kế thừa C4) | governance-check | tự duyệt đề xuất của mình → DENY | SoD giữ |
| 14.6 | Ghi audit mọi quyết định RBAC (allow/deny + reason) | H5 audit | deny có bản ghi truy vết | audit đầy đủ |
| 14.7 | Quản lý role/gán quyền qua Control Plane (chỉ org-admin) | Plan-13 UI | non-admin đổi role → DENY | quản trị quyền |
## 5. Red-team / test
| Test | Kỳ vọng |
|---|---|
| `adv-viewer-writes-setting` | DENY |
| `adv-cross-tenant-read` (project A đọc B) | DENY |
| `adv-self-approve` (đề xuất tự duyệt) | DENY (SoD) |
| `adv-missing-role-defaults-allow` (thiếu role vẫn cho) | DENY (deny-by-default) |
| `adv-forged-role-claim` (JWT role giả) | DENY (verify chữ ký IdP — C4) |
| `benign-role-grant-roundtrip` (org-admin gán role hợp lệ) | PASS + audit |
## 6. Tiêu chí HOÀN THÀNH
- [ ] `rbac-policy.yaml` + enforcement point thống nhất, deny-by-default fail-closed.
- [ ] IdP claim → RBAC role; role giả bị chặn (verify qua C4).
- [ ] Tenant isolation: không rò dữ liệu chéo dự án.
- [ ] SoD giữ; mọi quyết định RBAC có audit H5.
- [ ] Control Plane (Plan-13) dùng RBAC cho toàn bộ hành động quản lý.
- [ ] Red-team mục 5 xanh; core harness 218/0 không tụt.
## 7. Ghi chú trung thực
- **[mới]** — hiện chỉ có approval-identity (C4), chưa có mô hình quyền đầy đủ.
- RBAC không thay IdP; nó ánh xạ identity (đã verify) → quyền, thực thi fail-closed.
---
_Liên quan: `CASAN_PLAN_07_PRODUCTION_HARDENING.md` (C4 IdP/OIDC — nguồn danh tính) · `CASAN_PLAN_13_CONTROL_PLANE.md` (tiêu thụ RBAC) · `CASAN_PLAN_06_ONBOARD.md` (đa dự án → phạm vi tenant)._