All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 46s
92 lines
4.5 KiB
Markdown
92 lines
4.5 KiB
Markdown
---
|
||
trigger: always_on
|
||
---
|
||
|
||
# 多租戶與權限架構實作規範 (RBAC Rules)
|
||
|
||
本文件定義 Star Cloud 系統的多租戶與權限(RBAC)實作標準,開發者必須嚴格遵守以下準則,以確保資料隔離與安全性。
|
||
|
||
---
|
||
|
||
## 1. 資料隔離核心 (Data Isolation)
|
||
|
||
### 1.1 租戶欄位 (`company_id`)
|
||
任何屬於租戶資源的資料表(如 `users`, `machines`, `transactions` 等),**必須**包含 `company_id` 欄位。
|
||
- `company_id = null`:系統管理員(SaaS 平台營運商)。
|
||
- `company_id = {ID}`:特定租戶。
|
||
|
||
### 1.2 自動過濾 (Global Scopes)
|
||
- 資源 Model 必須套用 `TenantScoped` Trait。
|
||
- 當非系統管理員登入時,所有 Eloquent 查詢必須自動加上 `where('company_id', auth()->user()->company_id)`。
|
||
- **嚴禁**在 Controller 手動撰寫重複的過濾邏輯,除非是複雜的 Raw SQL。
|
||
|
||
### 1.3 寫入安全
|
||
- 建立新資源時,必須在背景強制綁定 `company_id`,禁止由前端傳參決定。
|
||
- 範例:`$model->company_id = Auth::user()->company_id;`
|
||
|
||
### 1.4 角色清單隔離 (Role List Isolation)
|
||
- 租戶管理員 (Tenant Admin) 只能管理隸屬於其公司下的角色。
|
||
- **嚴禁使用**包含 `NULL` 的 `forCompany` 廣義作用域來展示管理清單。
|
||
- 查詢時必須嚴格使用 `where('company_id', auth()->user()->company_id)` 隔離系統 Super Admin 或 角色範本。
|
||
|
||
---
|
||
|
||
## 2. 權限開發規範 (spatie/laravel-permission)
|
||
|
||
### 2.1 租戶感知角色 (Tenant-Aware Roles)
|
||
- `roles` 資料表已擴充 `company_id` 欄位。
|
||
- 撈取角色清單供指派時,必須過濾 `company_id` 或為 null 的系統預設角色。
|
||
|
||
### 2.2 權限命名
|
||
- 權限名稱應遵循 `[module].[action]` 格式(例如 `machine.view`, `machine.edit`)。
|
||
- 所有租戶共用相同的權限定義。
|
||
|
||
### 2.3 權限遞迴約束 (Privilege Delegation Constraint)
|
||
為防止權限提升 (Privilege Escalation):
|
||
- **權限子集驗證**:管理員僅能指派其**自身持有**之權限給其他角色或帳號。
|
||
- **Controller 實作**:在 `store` 或 `update` 時,必須比對傳入的權限集合是否為操作者 `getPermissionNames()` 的子集。
|
||
- **UI 過濾**:權限分配介面應基於當前使用者權限清單進行動態過濾展示。
|
||
|
||
---
|
||
|
||
## 3. 介面安全 (UI/Blade)
|
||
|
||
### 3.1 身份判定 Helper
|
||
使用以下方法進行區分:
|
||
- `$user->isSystemAdmin()`: 判斷是否為平台營運人員。
|
||
- `$user->isTenant()`: 判斷是否為租戶帳號。
|
||
|
||
### 3.2 Blade 指令
|
||
- 涉及全站管理或跨租戶功能,必須使用 `@if(auth()->user()->isSystemAdmin())` 包裹。
|
||
- 確保租戶登入時,不會在 Sidebar 或選單看到不屬於其權限範圍的項目。
|
||
|
||
---
|
||
|
||
## 4. API 安全
|
||
- 所有的 API Route 應預設包含 `CheckTenantAccess` Middleware。
|
||
- 嚴禁透過 URL 修改 ID 存取不屬於該租戶的資料,必須依賴 `company_id` 的 Scope 過濾。
|
||
|
||
---
|
||
|
||
## 5. 客戶初次建立與角色初始化 (Role Provisioning)
|
||
|
||
### 5.1 初始角色建立
|
||
當系統管理員為新客戶(該租戶尚未有任何角色)建立第一個帳號時,應遵循以下邏輯:
|
||
1. **選取範本**:從系統預設的「全域角色範本」(`company_id = null` 且 `is_system = 1`)中選取一個作為基礎,但必須排除「超級管理員 (`super-admin`)」。
|
||
2. **自動克隆**:系統會將該範本的權限內容複製一份至該租戶下。
|
||
3. **統一命名**:克隆後的角色名稱在該租戶公司內應統一命名為**「管理員」**。
|
||
4. **帳號綁定**:該新客戶帳號將被指派至此新建立的「管理員」角色。
|
||
|
||
### 5.2 角色權限維護
|
||
- 初始建立後,該租戶的「管理員」角色即成為獨立資源,可由具有權限的帳號進行細部調整。
|
||
|
||
### 5.3 機台授權原則 (Machine Authorization) [CRITICAL]
|
||
- **以帳號為準**:機台授權是基於「帳號 (User)」而非「角色 (Role)」。
|
||
- **授權層級**:
|
||
1. **系統管理員 (isSystemAdmin = true)**:具備全系統所有機台之完整權限。
|
||
2. **租戶/公司帳號 (含管理員)**:僅能存取由「系統管理員」明確授權給該帳號的機台(透過 `machine_user` 關聯)。
|
||
3. **子帳號**:僅能存取由其「公司管理員」所授權的機台子集。
|
||
- **實作要求**:
|
||
- `Machine` Model 的全域過濾器**不得**對「管理員 (Tenant Admin)」角色進行例外排除。
|
||
- 所有的機台存取必須嚴格比對 `machine_user` 表,除非操作者為「系統管理員 (Super Admin)」。
|