Tóm tắt
Quyền trong identity giờ được kiểm tra theo action (vd identity:user:create), lấy từ policy của các role mà user
đang có, không còn so tên role owner/system_admin. Role system_admin và member được đổi tên thành
"Quản trị hệ thống" và "Thành viên", nên mọi chỗ FE đang so tên role (useIsOrgAdmin, ADMIN_ROLES) sẽ sai:
user system_admin cũ mất giao diện quản trị. FE cần chuyển sang API mới GET /users/me/permissions.
Spec: specs/003-iam-role-policy/.
Chi tiết
- Mỗi route identity gắn 1 action, bảng đầy đủ ở
specs/003-iam-role-policy/contracts/action-route-map.md. Thiếu action → 403common.permission.denied, body có thêmdetails: { action }. - Wework / Workflow / Request cũng kiểm tra action (WEWORK-031, WORKFLOW-024, REQUEST-023): mọi route của 3
service này giờ cần action tương ứng, thiếu thì 403
common.permission.denied. User đã chuyển đổi sang "Thành viên" / "Quản trị hệ thống" vẫn toàn quyền 3 service; user mới phải được gán role có policy tương ứng (vdWeworkMember,RequestUser). Luật nghiệp vụ cũ (người duyệt bước hiện tại, người tạo job...) giữ nguyên. - Role cho nhóm, bỏ quyền theo ứng dụng (IDENTITY-033): gán role cho nhóm, mọi thành viên thừa hưởng. Các API
quyền ứng dụng cũ (
/groups/:groupId/app-permissions/:appId,/users/:userId/app-permissions/:appId,.../effective) đã bị xoá (404). Thêm thành viên vào nhóm có role: người thao tác phải có đủ quyền của các role đó (403identity.iam.escalation_denied), khách không vào được nhóm có role (409identity.iam.guest_cannot_have_roles). - Việc cá nhân không cần action:
/users/me,/users/me/permissions, 2FA, lịch sử đăng nhập, lịch làm việc của mình, thông báo của mình, ủy quyền,/organizations/me,/applications. - Role sau khi chuyển đổi dữ liệu:
owner: toàn quyền (policyAdministratorAccess, action*).- "Quản trị hệ thống" (trước là
system_admin): toàn quyền identity + wework + workflow + request. - "Thành viên" (trước là
member): xem danh bạ, nhóm, lịch làm việc; toàn quyền 3 phân hệ nghiệp vụ. - Tổ chức mới chỉ có role
owner.
- Không còn role mặc định:
POST /userskhông tự gánmembernữa. Chọn role ngay trong form tạo tài khoản (roleIds) hoặc gán sau (POST /users/:id/roles { roleId }). User không có role chỉ làm được việc cá nhân. - Quản lý role/policy (IDENTITY-032): tổ chức tự tạo role từ policy hệ thống hoặc policy tuỳ chỉnh. Không cấp được
quyền mình không có (403
identity.iam.escalation_denied,details.missing), chỉ owner gán/gỡ owner (403identity.iam.owner_only), luôn còn ít nhất 1 owner đang hoạt động (409identity.iam.last_owner). - Claim
rolestrong access token vẫn còn (tên role) nhưng không còn quyết định quyền. - Lỗi domain có thể kèm
details(object) bên cạnhcode/message. Trường này chỉ xuất hiện khi có dữ liệu.
Contract (trước → sau)
| Trước | Sau | |
|---|---|---|
| Endpoint mới | — | GET /users/me/permissions (mọi nhân viên đã đăng nhập; khách → 403) |
| Response mới | — | { data: { roles: RoleRef[], actions: string[] } }, actions đã mở rộng wildcard, sắp xếp |
RoleRef |
— | { id, name, key: 'owner' | null, source: 'direct' | 'group', groupId?, groupName? } |
Response User |
{ ..., roles: string[] } |
{ ..., roles: string[], roleRefs: RoleRef[] } |
POST /users |
tự gán role member |
body thêm roleIds?: string[]; không có thì không gán role nào |
POST /users/:id/roles |
body { roleName }, trả string[] |
body { roleId }, trả RoleRef[] (role trực tiếp) — breaking |
DELETE /users/:id/roles/:roleId |
— | mới, trả RoleRef[]; 404 identity.user_role.not_assigned, 409 identity.iam.last_owner |
GET/POST /roles, GET/PATCH/DELETE /roles/:id |
— | mới (identity:role:*); Role { id, name, description, key, isSystem, policies[], userCount, groupCount } |
GET /iam/actions |
— | mới: danh mục action { code, service, description }[] |
Policy hệ thống (GET /policies?type=system) |
— | 19 policy, gồm 5 policy quản trị người dùng để ghép vào role: UserReadOnly, UserAdmin, UserRoleAdmin, GroupManagement, GuestManagement |
GET/POST /policies, GET/PATCH/DELETE /policies/:id |
— | mới (identity:policy:*); Policy { id, name, description, isSystem, key, actions[], staleActions[], roleCount } |
PATCH /users/:id |
— | khoá owner đang hoạt động cuối cùng → 409 identity.iam.last_owner |
GET/POST /groups/:id/roles, DELETE /groups/:id/roles/:roleId |
— | mới (identity:group:read / identity:group:assign-role), trả RoleRef[] (source: 'group'); role owner → 409 |
PUT/DELETE /groups/:groupId/app-permissions/:appId, PUT/DELETE /users/:userId/app-permissions/:appId, GET .../effective |
có | xoá (404) — breaking |
RoleRef trong roleRefs / /users/me/permissions |
chỉ direct |
thêm role thừa hưởng từ nhóm: source: 'group', groupId, groupName |
| 403 thiếu quyền | { statusCode: 403, message } (Nest mặc định) |
{ statusCode: 403, code: 'common.permission.denied', message, details: { action } } |
| Tên role | owner, system_admin, member |
owner, Quản trị hệ thống, Thành viên (+ role tổ chức tự tạo, từ IDENTITY-032) |
Việc bên nhận cần làm
- FE: thay
useIsOrgAdmin/ADMIN_ROLES/rolesFromAccessTokenbằng kiểm tra action từGET /users/me/permissions(vd trang Audit log cầnidentity:audit-log:read, trang quyền ứng dụng cầnidentity:user:assign-role). - FE: gọi lại
/users/me/permissionssau đăng nhập, sau khi refresh token, và khi tab focus lại (quyền có thể trễ tới ~30 giây sau khi admin đổi). - FE: hiển thị role từ
roleRefs(tên có thể có dấu và khoảng trắng); không so sánh tên role cố định. - FE: xử lý 403
common.permission.deniedbằng thông báo "không có quyền" (có thể đọcdetails.action), ở cả màn hình Wework / Workflow / Request; ẩn nút theo action (vdwework:project:create,request:template:create). - FE: form tạo tài khoản thêm chọn role (
GET /roles→roleIdstrongPOST /users). - FE: đổi gán role sang
POST /users/:id/roles { roleId }, thêm gỡ roleDELETE /users/:id/roles/:roleId. - FE: bỏ trang/luồng quyền theo ứng dụng (
AppPermissionsPage), thay bằng gán role cho nhóm (/groups/:id/roles). - FE: màn hình quản lý role (
/roles) và policy (/policies, danh mụcGET /iam/actions); hiển thịdetails.missingkhi 403identity.iam.escalation_denied; ẩn nút sửa/xoá vớiisSystem: true.
Cách kiểm tra
- Đăng nhập owner →
GET /users/me/permissions→actionschứa đủ 60 action,roles[0].key === 'owner'. - Tạo user mới rồi đăng nhập bằng user đó →
GET /users→ 403common.permission.denied,details.action = 'identity:user:read'. - Owner lấy id role "Thành viên" từ
GET /roles, gán cho user đó (POST /users/:id/roles { roleId }) →GET /userscủa user đó trả 200 (trong ≤ 30 giây với service khác identity). - User chỉ có
IdentityFullAccesstạo role gắnWeworkFullAccess→ 403identity.iam.escalation_denied.
Thảo luận
[FE] 2026-09-25 @NinelXram — acked
Làm trên branch feat/fe-identity-invite-iam: thay useIsOrgAdmin/ADMIN_ROLES bằng GET /users/me/permissions, hiển
thị roleRefs, gán role theo roleId, bỏ trang quyền ứng dụng (API đã xoá).
[FE] 2026-09-25 @NinelXram — applied
Commit e4e9c11 (branch feat/fe-identity-invite-iam). Đủ 3 việc + các breaking (roleId, xoá app-permissions, roleIds,
details trong lỗi). Chưa làm UI quản lý role/policy (/roles, /policies) và gán role cho nhóm — sẽ làm thành task FE riêng.
[FE] 2026-09-25 @NinelXram — applied
Làm nốt phần còn lại trên branch feat/fe-iam-access-management (635757e..6a02533): trang Phân quyền /access (quản lý
role + policy, cây chọn action từ /iam/actions, hiện details.missing khi escalation_denied, ẩn sửa/xoá với
isSystem) và gán role cho nhóm (/groups/:id/roles). Nhóm theo role chưa tra được → note 2026-09-25-fe-role-groups-lookup.