组织层次结构
实例包含顶级组织。一个组织可以包含一级子组织;每个组织都保留策略、成员资格、品牌、RBAC 和隔离边界。
组织单位是一个组织内的一个部门或团队。它永远不会更改 TenantContext、发行者、令牌声明或一级 SubOrg 限制。
- OrgUnit 树支持的最大深度为 8。
- 每个成员可以有一个主要组织单元和其他展示位置。
- OrgUnit 祖先链中最近的活动管理者是第一个访问请求批准者候选者。
项目和准入政策
项目组应用程序和授权角色。每个项目的access_policy仅控制同一组织的用户,没有有效的UserGrant;跨组织的 ProjectGrant 授权不受影响。
| 项目政策 | 同一组织行为 | 自助服务路径 |
|---|---|---|
| 打开 | 无需 UserGrant 即可允许。 | 不需要访问请求。 |
| 受限制的 | 被拒绝;管理员直接授予访问权限。 | 不提供自助服务请求。 |
| 需要批准 | 在 AccessRequest 获得批准之前被拒绝。 | 用户提交访问请求。 |
访问请求生命周期
AccessRequest 从待处理变为已批准、已拒绝、已取消或已过期。每个结果都是最终结果,待处理的请求会在 14 天后延迟过期。
批准会在同一事务中创建可追踪的 UserGrant。请求者不能批准自己的请求;决议从 OrgUnit 经理下达给项目和组织经理。
| 方式 | 路径 | 用途 | 所需范围 |
|---|---|---|---|
GET, POST |
/auth/access-requests |
创建并列出当前用户的请求。 | session |
POST |
/auth/access-requests/:id/cancel |
取消当前用户的待处理请求。 | session |
GET |
/auth/access-approvals |
列出等待当前用户批准的请求。 | session |
POST |
/auth/access-approvals/:id/{approve|deny} |
批准或拒绝分配给当前用户的待处理请求。 | session |
GET |
/v1/organizations/:orgId/access-requests |
列出一个组织内部的请求。 | access-requests:read |
GET |
/v1/organizations/:orgId/units |
阅读组织单位树。 | org-units:read |
POST, PATCH, DELETE, PUT |
/v1/organizations/:orgId/units/* |
创建、更新、移动、存档和管理单位成员。 | org-units:write |
安全边界
- 每个 OrgUnit 和 AccessRequest 查询的范围均由
tenant_id和org_id确定。跨组织或跨租户标识符返回 404,而不透露其存在。 - 成员身份和项目访问权限是分开的:邀请加入组织,而 AccessRequest 授予现有活跃成员对一个项目的访问权限。
- SCIM 提供用户和成员资格,但不会将目录组映射到当前实现中的 OrgUnit 或项目角色。
- 管理 API 使用光标分页和共享 API 密钥或组织管理器防护。它不重用最终用户业务路由。