Phase 6.4 - Modular Architecture: - Add lewooogo-brain adapters for LLM providers - Add lewooogo-data dual memory (Redis + PostgreSQL) - Implement consensus engine for multi-agent decisions - Add incident memory service for historical context Phase 9 - Agent Teams (Claude Agent SDK): - Add base agent class with Claude Sonnet 4 integration - Implement action planner, blast radius, and security agents - Add agent API endpoints and proposal workflow - Integrate ADR-009 OpenClaw Agent Teams architecture DevOps & CI/CD: - Add GitHub Actions CI/CD workflows (ci.yaml, cd.yaml) - Add pre-commit hooks and secrets baseline - Add docker-compose for local development - Update Kubernetes network policies Frontend Improvements: - Add auto-healing error boundary component - Update i18n messages for agent features - Enhance dual-state incident card with execution feedback Documentation: - Add 7 ADRs covering MCP, design system, architecture decisions - Update ARCHITECTURE_MEMORY.md with modular design - Add GLOBAL_RULES.md and SOUL.md for project identity Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
12 KiB
12 KiB
AWOOOI RBAC 權限架構設計
版本: v1.0 建立日期: 2026-03-20 負責人: CISO 狀態: Phase 0 草稿
概述
本文件定義 AWOOOI 的角色基礎存取控制 (RBAC) 架構,採用簡化設計原則,解決舊系統「8+ 角色難以理解」的痛點。
設計原則
- 簡單直觀: 4 個核心角色,一目瞭然
- 資源導向: 角色 + 資源級權限,彈性組合
- 最小權限: 預設拒絕,明確授權
- 可審計: 所有權限變更留有記錄
角色定義
四大核心角色
| 角色 | 代碼 | 說明 | 典型用戶 |
|---|---|---|---|
| Owner | owner |
組織擁有者,最高權限 | CEO, 創辦人 |
| Admin | admin |
管理員,可管理用戶與設定 | CTO, CIO, 部門主管 |
| Member | member |
成員,可操作與查看 | 工程師, 運維人員 |
| Viewer | viewer |
觀察者,僅可查看 | 稽核人員, 實習生 |
角色繼承
Owner
└── Admin
└── Member
└── Viewer
- 上層角色繼承下層所有權限
- 權限向下傳遞,不可跨層授權
權限矩陣
系統級權限
| 權限 | Owner | Admin | Member | Viewer |
|---|---|---|---|---|
| 管理組織設定 | ✅ | ❌ | ❌ | ❌ |
| 管理帳單 | ✅ | ❌ | ❌ | ❌ |
| 邀請/移除用戶 | ✅ | ✅ | ❌ | ❌ |
| 變更用戶角色 | ✅ | ✅¹ | ❌ | ❌ |
| 管理 API Keys | ✅ | ✅ | ❌ | ❌ |
| 查看審計日誌 | ✅ | ✅ | ❌ | ❌ |
¹ Admin 只能指派 Member/Viewer,不可指派 Admin/Owner
模組級權限
| 模組 | 動作 | Owner | Admin | Member | Viewer |
|---|---|---|---|---|---|
| Monitor | 查看儀表板 | ✅ | ✅ | ✅ | ✅ |
| 配置告警規則 | ✅ | ✅ | ✅ | ❌ | |
| 確認告警 | ✅ | ✅ | ✅ | ❌ | |
| Deploy | 查看部署 | ✅ | ✅ | ✅ | ✅ |
| 執行部署 | ✅ | ✅ | ✅² | ❌ | |
| 回滾 | ✅ | ✅ | ✅² | ❌ | |
| 批准部署 | ✅ | ✅ | ❌ | ❌ | |
| Security | 查看漏洞 | ✅ | ✅ | ✅ | ✅ |
| 執行掃描 | ✅ | ✅ | ✅ | ❌ | |
| 標記已修復 | ✅ | ✅ | ✅ | ❌ | |
| Tickets | 查看工單 | ✅ | ✅ | ✅ | ✅ |
| 建立工單 | ✅ | ✅ | ✅ | ❌ | |
| 關閉工單 | ✅ | ✅ | ✅³ | ❌ | |
| Settings | 查看設定 | ✅ | ✅ | ✅ | ❌ |
| 修改設定 | ✅ | ✅ | ❌ | ❌ | |
| AI Copilot | 使用 AI | ✅ | ✅ | ✅ | ✅ |
| 執行 AI 建議 | ✅ | ✅ | ✅² | ❌ |
² 需資源級權限 ³ 僅能關閉自己建立的工單
資源級權限
設計理念
角色定義「能做什麼」,資源權限定義「能對什麼做」。
最終權限 = 角色權限 ∩ 資源權限
資源類型
| 資源類型 | 代碼 | 說明 |
|---|---|---|
| 主機 | host |
單一主機 |
| 主機群組 | host_group |
主機群組 |
| 服務 | service |
單一服務 |
| Pipeline | pipeline |
部署流水線 |
| 專案 | project |
整個專案 |
授權範例
{
"user_id": "u-001",
"role": "member",
"resource_permissions": [
{
"resource_type": "host_group",
"resource_id": "hg-web-servers",
"actions": ["deploy", "rollback", "restart"]
},
{
"resource_type": "host_group",
"resource_id": "hg-database",
"actions": ["view"] // 只能看,不能操作
},
{
"resource_type": "pipeline",
"resource_id": "pl-api-deploy",
"actions": ["execute", "view"]
}
]
}
資源權限動作
| 資源類型 | 可用動作 |
|---|---|
| host / host_group | view, deploy, rollback, restart, ssh, manage |
| service | view, start, stop, restart, scale, manage |
| pipeline | view, execute, approve, manage |
| project | view, edit, delete, manage |
Multi-Sig 簽核機制
適用場景
| 場景 | 風險等級 | 簽核要求 |
|---|---|---|
| 生產環境部署 | High | 2 人簽核 (含 1 Admin+) |
| 資料庫 Schema 變更 | Critical | 2 人簽核 (含 CTO) |
| 安全設定變更 | High | 2 人簽核 (含 CISO) |
| 用戶權限提升 | Medium | 1 人簽核 (Admin+) |
| 回滾操作 | Medium | 1 人簽核 (Admin+) |
簽核規則
interface ApprovalPolicy {
action: string;
blastRadius: 'low' | 'medium' | 'high' | 'critical';
requiredSignatures: number;
requiredRoles: Role[];
timeoutMinutes: number;
escalationPolicy?: EscalationPolicy;
}
const policies: ApprovalPolicy[] = [
{
action: 'deploy:production',
blastRadius: 'high',
requiredSignatures: 2,
requiredRoles: ['admin', 'owner'],
timeoutMinutes: 60,
escalationPolicy: {
afterMinutes: 30,
notifyRoles: ['owner'],
},
},
{
action: 'security:config_change',
blastRadius: 'high',
requiredSignatures: 2,
requiredRoles: ['admin'], // 至少一人必須有 CISO tag
timeoutMinutes: 120,
},
];
簽核流程
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 請求發起 │ ─→ │ 等待簽核 │ ─→ │ 執行操作 │
│ (Member) │ │ (Admin+) │ │ (系統) │
└─────────────┘ └─────────────┘ └─────────────┘
│
▼
┌─────────────┐
│ 超時處理 │
│ (自動拒絕) │
└─────────────┘
資料模型
資料庫 Schema
-- 用戶表
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) NOT NULL UNIQUE,
name VARCHAR(255) NOT NULL,
role VARCHAR(50) NOT NULL DEFAULT 'viewer',
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
last_login_at TIMESTAMP WITH TIME ZONE,
is_active BOOLEAN DEFAULT TRUE,
CONSTRAINT valid_role CHECK (role IN ('owner', 'admin', 'member', 'viewer'))
);
-- 資源權限表
CREATE TABLE resource_permissions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
resource_type VARCHAR(50) NOT NULL,
resource_id VARCHAR(255) NOT NULL,
actions TEXT[] NOT NULL,
granted_by UUID REFERENCES users(id),
granted_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
expires_at TIMESTAMP WITH TIME ZONE,
UNIQUE (user_id, resource_type, resource_id)
);
-- 簽核請求表
CREATE TABLE approval_requests (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
action VARCHAR(100) NOT NULL,
requester_id UUID NOT NULL REFERENCES users(id),
target_resource_type VARCHAR(50) NOT NULL,
target_resource_id VARCHAR(255) NOT NULL,
blast_radius VARCHAR(20) NOT NULL,
required_signatures INT NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'pending',
metadata JSONB,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
completed_at TIMESTAMP WITH TIME ZONE,
CONSTRAINT valid_status CHECK (status IN ('pending', 'approved', 'rejected', 'expired', 'cancelled'))
);
-- 簽核記錄表
CREATE TABLE approval_signatures (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
request_id UUID NOT NULL REFERENCES approval_requests(id) ON DELETE CASCADE,
signer_id UUID NOT NULL REFERENCES users(id),
decision VARCHAR(20) NOT NULL,
comment TEXT,
signed_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE (request_id, signer_id),
CONSTRAINT valid_decision CHECK (decision IN ('approve', 'reject'))
);
-- 審計日誌表
CREATE TABLE audit_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
action VARCHAR(100) NOT NULL,
resource_type VARCHAR(50),
resource_id VARCHAR(255),
old_value JSONB,
new_value JSONB,
ip_address INET,
user_agent TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 索引
CREATE INDEX idx_resource_permissions_user ON resource_permissions(user_id);
CREATE INDEX idx_resource_permissions_resource ON resource_permissions(resource_type, resource_id);
CREATE INDEX idx_approval_requests_status ON approval_requests(status, expires_at);
CREATE INDEX idx_audit_logs_user ON audit_logs(user_id, created_at);
CREATE INDEX idx_audit_logs_resource ON audit_logs(resource_type, resource_id, created_at);
API 設計
權限檢查 API
// POST /v1/auth/check-permission
interface CheckPermissionRequest {
userId: string;
action: string;
resourceType: string;
resourceId: string;
}
interface CheckPermissionResponse {
allowed: boolean;
reason?: string;
requiresApproval?: boolean;
approvalPolicy?: ApprovalPolicy;
}
簽核 API
// POST /v1/approvals
interface CreateApprovalRequest {
action: string;
targetResourceType: string;
targetResourceId: string;
metadata?: Record<string, any>;
}
// POST /v1/approvals/{id}/sign
interface SignApprovalRequest {
decision: 'approve' | 'reject';
comment?: string;
}
用戶權限 API
// GET /v1/users/{id}/permissions
interface UserPermissionsResponse {
role: Role;
systemPermissions: string[];
resourcePermissions: ResourcePermission[];
}
// PUT /v1/users/{id}/role
interface UpdateRoleRequest {
role: Role;
}
// POST /v1/users/{id}/resource-permissions
interface GrantResourcePermissionRequest {
resourceType: string;
resourceId: string;
actions: string[];
expiresAt?: string;
}
安全考量
Token 管理
interface JWTPayload {
sub: string; // user_id
role: Role;
permissions: string[]; // 快取常用權限
iat: number;
exp: number;
}
// Token 過期策略
const TOKEN_CONFIG = {
accessTokenTTL: '15m', // 存取 Token
refreshTokenTTL: '7d', // 刷新 Token
rotateRefreshToken: true, // 刷新時輪換
};
敏感操作保護
- 再次驗證: 變更權限前要求重新輸入密碼
- 操作冷卻: 連續拒絕 3 次後鎖定 15 分鐘
- 異常偵測: 異地登入、異常時間操作告警
- Session 管理: 支援踢出其他 Session
審計要求
所有以下操作必須記錄審計日誌:
- 用戶登入/登出
- 角色變更
- 資源權限授予/撤銷
- 簽核操作
- 敏感資源存取
- 設定變更
遷移策略
舊系統角色對應
| 舊角色 | 新角色 | 補充權限 |
|---|---|---|
| Super Admin | Owner | - |
| Admin | Admin | - |
| Manager | Admin | 資源級限制 |
| Developer | Member | 開發資源權限 |
| Operator | Member | 運維資源權限 |
| Auditor | Viewer | 審計日誌存取 |
| Guest | Viewer | - |
| API User | Member | API 專用權限 |
遷移腳本
# scripts/migrate_roles.py
ROLE_MAPPING = {
'super_admin': 'owner',
'admin': 'admin',
'manager': 'admin',
'developer': 'member',
'operator': 'member',
'auditor': 'viewer',
'guest': 'viewer',
'api_user': 'member',
}
def migrate_user_role(old_user):
new_role = ROLE_MAPPING.get(old_user.role, 'viewer')
# 特殊處理: manager 需要資源級權限
if old_user.role == 'manager':
grant_resource_permissions(
user_id=old_user.id,
resource_type='project',
resource_id=old_user.managed_project,
actions=['view', 'edit', 'manage']
)
return new_role
變更記錄
| 日期 | 版本 | 變更 | 作者 |
|---|---|---|---|
| 2026-03-20 | v1.0 | 初版建立 | CISO |
此文件由 CISO 維護,所有權限相關開發必須遵守此架構。