# VBase 权限系统文档 ## 1. 权限模型概述 VBase 是一个类似 **Supabase** 的 BaaS 平台,为 2C(个人开发者)和 2B(团队/企业)用户提供后端资源托管服务。权限系统采用 **RBAC + ABAC** 混合模型,支持三级权限体系: - **平台级 (Platform)**: 用户管理自己的账号和数据 - **项目级 (Project)**: 项目内的成员管理和资源控制 - **资源级 (Resource)**: 具体资源的读写操作 --- ## 2. 核心概念 ### 2.1 权限层级 ``` ┌─────────────────────────────────────────────────────────────┐ │ 平台级权限 (Platform) │ │ - 管理自己的用户信息 │ │ - 创建新项目 │ │ - 管理第三方账号绑定 │ │ - 访问被邀请的项目 │ └─────────────────────────────────────────────────────────────┘ │ ▼ (进入项目上下文) ┌─────────────────────────────────────────────────────────────┐ │ 项目级权限 (Project) │ │ - 项目设置管理 (所有者/管理员) │ │ - 成员邀请和管理 │ │ - 资源创建和管理 │ │ - 查看项目统计信息 │ └─────────────────────────────────────────────────────────────┘ │ ▼ (访问具体资源) ┌─────────────────────────────────────────────────────────────┐ │ 资源级权限 (Resource) │ │ - 数据库读写操作 │ │ - 存储文件上传下载 │ │ - 函数调用和管理 │ │ - API 密钥管理 │ └─────────────────────────────────────────────────────────────┘ ``` ### 2.2 实体关系 ``` User (平台用户) ├── Platform Permission (平台级权限) │ └── 默认: 管理自己的数据 │ └── OrgMember (项目成员关系) ├── Org/Project (项目) │ ├── Resource (项目资源) │ └── Resource (项目资源) │ └── Role (项目角色) └── Policy (策略) ``` ### 2.3 使用场景示例 **场景1: 个人开发者 (2C)** ``` 小明 (User) ├── 个人信息管理 (平台级) ├── 我的项目A (Org) │ ├── 数据库资源 │ └── 存储资源 └── 我的项目B (Org) └── ... ``` **场景2: 团队协作 (2B)** ``` CEO (User) ├── 拥有的项目: WebApp, MobileApp └── 角色: 所有者 (Owner) CTO (User) ├── 参与的项目: WebApp (Admin), MobileApp (Developer) └── 角色: 管理员/开发者 员工A (User) ├── 参与的项目: WebApp (Developer) └── 角色: 开发者 ``` ### 2.2 策略 (Policy) 策略是权限控制的最小单元,定义了对特定资源的操作权限。 **策略结构:** ```go type Policy struct { Code string // 策略编码,唯一标识 Name string // 策略名称 Description string // 策略描述 Resource string // 资源类型: user/org/member/policy/role/* Action string // 操作: create/read/update/delete/* Effect string // 效果: allow/deny Condition string // 条件表达式 Priority int // 优先级: 数字越大优先级越高 IsSystem bool // 是否系统策略 } ``` **策略分类:** **平台级策略** (无 org_id 上下文) | 策略 | 资源 | 操作 | 效果 | 条件 | 说明 | |------|------|------|------|------|------| | user:read:own | user | read | allow | owner | 读取自己的用户信息 | | user:update:own | user | update | allow | owner | 更新自己的用户信息 | | binding:manage | binding | * | allow | - | 管理第三方账号绑定 | | org:create | org | create | allow | - | 创建新项目 | **项目级策略** (需要 org_id 上下文) | 策略 | 资源 | 操作 | 效果 | 条件 | 说明 | |------|------|------|------|------|------| | org:admin | * | * | allow | org_owner | 项目所有者拥有所有权限 | | org:update | org | update | allow | admin | 更新项目设置 | | member:read | member | read | allow | member | 读取项目成员列表 | | member:manage | member | * | allow | admin | 管理项目成员 | | resource:create | resource | create | allow | developer | 创建项目资源 | | resource:delete | resource | delete | allow | admin | 删除项目资源 | ### 2.4 角色 (Role) 角色是一组策略的集合,在项目级别定义。 **角色结构:** ```go type Role struct { ID string // 角色ID OrgID string // 所属项目 Name string // 角色名称 Description string // 角色描述 PolicyIDs []string // 关联的策略ID列表 Scope string // 作用域: project/resource IsSystem bool // 是否系统角色 } ``` **系统内置角色:** | 角色 | 适用对象 | 权限范围 | 说明 | |------|----------|----------|------| | **owner** | 项目所有者 | 全部权限 | 项目的创建者,拥有所有权限,可删除项目 | | **admin** | 管理员 | 项目级管理 | 管理项目设置、成员、资源,但不能删除项目 | | **developer** | 开发者 | 资源级操作 | 创建和管理资源(数据库、存储、函数) | | **viewer** | 访客 | 只读访问 | 只能查看项目和资源信息,不能修改 | ### 2.4 条件 (Condition) 条件用于实现 ABAC,支持以下类型: | 条件 | 说明 | 使用场景 | |------|------|----------| | "" | 无条件,始终匹配 | 通用权限 | | "owner" | 资源所有者 | 只能操作自己的数据 | | "org_member" | 项目成员 | 项目内数据访问 | | "org_owner" | 项目所有者 | 项目所有者权限判断 | --- ## 3. 权限检查流程 ### 3.1 权限检查流程 根据是否有项目上下文 (`org_id`),权限检查分为两种方式: #### 流程 A: 平台级权限检查 (无项目上下文) ``` ┌─────────────────────────────┐ │ 请求进入 (无 org_id) │ │ user, resource, action │ └────────────┬────────────────┘ │ ▼ ┌─────────────────────────────┐ 命中 ┌─────────────────┐ │ 检查缓存 │────────────→│ 返回缓存结果 │ └────────────┬────────────────┘ └─────────────────┘ │ 未命中 ▼ ┌─────────────────────────────┐ │ 1. 检查是否是资源所有者 │ │ owner_id == user_id │ └────────────┬────────────────┘ │ 是 ▼ ┌──────────┐ │ 返回 Allow│ └──────────┘ │ 否 ▼ ┌─────────────────────────────┐ │ 2. 加载平台级默认策略 │ │ personal:* 策略 │ └────────────┬────────────────┘ │ ▼ ┌─────────────────────────────┐ │ 3. 评估策略 (Deny优先) │ └────────────┬────────────────┘ │ ┌─────┴─────┐ ▼ ▼ ┌───────┐ ┌───────┐ │ Deny │ │ Allow │ └───────┘ └───────┘ ``` #### 流程 B: 项目级权限检查 (有项目上下文) ``` ┌─────────────────────────────┐ │ 请求进入 (有 org_id) │ │ user, org_id, resource... │ └────────────┬────────────────┘ │ ▼ ┌─────────────────────────────┐ 命中 ┌─────────────────┐ │ 检查缓存 │────────────→│ 返回缓存结果 │ └────────────┬────────────────┘ └─────────────────┘ │ 未命中 ▼ ┌─────────────────────────────┐ │ 1. 检查是否是项目所有者 │ │ org.owner_id == user_id │────────┐ └────────────┬────────────────┘ │ │ 是 │ ▼ │ ┌──────────┐ │ │ 返回 Allow│───────────────────┘ └──────────┘ │ 否 ▼ ┌─────────────────────────────┐ │ 2. 获取用户在项目的角色 │ │ 从 OrgMember 表查询 │ └────────────┬────────────────┘ │ ▼ ┌─────────────────────────────┐ │ 3. 获取角色关联的策略 │ └────────────┬────────────────┘ │ ▼ ┌─────────────────────────────┐ │ 4. 评估策略 (Deny优先) │ │ Deny策略 → Allow策略 │ └────────────┬────────────────┘ │ ┌─────┴─────┐ ▼ ▼ ┌───────┐ ┌───────┐ │ Deny │ │ Allow │ └───────┘ └───────┘ ``` ### 3.2 决策规则 1. **Deny 优先**: 如果匹配到 Deny 策略,直接拒绝 2. **显式 Allow**: 必须匹配到 Allow 策略才允许 3. **默认拒绝**: 未匹配到任何策略时拒绝 4. **优先级**: 高优先级策略优先匹配 --- ## 4. 使用指南 ### 4.1 平台级权限检查 **场景**:用户管理自己的账号、创建新项目 ```go // 检查用户是否可以更新自己的信息 // orgID 传空字符串,表示平台级检查 result, err := checker.Check(userID, "", "user", "update", map[string]any{ "owner_id": userID, // 传入自己的ID }) // 结果:允许(满足 owner 条件) // 检查用户是否可以创建新项目 result, err := checker.Check(userID, "", "org", "create", nil) // 结果:允许(平台级默认策略允许创建项目) // 检查用户是否可以更新其他用户信息 result, err := checker.Check(userID, "", "user", "update", map[string]any{ "owner_id": otherUserID, // 传入他人ID }) // 结果:拒绝(不满足 owner 条件) ``` ### 4.2 项目级权限检查 **场景**:在项目内操作资源 ```go // 检查用户在项目内是否有管理员权限 result, err := checker.Check(userID, "project-123", "member", "invite", nil) // 结果取决于用户在 project-123 中的角色 // 项目所有者检查(快速路径) // 如果 userID == org.OwnerID,直接返回允许 // 普通成员检查 // 1. 查询 OrgMember 获取角色 // 2. 查询 Role 获取策略 // 3. 评估策略 ``` ### 4.3 完整示例:更新用户信息 ```go func UpdateUser(x *vigo.X, req *UpdateRequest) error { userID := middleware.CurrentUser(x) targetUserID := req.UserID checker := service.NewPermissionChecker() // 场景1: 更新自己的信息(平台级) if targetUserID == userID { result, err := checker.Check(userID, "", "user", "update", map[string]any{ "owner_id": userID, }) if err != nil || !result.Allowed { return vigo.ErrForbidden.WithString(result.Reason) } // 执行更新... return nil } // 场景2: 管理员更新其他用户信息(需要平台级管理员权限) result, err := checker.Check(userID, "", "user", "update", nil) if err != nil || !result.Allowed { return vigo.ErrForbidden.WithString("only admin can update other users") } // 执行更新... return nil } ``` ### 4.4 完整示例:项目内操作 ```go func DeleteProjectResource(x *vigo.X, req *DeleteResourceRequest) error { userID := middleware.CurrentUser(x) orgID := middleware.CurrentOrg(x) // 从请求头 X-Org-ID 获取 if orgID == "" { return vigo.ErrArgInvalid.WithString("org_id required") } checker := service.NewPermissionChecker() // 检查用户在项目内是否有删除资源的权限 result, err := checker.Check(userID, orgID, "resource", "delete", map[string]any{ "resource_id": req.ResourceID, }) if err != nil || !result.Allowed { return vigo.ErrForbidden.WithString(result.Reason) } // 执行删除... return nil } ``` ### 4.5 创建自定义策略 ```go // 项目级策略(需要关联到具体项目) policy := &model.Policy{ Code: "custom:db:admin", Name: "数据库管理员", Description: "管理项目数据库", Resource: "database", Action: "*", // 所有操作 Effect: model.EffectAllow, Condition: "", // 无条件限制 Scope: "project", // 项目级策略 OrgID: "project-123", // 所属项目 } model.DB.Create(policy) // 将策略添加到角色 role := &model.Role{ OrgID: "project-123", Name: "DBAdmin", PolicyIDs: "custom:db:admin", } model.DB.Create(role) // 分配角色给用户 member := &model.OrgMember{ OrgID: "project-123", UserID: "user-456", RoleIDs: role.ID, } model.DB.Create(member) ``` --- ## 5. 系统内置策略 ### 5.1 用户相关 ```go // 读取自己 SysPolicyUserReadOwn = "sys:user:read:own" Resource: "user" Action: "read" Condition: "owner" // 更新自己 SysPolicyUserUpdateOwn = "sys:user:update:own" Resource: "user" Action: "update" Condition: "owner" // 删除自己 SysPolicyUserDeleteOwn = "sys:user:delete:own" Resource: "user" Action: "delete" Condition: "owner" ``` ### 5.2 组织相关 ```go // 组织管理员 SysPolicyOrgAdmin = "sys:org:admin" Resource: "*" Action: "*" Condition: "org_owner" Priority: 100 // 读取组织 SysPolicyOrgRead = "sys:org:read" Resource: "org" Action: "read" Condition: "org_member" ``` ### 5.3 成员相关 ```go // 读取成员 SysPolicyMemberRead = "sys:member:read" Resource: "member" Action: "read" Condition: "org_member" // 管理成员 SysPolicyMemberManage = "sys:member:manage" Resource: "member" Action: "*" Condition: "" ``` ### 5.4 角色策略相关 ```go // 读取角色 SysPolicyRoleRead = "sys:role:read" Resource: "role" Action: "read" Condition: "org_member" // 管理角色 SysPolicyRoleManage = "sys:role:manage" Resource: "role" Action: "*" Condition: "admin" // 读取策略 SysPolicyPolicyRead = "sys:policy:read" Resource: "policy" Action: "read" Condition: "org_member" // 管理策略 SysPolicyPolicyManage = "sys:policy:manage" Resource: "policy" Action: "*" Condition: "admin" ``` ### 5.5 资源级策略(BaaS 核心资源) **数据库资源 (database)** ```go // 查询数据库 SysPolicyDBRead = "sys:db:read" Resource: "database" Action: "read" Condition: "org_member" // 管理数据库(创建表、修改结构) SysPolicyDBManage = "sys:db:manage" Resource: "database" Action: "*" Condition: "developer" ``` **存储资源 (storage)** ```go // 读取存储文件 SysPolicyStorageRead = "sys:storage:read" Resource: "storage" Action: "read" Condition: "org_member" // 上传/删除文件 SysPolicyStorageWrite = "sys:storage:write" Resource: "storage" Action: "create,update,delete" Condition: "developer" // 管理存储桶 SysPolicyStorageAdmin = "sys:storage:admin" Resource: "storage" Action: "*" Condition: "admin" ``` **函数资源 (function)** ```go // 调用函数 SysPolicyFunctionCall = "sys:function:call" Resource: "function" Action: "call" Condition: "org_member" // 管理函数(部署、删除) SysPolicyFunctionManage = "sys:function:manage" Resource: "function" Action: "create,update,delete" Condition: "developer" ``` **API 密钥管理 (apikey)** ```go // 读取 API 密钥(只能读取自己创建的密钥) SysPolicyAPIKeyRead = "sys:apikey:read" Resource: "apikey" Action: "read" Condition: "owner" // 管理 API 密钥 SysPolicyAPIKeyManage = "sys:apikey:manage" Resource: "apikey" Action: "*" Condition: "developer" ``` ### 5.6 平台超级管理员策略 ```go // 超级管理员 - 拥有所有权限 SysPolicySuperAdmin = "sys:super:admin" Resource: "*" Action: "*" Condition: "is_super_admin" Priority: 999 ``` --- ## 6. 权限缓存 ### 6.1 缓存机制 ``` 缓存键: perm:{user_id}:{org_id}:{resource}:{action} TTL: 1分钟 值: "allow" 或 "deny" ``` ### 6.2 缓存失效 以下操作会触发缓存清除: - 用户角色变更 - 角色策略变更 - 策略内容变更 - 组织成员变更 ```go // 清除用户权限缓存 service.ClearUserPermissionCache(userID) // 清除组织权限缓存 service.ClearOrgPermissionCache(orgID) ``` ### 6.3 缓存命中率优化 - 权限变更频率低,1分钟 TTL 平衡了性能和实时性 - 批量操作时建议先清除缓存,操作完成后统一刷新 --- ## 7. 最佳实践 ### 7.1 策略设计 1. **最小权限原则**: 只授予完成任务所需的最小权限 2. **职责分离**: 敏感操作需要多个角色共同完成 3. **策略命名规范**: `{resource}:{action}:{condition}` ### 7.2 BaaS 平台角色设计 VBase 作为 Supabase-like BaaS 平台,角色设计覆盖 **2C个人开发者** 和 **2B团队/企业** 场景: #### 2C 个人开发者场景 ``` 个人项目角色体系: ├── owner (项目所有者) │ └── 全部权限(可以删除项目) └── developer (开发者) └── 读写资源、调用 API ``` 个人开发者通常自己就是项目所有者,不需要复杂的角色体系。 #### 2B 团队协作场景 ``` 团队项目角色体系: ├── owner (所有者) │ └── 全部权限、可删除项目、管理账单 ├── admin (管理员) │ └── 管理成员、角色、资源设置 ├── developer (开发者) │ ├── 数据库: 创建表、查询、修改结构 │ ├── 存储: 上传/下载文件、管理存储桶 │ ├── 函数: 部署、调用、删除函数 │ └── API密钥: 创建、管理 ├── viewer (访客/只读) │ └── 查看数据、只读访问 └── auditor (审计员 - 可选) └── 查看日志、审计记录 ``` #### 角色权限对照表 | 角色 | 成员管理 | 资源管理 | 数据读写 | API密钥 | 项目设置 | |------|----------|----------|----------|---------|----------| | **owner** | ✓ | ✓ | ✓ | ✓ | ✓ | | **admin** | ✓ | ✓ | ✓ | ✓ | ✗ | | **developer** | ✗ | ✓ | ✓ | ✓ | ✗ | | **viewer** | ✗ | ✗ | 只读 | ✗ | ✗ | #### 系统角色配置示例 ```go // Owner 角色 - 绑定所有权限 var RoleOwner = model.Role{ Name: "owner", Description: "项目所有者", PolicyIDs: "sys:org:admin,sys:member:manage,sys:role:manage,sys:policy:manage", IsSystem: true, } // Admin 角色 - 管理权限 var RoleAdmin = model.Role{ Name: "admin", Description: "项目管理员", PolicyIDs: "sys:member:manage,sys:role:read,sys:db:manage,sys:storage:admin,sys:function:manage", IsSystem: true, } // Developer 角色 - 开发权限 var RoleDeveloper = model.Role{ Name: "developer", Description: "开发者", PolicyIDs: "sys:db:manage,sys:storage:write,sys:function:manage,sys:apikey:manage", IsSystem: true, } // Viewer 角色 - 只读权限 var RoleViewer = model.Role{ Name: "viewer", Description: "访客", PolicyIDs: "sys:org:read,sys:db:read,sys:storage:read,sys:function:call", IsSystem: true, } ``` ### 7.3 权限检查位置 **Controller 层检查:** ```go func Handler(x *vigo.X) error { // 先检查权限 if !hasPermission(x, "resource", "action") { return vigo.ErrForbidden } // 执行业务逻辑 } ``` **Service 层检查(数据级):** ```go func UpdateUser(userID string, data map[string]any) error { // 检查是否是本人或管理员 if !isOwner(userID) && !hasAdminRole() { return ErrForbidden } // 执行更新 } ``` ### 7.4 BaaS 平台权限场景示例 **场景1: 个人开发者创建项目** ```go // 小明是个人开发者,注册后创建项目 // 1. 创建项目(平台级权限检查) result, _ := checker.Check("xiaoming_user_id", "", "org", "create", nil) // 结果: 允许(personal:org:create 策略) // 2. 小明成为项目所有者 // org.owner_id = "xiaoming_user_id" // 3. 小明在项目内操作数据库(项目级权限) result, _ = checker.Check("xiaoming_user_id", "my-project", "database", "create", nil) // 结果: 允许(小明是项目所有者) ``` **场景2: 团队协作开发** ```go // CEO 创建 WebApp 项目,邀请 CTO 为管理员,员工为开发者 // - CEO: owner // - CTO: admin // - 员工A: developer // - 外包人员: viewer // CTO 邀请成员(有 member:manage 权限) result, _ := checker.Check("cto_user_id", "webapp-project", "member", "create", nil) // 结果: 允许(admin 角色有 member:manage 策略) // 员工A 创建数据库表(有 db:manage 权限) result, _ = checker.Check("employee_a_id", "webapp-project", "database", "create", nil) // 结果: 允许(developer 角色有 db:manage 策略) // 外包人员 尝试删除表(viewer 没有 delete 权限) result, _ = checker.Check("contractor_id", "webapp-project", "database", "delete", nil) // 结果: 拒绝(viewer 只有 db:read 权限) ``` **场景3: API 密钥访问控制** ```go // 开发者创建 API 密钥用于后端服务 // 只能查看自己创建的密钥 result, _ := checker.Check("developer_id", "project-123", "apikey", "read", map[string]any{ "owner_id": "developer_id", }) // 结果: 允许(满足 owner 条件) // 尝试查看他人创建的密钥 result, _ = checker.Check("developer_id", "project-123", "apikey", "read", map[string]any{ "owner_id": "other_developer_id", }) // 结果: 拒绝(不满足 owner 条件) ``` **场景4: 跨项目资源访问** ```go // 用户小明在 project-A 是开发者,在 project-B 是访客 // 在 project-A 上传文件 result, _ := checker.Check("xiaoming_id", "project-A", "storage", "create", nil) // 结果: 允许(developer 角色有 storage:write 权限) // 在 project-B 上传文件 result, _ = checker.Check("xiaoming_id", "project-B", "storage", "create", nil) // 结果: 拒绝(viewer 角色只有 storage:read 权限) ``` ### 7.5 权限测试 ```go func TestPermissionCheck(t *testing.T) { tests := []struct { name string userID string orgID string resource string action string data map[string]any want bool }{ { name: "owner can update own profile", userID: "user1", orgID: "", resource: "user", action: "update", data: map[string]any{"owner_id": "user1"}, want: true, }, { name: "user cannot update others profile", userID: "user1", orgID: "", resource: "user", action: "update", data: map[string]any{"owner_id": "user2"}, want: false, }, } checker := service.NewPermissionChecker() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result, _ := checker.Check(tt.userID, tt.orgID, tt.resource, tt.action, tt.data) if result.Allowed != tt.want { t.Errorf("Check() = %v, want %v", result.Allowed, tt.want) } }) } } ``` --- ## 8. 故障排查 ### 8.1 权限检查失败 **检查步骤:** **平台级权限检查失败(org_id 为空):** 1. 确认用户已登录 2. 确认操作的是自己的资源(检查 owner_id 条件) 3. 检查用户是否有平台级管理员权限 4. 检查默认个人策略是否生效 **项目级权限检查失败(有 org_id):** 1. 确认用户是项目成员(OrgMember 状态为 active) 2. 检查用户角色是否正确分配 3. 检查角色绑定的策略 4. 检查策略的 Effect 和 Condition 5. 确认资源所属的项目是否正确 **调试日志:** ```go // 开启调试日志 checker := service.NewPermissionChecker() result, err := checker.Check(userID, orgID, resource, action, data) log.Printf("Permission check: user=%s, resource=%s, action=%s, allowed=%v, reason=%s", userID, resource, action, result.Allowed, result.Reason) ``` ### 8.2 缓存问题 ```bash # 清除 Redis 权限缓存 redis-cli KEYS "perm:*" | xargs redis-cli DEL # 或重启应用(开发环境) ``` ### 8.3 权限不生效 1. 检查策略是否保存成功 2. 检查角色是否正确绑定策略 3. 检查用户是否正确分配角色 4. 检查缓存是否已清除 --- ## 9. 扩展开发 ### 9.1 添加自定义条件 ```go // 在 permission.go 中扩展 evaluateCondition func (pc *PermissionChecker) evaluateCondition(p *model.Policy, userID, orgID string, resourceData map[string]any) bool { switch p.Condition { case "owner": // 现有逻辑... case "custom_condition": // 自定义条件逻辑 return checkCustomCondition(userID, orgID, resourceData) default: return true } } ``` ### 9.2 添加 BaaS 资源类型 **步骤1: 定义资源常量** ```go // 在 policy.go 中添加资源常量 const ( ResourceUser = "user" ResourceOrg = "org" ResourceMember = "member" ResourceDatabase = "database" ResourceStorage = "storage" ResourceFunction = "function" ResourceAPIKey = "apikey" ResourceCustom = "custom_resource" // 新增资源类型 ) ``` **步骤2: 创建资源级策略** ```go // 为新增资源创建策略 func (pc *PermissionChecker) getCustomResourcePolicies() []model.Policy { return []model.Policy{ { Code: "custom:read", Name: "读取自定义资源", Resource: ResourceCustom, Action: "read", Effect: model.EffectAllow, Condition: "org_member", }, { Code: "custom:manage", Name: "管理自定义资源", Resource: ResourceCustom, Action: "create,update,delete", Effect: model.EffectAllow, Condition: "developer", }, } } ``` **步骤3: 在角色中使用** ```go // 创建新角色使用自定义策略 customRole := &model.Role{ OrgID: orgID, Name: "custom_manager", Description: "自定义资源管理员", PolicyIDs: "custom:read,custom:manage", Scope: "resource", } ``` ### 9.3 多租户资源隔离 在 BaaS 平台中,资源需要严格的项目隔离: ```go // 查询时自动添加 org_id 过滤 func ListResources(userID, orgID string) ([]Resource, error) { // 检查用户在项目中的权限 checker := service.NewPermissionChecker() result, err := checker.Check(userID, orgID, "custom_resource", "read", nil) if err != nil || !result.Allowed { return nil, vigo.ErrForbidden } // 查询该项目的资源(自动隔离) var resources []Resource err = model.DB.Where("org_id = ?", orgID).Find(&resources).Error return resources, err } ``` --- ## 10. 参考 - [RBAC 模型](https://en.wikipedia.org/wiki/Role-based_access_control) - [ABAC 模型](https://en.wikipedia.org/wiki/Attribute-based_access_control) - [NIST RBAC 标准](https://csrc.nist.gov/projects/role-based-access-control)