# Built-in `iam` — Định danh & xác thực (workspace)

> 08/7/2026 · **Built-in module — WS runtime** (sẵn lúc boot, không cài qua .ogapp) · Bản HTML: [iam-builtin.html](iam-builtin.html) · [Review tổng core](core-review-2026-07-07.md) · [Quan hệ module](../quan-he-module-2026-07-07.md)
>
> 🎯 **Thiết kế đích sau RT-16 + fix cache (P4 review)** — hiện trạng: roles cũ song song `rt_role`, permissionCache mất sau restart, PAT chưa có scope.

## 1. Vai trò
Danh bạ **user cục bộ workspace**, phiên đăng nhập, **PAT có scope** và UI gán quyền. Sau hợp nhất: iam chỉ giữ **định danh & token** — mọi quyền nằm ở engine `rt_role` (một nguồn sự thật).

## 2. Feature / BO / Action

| Feature | BO chính | Action |
|---|---|---|
| `user` | Người dùng workspace (map từ SSO CP) | view·create·edit·**reset** |
| `session` | Phiên đăng nhập WS (JWT cục bộ) | view·**revoke** |
| `token` | Access Token (PAT) scope + hạn | view·create·delete·**revoke** |
| `role-admin` | Gán vai trò (đọc/ghi engine rt_role) | view·assign·configure |

## 3. Manifest — khai báo permissions

Permission key: `iam.<group>.<feature>.<action>`; `fields`/`scopeVars` theo plan data-scope (manifest v1.1).

```json
{
  "key": "iam",
  "name": "Định danh & Xác thực",
  "version": "2.0.0 (đích sau RT-16)",
  "permissions": [
    {
      "group": "administration",
      "feature": "user",
      "label": "Người dùng",
      "actions": [
        "view",
        "create",
        "edit",
        "reset"
      ]
    },
    {
      "group": "administration",
      "feature": "session",
      "label": "Phiên đăng nhập",
      "actions": [
        "view",
        "revoke"
      ]
    },
    {
      "group": "administration",
      "feature": "token",
      "label": "Access Token",
      "actions": [
        "view",
        "create",
        "delete",
        "revoke"
      ],
      "scopeVars": [
        "current_user_id"
      ]
    },
    {
      "group": "administration",
      "feature": "role-admin",
      "label": "Vai trò & Quyền",
      "actions": [
        "view",
        "assign",
        "configure"
      ]
    }
  ]
}
```

## 4. Dữ liệu chính

### Người dùng
| Trường | Kiểu | Bắt buộc | Ghi chú |
|---|---|---|---|
| Global user id | text | ✔ | Từ CP SSO — không lưu mật khẩu tại WS |
| Username | text | ✔ | Duy nhất trong workspace |
| Email / SĐT | text | — | Hiển thị + liên hệ |
| Trạng thái | bool | ✔ | Hoạt động / khóa |
| Lần đăng nhập cuối | datetime | — |  |

### Access Token (PAT)
| Trường | Kiểu | Bắt buộc | Ghi chú |
|---|---|---|---|
| Tên token | text | ✔ | Mô tả mục đích (vd connector DAT) |
| Token hash | text | ✔ | Chỉ lưu hash — không xem lại được giá trị |
| Scope | list permission | ✔ | Quyền hiệu lực = giao(scope, quyền chủ token) |
| Ngày hết hạn | date | ✔ | Bắt buộc — không có token vĩnh viễn |
| Lần dùng cuối | datetime | — | Phát hiện token bỏ quên |
| Trạng thái | enum | ✔ | hoạt động / đã thu hồi |

### Gán vai trò
| Trường | Kiểu | Bắt buộc | Ghi chú |
|---|---|---|---|
| Người dùng | ref user | ✔ |  |
| Vai trò | ref rt_role | ✔ | Engine là nguồn — iam chỉ là UI |
| Người gán / thời gian | ref·datetime | ✔ | Nhật ký thay đổi quyền |

## 5. Ma trận quyền — vai trò × feature

| Feature | QTHT | GIAM_DOC | QL_DAO_TAO | TUYEN_SINH | GIAO_VU | GIAO_VIEN | KE_TOAN | NHAN_SU |
|---|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| `user` | W | R | — | — | — | — | — | — |
| `session` | W | R | — | — | — | — | — | — |
| `token` | W | R | R² | R² | R² | R² | R² | R² |
| `role-admin` | W·A | R | — | — | — | — | — | — |

¹ chỉ bản ghi mình phụ trách · ² chỉ của chính mình · **W·A** = tạo/sửa + duyệt
Token: mỗi user tự quản token của chính mình (²); QTHT quản toàn bộ.

## 6. Quy tắc nghiệp vụ
1. Quyền **một nguồn duy nhất**: engine rt_role — gỡ bảng roles/user_roles cũ sau di cư RT-16
2. PAT bắt buộc scope + hạn; không vượt quyền chủ token
3. Quyền nạp theo **epoch** — restart không mất, đổi quyền hiệu lực ngay
4. Mọi gán/thu quyền, tạo/thu token → ghi nhật ký

## 7. Liên kết chéo
- **cp-identity** — SSO đổ identity, membership
- **rt-authz** — nguồn quyền duy nhất
- **hrm** — Employee.user_id ↔ user
- **portal** — học viên self-scope qua user_id

## 8. Câu hỏi mở
- Lộ trình gỡ bảng roles cũ sau RT-16?
- PAT có cần cho connector DAT gọi vào ở GĐ1?
