feat(P1/P2): 完成TDD开发及P1/P2设计文档

## 设计文档
- multi_role_permission_design: 多角色权限设计 (CONDITIONAL GO)
- audit_log_enhancement_design: 审计日志增强 (CONDITIONAL GO)
- routing_strategy_template_design: 路由策略模板 (CONDITIONAL GO)
- sso_saml_technical_research: SSO/SAML调研 (CONDITIONAL GO)
- compliance_capability_package_design: 合规能力包设计 (CONDITIONAL GO)

## TDD开发成果
- IAM模块: supply-api/internal/iam/ (111个测试)
- 审计日志模块: supply-api/internal/audit/ (40+测试)
- 路由策略模块: gateway/internal/router/ (33+测试)
- 合规能力包: gateway/internal/compliance/ + scripts/ci/compliance/

## 规范文档
- parallel_agent_output_quality_standards: 并行Agent产出质量规范
- project_experience_summary: 项目经验总结 (v2)
- 2026-04-02-p1-p2-tdd-execution-plan: TDD执行计划

## 评审报告
- 5个CONDITIONAL GO设计文档评审报告
- fix_verification_report: 修复验证报告
- full_verification_report: 全面质量验证报告
- tdd_module_quality_verification: TDD模块质量验证
- tdd_execution_summary: TDD执行总结

依据: Superpowers执行框架 + TDD规范
This commit is contained in:
Your Name
2026-04-02 23:35:53 +08:00
parent ed0961d486
commit 89104bd0db
94 changed files with 24738 additions and 5 deletions

View File

@@ -0,0 +1,697 @@
# 多角色权限设计方案P1
- 版本v1.0
- 日期2026-04-02
- 状态:设计稿(已修复)
- 依赖:
- `docs/token_runtime_minimal_spec_v1.md`TOK-001
- `docs/token_auth_middleware_design_v1_2026-03-29.md`TOK-002
- `docs/llm_gateway_prd_v1_2026-03-25.md`
- 目标:实现 PRD P1 "多角色权限"需求
---
## 1. 背景与目标
### 1.1 业务背景
LLM Gateway 平台需要支持多类用户角色,满足不同的使用场景:
1. **平台管理员** - 负责组织级策略、预算、权限管理
2. **AI 应用开发者** - 负责接入模型与业务落地
3. **财务/运营负责人** - 负责成本追踪、对账与预算控制
4. **供应方** - 拥有多余LLM配额的个人或企业平台用户
5. **需求方** - 需要LLM调用能力的企业/开发者
### 1.2 设计目标
1. **角色扩展**:在现有 `owner/viewer/admin` 三角色基础上扩展,支持更多业务场景
2. **权限细分**:支持细粒度的 scope 权限控制
3. **层级清晰**:建立的角色继承/层级关系
4. **API兼容**:保持与现有 SUP-004~SUP-008 链路一致
5. **可扩展**:支持未来新增角色和权限
---
## 2. 现有权限模型分析
### 2.1 现有角色体系TOK-001
| 角色 | 等级 | 能力 | 约束 |
|------|------|------|------|
| admin | 3 | 风控与审计管理 | 仅平台内部可用 |
| owner | 2 | 管理供应侧账号、套餐、结算 | 不可读取上游凭证明文 |
| viewer | 1 | 只读查询 | 不可执行写操作 |
### 2.2 现有 JWT Token Claims 结构
```go
type TokenClaims struct {
jwt.RegisteredClaims
SubjectID string `json:"subject_id"` // 用户主体ID
Role string `json:"role"` // 角色: admin/owner/viewer
Scope []string `json:"scope"` // 授权范围列表
TenantID int64 `json:"tenant_id"` // 租户ID
}
```
### 2.3 现有中间件链路TOK-002
```
RequestIdMiddleware
QueryKeyRejectMiddleware
BearerExtractMiddleware
TokenVerifyMiddleware
TokenStatusCheckMiddleware
ScopeRoleAuthzMiddleware ← 权限校验
AuditEmitMiddleware
```
---
## 3. 多角色权限设计方案
### 3.1 角色定义
#### 3.1.1 平台侧角色Platform Roles
| 角色 | 代码 | 层级 | 说明 | 继承关系 |
|------|------|------|------|----------|
| 超级管理员 | `super_admin` | 100 | 平台最高权限,仅平台运营方可用 | - |
| 组织管理员 | `org_admin` | 50 | 组织级管理,管理本组织所有资源 | 显式配置拥有operator+finops+developer+viewer所有scope |
| 运维人员 | `operator` | 30 | 系统运维与配置 | 显式配置拥有viewer所有scope + platform:write等 |
| 开发者 | `developer` | 20 | AI应用开发者接入模型与业务落地 | 继承 viewer |
| 财务人员 | `finops` | 20 | 成本追踪、对账与预算控制 | 继承 viewer |
| 查看者 | `viewer` | 10 | 只读查询 | - |
**说明**
1. 继承关系仅用于权限聚合,代表"子角色拥有父角色所有scope + 自身额外scope"
2. `org_admin` 显式配置拥有 `operator` + `finops` + `developer` + `viewer` 的所有scope
3. `operator` 显式配置拥有 `viewer` 所有scope + `platform:write` 等权限
4. 层级数值仅用于权限优先级判断,不影响继承关系
#### 3.1.2 供应侧角色Supply Roles
| 角色 | 代码 | 层级 | 说明 | 继承关系 |
|------|------|------|------|----------|
| 供应方管理员 | `supply_admin` | 40 | 供应侧全面管理 | 显式配置拥有supply_operator+supply_finops所有scope |
| 供应方运维 | `supply_operator` | 30 | 套餐管理、额度配置 | 显式配置拥有supply_viewer所有scope + supply:package:write等 |
| 供应方财务 | `supply_finops` | 20 | 收益结算、对账 | 继承 supply_viewer |
| 供应方查看者 | `supply_viewer` | 10 | 只读查询 | - |
#### 3.1.3 需求侧角色Consumer Roles
| 角色 | 代码 | 层级 | 说明 | 继承关系 |
|------|------|------|------|----------|
| 需求方管理员 | `consumer_admin` | 40 | 需求侧全面管理 | 显式配置拥有consumer_operator所有scope |
| 需求方运维 | `consumer_operator` | 30 | API Key管理、调用配置 | 显式配置拥有consumer_viewer所有scope + consumer:apikey:*等) |
| 需求方查看者 | `consumer_viewer` | 10 | 只读查询 | - |
### 3.2 角色层级关系图
```
┌─────────────┐
│ super_admin │ (层级100)
└──────┬──────┘
│ 权限聚合
┌─────────────┐
│ org_admin │ (层级50)
└──────┬──────┘
│ 显式配置聚合operator+developer+finops+viewer scope
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ operator │ │developer │ │ finops │ (层级20-30)
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
│ 显式配置 │ 继承 │ 继承
│ (+viewer) │ (+viewer) │ (+viewer)
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ viewer │ │ viewer │ │ viewer │ (层级10)
└──────────┘ └──────────┘ └──────────┘
─────────────────────────────────────────
┌──────────┐ ┌──────────────┐
│supply_ad │────│consumer_adm │
│ min │ │ in │ (层级40)
└────┬─────┘ └──────┬───────┘
│ 显式配置 │ 显式配置
│ (+operator │ (+operator
│ +finops) │ +viewer)
▼ ▼
┌──────────┐ ┌──────────────┐
│supply_op │ │consumer_op │
│ erator │ │ erator │ (层级30)
└────┬─────┘ └──────┬───────┘
│ 显式配置 │ 显式配置
│ (+viewer) │ (+viewer)
▼ ▼
┌──────────┐ ┌──────────────┐
│supply_vi │ │consumer_vi │
│ ewer │ │ ewer │ (层级10)
└──────────┘ └──────────────┘
```
**继承关系说明**
- 继承 = 子角色拥有父角色所有 scope + 自身额外 scope
- 显式配置 = 直接授予特定 scope 列表(等效于显式继承但更清晰)
- supply_admin/consumer_admin = 拥有该类别下所有子角色 scope
- operator/developer/finops = 拥有 viewer 所有 scope + 各自额外 scope
### 3.3 Scope 权限定义
#### 3.3.1 Platform Scope
| Scope | 说明 | 授予角色 |
|-------|------|----------|
| `platform:read` | 读取平台配置 | viewer+ |
| `platform:write` | 修改平台配置 | operator+ |
| `platform:admin` | 平台级管理 | org_admin+ |
| `platform:audit:read` | 读取审计日志 | operator+ |
| `platform:audit:export` | 导出审计日志 | org_admin+ |
#### 3.3.2 Tenant Scope
| Scope | 说明 | 授予角色 | 备注 |
|-------|------|----------|------|
| `tenant:read` | 读取租户信息 | viewer+ | |
| `tenant:write` | 修改租户配置 | operator+ | |
| `tenant:member:manage` | 管理租户成员 | org_admin | |
| `tenant:billing:write` | 修改账单设置 | org_admin | |
#### 3.3.3 Supply Scope
| Scope | 说明 | 授予角色 | 备注 |
|-------|------|----------|------|
| `supply:account:read` | 读取供应账号 | supply_viewer+ | |
| `supply:account:write` | 管理供应账号 | supply_operator+ | |
| `supply:package:read` | 读取套餐信息 | supply_viewer+ | |
| `supply:package:write` | 管理套餐 | supply_operator+ | |
| `supply:package:publish` | 发布套餐 | supply_operator+ | |
| `supply:package:offline` | 下架套餐 | supply_operator+ | |
| `supply:settlement:withdraw` | 提现 | supply_admin | |
| `supply:credential:manage` | 管理凭证 | supply_admin | |
#### 3.3.4 Consumer Scope
| Scope | 说明 | 授予角色 | 备注 |
|-------|------|----------|------|
| `consumer:account:read` | 读取账户信息 | consumer_viewer+ | |
| `consumer:account:write` | 管理账户 | consumer_operator+ | |
| `consumer:apikey:create` | 创建API Key | consumer_operator+ | |
| `consumer:apikey:read` | 读取API Key | consumer_viewer+ | |
| `consumer:apikey:revoke` | 吊销API Key | consumer_operator+ | |
| `consumer:usage:read` | 读取使用量 | consumer_viewer+ | |
#### 3.3.5 Billing Scope统一
| Scope | 说明 | 授予角色 | user_type限定 |
|-------|------|----------|---------------|
| `billing:read` | 读取账单 | finops+, supply_finops+, consumer_viewer+ | 通过user_type区分数据范围 |
| `billing:write` | 修改账单设置 | org_admin | |
**说明**
- 原有 `tenant:billing:read``supply:settlement:read``consumer:billing:read` 统一为 `billing:read`
- 通过 TokenClaims.user_type 字段限定数据范围platform用户看租户账单supply用户看供应结算consumer用户看需求账单
- 原 scope 名称保留作为 deprecated alias
#### 3.3.6 Router Scope网关转发
| Scope | 说明 | 授予角色 |
|-------|------|----------|
| `router:invoke` | 调用模型 | 所有认证用户 |
| `router:model:list` | 列出可用模型 | viewer+ |
| `router:model:config` | 配置路由策略 | operator+ |
---
## 4. API 路由权限映射
### 4.1 Platform API
| API路径 | 方法 | 所需Scope | 所需角色 |
|---------|------|-----------|----------|
| `/api/v1/platform/info` | GET | `platform:read` | viewer+ |
| `/api/v1/platform/config` | GET | `platform:read` | viewer+ |
| `/api/v1/platform/config` | PUT | `platform:write` | operator+ |
| `/api/v1/platform/tenants` | GET | `tenant:read` | viewer+ |
| `/api/v1/platform/tenants` | POST | `tenant:write` | operator+ |
| `/api/v1/platform/audit/events` | GET | `platform:audit:read` | operator+ |
| `/api/v1/platform/audit/events/export` | POST | `platform:audit:export` | org_admin+ |
### 4.2 Supply API与 SUP-004~SUP-008 保持一致)
| API路径 | 方法 | 所需Scope | 所需角色 |
|---------|------|-----------|----------|
| `/api/v1/supply/accounts` | GET | `supply:account:read` | supply_viewer+ |
| `/api/v1/supply/accounts` | POST | `supply:account:write` | supply_operator+ |
| `/api/v1/supply/accounts/:id` | PUT | `supply:account:write` | supply_operator+ |
| `/api/v1/supply/accounts/:id/verify` | POST | `supply:account:write` | supply_operator+ |
| `/api/v1/supply/packages` | GET | `supply:package:read` | supply_viewer+ |
| `/api/v1/supply/packages` | POST | `supply:package:write` | supply_operator+ |
| `/api/v1/supply/packages/:id/publish` | POST | `supply:package:publish` | supply_operator+ |
| `/api/v1/supply/packages/:id/offline` | POST | `supply:package:offline` | supply_operator+ |
| `/api/v1/supply/settlements` | GET | `billing:read` | supply_finops+ |
| `/api/v1/supply/settlements/withdraw` | POST | `supply:settlement:withdraw` | supply_admin |
| `/api/v1/supply/billing` | GET | `billing:read` | supply_finops+ |
**Deprecated Alias 说明**
- `/api/v1/supplier/*` 路径仅作为历史兼容别名保留
- 新接口禁止使用 `/supplier` 前缀
- deprecated alias 响应体应包含 `deprecation_notice` 字段提示迁移
- S2 阶段评估 alias 下线时间
### 4.3 Consumer API
| API路径 | 方法 | 所需Scope | 所需角色 |
|---------|------|-----------|----------|
| `/api/v1/consumer/account` | GET | `consumer:account:read` | consumer_viewer+ |
| `/api/v1/consumer/account` | PUT | `consumer:account:write` | consumer_operator+ |
| `/api/v1/consumer/apikeys` | GET | `consumer:apikey:read` | consumer_viewer+ |
| `/api/v1/consumer/apikeys` | POST | `consumer:apikey:create` | consumer_operator+ |
| `/api/v1/consumer/apikeys/:id/revoke` | POST | `consumer:apikey:revoke` | consumer_operator+ |
| `/api/v1/consumer/usage` | GET | `consumer:usage:read` | consumer_viewer+ |
| `/api/v1/consumer/billing` | GET | `billing:read` | consumer_viewer+ |
### 4.4 Router API网关调用
| API路径 | 方法 | 所需Scope | 所需角色 |
|---------|------|-----------|----------|
| `/v1/chat/completions` | POST | `router:invoke` | 所有认证用户 |
| `/v1/completions` | POST | `router:invoke` | 所有认证用户 |
| `/v1/embeddings` | POST | `router:invoke` | 所有认证用户 |
| `/v1/models` | GET | `router:model:list` | viewer+ |
| `/api/v1/router/models` | GET | `router:model:list` | viewer+ |
| `/api/v1/router/policies` | GET | `router:model:config` | operator+ |
| `/api/v1/router/policies` | PUT | `router:model:config` | operator+ |
---
## 5. 数据模型扩展
### 5.1 Role 定义表iam_roles
```sql
CREATE TABLE iam_roles (
id BIGSERIAL PRIMARY KEY,
role_code VARCHAR(50) NOT NULL UNIQUE, -- super_admin, org_admin, operator, developer, finops, viewer
role_name VARCHAR(100) NOT NULL,
role_type VARCHAR(20) NOT NULL, -- platform, supply, consumer
parent_role_id BIGINT REFERENCES iam_roles(id), -- 继承关系
level INT NOT NULL DEFAULT 0, -- 权限层级
description TEXT,
is_active BOOLEAN DEFAULT TRUE,
-- 审计字段(符合 database_domain_model_and_governance v1 规范)
request_id VARCHAR(64), -- 请求追踪ID
created_ip INET, -- 创建者IP
updated_ip INET, -- 更新者IP
version INT DEFAULT 1, -- 乐观锁版本号
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_iam_roles_code ON iam_roles(role_code);
CREATE INDEX idx_iam_roles_type ON iam_roles(role_type);
CREATE INDEX idx_iam_roles_request_id ON iam_roles(request_id);
```
### 5.2 Scope 定义表iam_scopes
```sql
CREATE TABLE iam_scopes (
id BIGSERIAL PRIMARY KEY,
scope_code VARCHAR(100) NOT NULL UNIQUE, -- platform:read, supply:account:write
scope_name VARCHAR(100) NOT NULL,
scope_type VARCHAR(50) NOT NULL, -- platform, supply, consumer, router
description TEXT,
is_active BOOLEAN DEFAULT TRUE,
-- 审计字段(符合 database_domain_model_and_governance v1 规范)
request_id VARCHAR(64), -- 请求追踪ID
created_ip INET, -- 创建者IP
updated_ip INET, -- 更新者IP
version INT DEFAULT 1, -- 乐观锁版本号
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_iam_scopes_code ON iam_scopes(scope_code);
CREATE INDEX idx_iam_scopes_request_id ON iam_scopes(request_id);
```
### 5.3 角色-Scope 关联表iam_role_scopes
```sql
CREATE TABLE iam_role_scopes (
id BIGSERIAL PRIMARY KEY,
role_id BIGINT NOT NULL REFERENCES iam_roles(id),
scope_id BIGINT NOT NULL REFERENCES iam_scopes(id),
-- 审计字段(符合 database_domain_model_and_governance v1 规范)
request_id VARCHAR(64), -- 请求追踪ID
created_ip INET, -- 创建者IP
version INT DEFAULT 1, -- 乐观锁版本号
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(role_id, scope_id)
);
CREATE INDEX idx_iam_role_scopes_role ON iam_role_scopes(role_id);
CREATE INDEX idx_iam_role_scopes_scope ON iam_role_scopes(scope_id);
CREATE INDEX idx_iam_role_scopes_request_id ON iam_role_scopes(request_id);
```
### 5.4 用户-角色关联表iam_user_roles
```sql
CREATE TABLE iam_user_roles (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
role_id BIGINT NOT NULL REFERENCES iam_roles(id),
tenant_id BIGINT, -- 租户范围NULL表示全局
granted_by BIGINT,
granted_at TIMESTAMPTZ DEFAULT NOW(),
expires_at TIMESTAMPTZ, -- 角色过期时间
-- 审计字段(符合 database_domain_model_and_governance v1 规范)
request_id VARCHAR(64), -- 请求追踪ID
created_ip INET, -- 创建者IP
updated_ip INET, -- 更新者IP
version INT DEFAULT 1, -- 乐观锁版本号
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_iam_user_roles_user ON iam_user_roles(user_id);
CREATE INDEX idx_iam_user_roles_tenant ON iam_user_roles(tenant_id);
CREATE INDEX idx_iam_user_roles_request_id ON iam_user_roles(request_id);
CREATE UNIQUE INDEX idx_iam_user_roles_unique ON iam_user_roles(user_id, role_id, tenant_id);
```
### 5.5 扩展 Token Claims
```go
type TokenClaims struct {
jwt.RegisteredClaims
SubjectID string `json:"subject_id"` // 用户主体ID
Role string `json:"role"` // 主角色
Scope []string `json:"scope"` // 授权范围列表
TenantID int64 `json:"tenant_id"` // 租户ID
UserType string `json:"user_type"` // 用户类型: platform/supply/consumer
Permissions []string `json:"permissions"` // 细粒度权限列表
}
```
---
## 6. 中间件设计
### 6.1 扩展 ScopeRoleAuthzMiddleware
```go
// 扩展后的权限校验逻辑
type AuthzConfig struct {
// 路由-角色映射
RouteRolePolicies map[string]RolePolicy
// 路由-Scope映射
RouteScopePolicies map[string][]string
// 角色层级
RoleHierarchy map[string]int
}
type RolePolicy struct {
RequiredLevel int
RequiredRole string
RequiredScope []string
}
// 权限校验逻辑
func (m *AuthMiddleware) ScopeRoleAuthzMiddleware(requiredScope string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
claims, ok := r.Context().Value(tokenClaimsKey).(*TokenClaims)
if !ok {
writeAuthError(w, http.StatusUnauthorized, "AUTH_CONTEXT_MISSING", "")
return
}
// 1. Scope 校验
if requiredScope != "" && !containsScope(claims.Scope, requiredScope) {
m.emitAuditAndReject(r, w, "AUTH_SCOPE_DENIED", requiredScope, claims)
return
}
// 2. 角色层级校验(如果配置了角色要求)
if policy, exists := getRoutePolicy(r.URL.Path); exists {
if !checkRolePolicy(claims, policy) {
m.emitAuditAndReject(r, w, "AUTH_ROLE_DENIED", "", claims)
return
}
}
next.ServeHTTP(w, r)
})
}
}
```
### 6.2 新增角色层级中间件
```go
// RoleHierarchyMiddleware 角色层级校验中间件
// 用于需要特定角色层级的操作
func RoleHierarchyMiddleware(minLevel int) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
claims := GetTokenClaims(r.Context())
if claims == nil {
writeAuthError(w, http.StatusUnauthorized, "AUTH_CONTEXT_MISSING", "")
return
}
if getRoleLevel(claims.Role) < minLevel {
writeAuthError(w, http.StatusForbidden, "AUTH_ROLE_LEVEL_DENIED",
fmt.Sprintf("required role level %d", minLevel))
return
}
next.ServeHTTP(w, r)
})
}
}
```
### 6.3 新增跨类型校验中间件
```go
// UserTypeMiddleware 用户类型校验中间件
// 用于区分 platform/supply/consumer 用户
func UserTypeMiddleware(allowedTypes ...string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
claims := GetTokenClaims(r.Context())
if claims == nil {
writeAuthError(w, http.StatusUnauthorized, "AUTH_CONTEXT_MISSING", "")
return
}
if !containsString(allowedTypes, claims.UserType) {
writeAuthError(w, http.StatusForbidden, "AUTH_USER_TYPE_DENIED",
fmt.Sprintf("allowed user types: %v", allowedTypes))
return
}
next.ServeHTTP(w, r)
})
}
}
```
---
## 7. 错误码扩展
| 错误码 | HTTP状态 | 说明 |
|--------|----------|------|
| `AUTH_SCOPE_DENIED` | 403 | Scope权限不足 |
| `AUTH_ROLE_DENIED` | 403 | 角色权限不足 |
| `AUTH_ROLE_LEVEL_DENIED` | 403 | 角色层级不足 |
| `AUTH_USER_TYPE_DENIED` | 403 | 用户类型不允许 |
| `AUTH_TENANT_MISMATCH` | 403 | 租户上下文不匹配 |
| `AUTH_RESOURCE_OWNER_DENIED` | 403 | 资源所有权校验失败 |
---
## 8. 审计事件扩展
| 事件名 | 说明 | 触发场景 |
|--------|------|----------|
| `role.assign` | 角色分配 | 给用户分配角色 |
| `role.revoke` | 角色吊销 | 吊销用户角色 |
| `role.scope.denied` | Scope权限拒绝 | Scope校验失败 |
| `role.hierarchy.denied` | 角色层级拒绝 | 角色层级校验失败 |
| `usertype.denied` | 用户类型拒绝 | 用户类型校验失败 |
---
## 9. API 契约更新
### 9.1 新增角色管理 API
#### GET /api/v1/iam/roles
获取角色列表
**响应:**
```json
{
"roles": [
{
"role_code": "org_admin",
"role_name": "组织管理员",
"role_type": "platform",
"level": 50,
"scopes": ["platform:read", "tenant:read", "tenant:write"]
}
]
}
```
#### POST /api/v1/iam/users/:userId/roles
分配角色给用户
**请求:**
```json
{
"role_code": "developer",
"tenant_id": 123,
"expires_at": "2026-12-31T23:59:59Z"
}
```
#### DELETE /api/v1/iam/users/:userId/roles/:roleCode
吊销用户角色
### 9.2 新增 Scope 查询 API
#### GET /api/v1/iam/scopes
获取所有可用Scope
---
## 10. 向后兼容方案
### 10.1 新旧层级映射表与TOK-001对齐
| TOK-001旧层级 | 旧角色代码 | 新角色代码 | 新层级 | 权限变化说明 |
|---------------|------------|------------|--------|--------------|
| 3 | admin | `super_admin` | 100 | 完全对应,平台最高权限 |
| 2 | owner | `supply_admin` | 40 | 权限范围明确为供应侧管理,不含平台运营权限 |
| 1 | viewer | `viewer` | 10 | 完全对应 |
**说明**
- TOK-001 新角色体系super_admin/org_admin/operator专属于平台侧管理
- 原 owner 角色对应 supply_admin供应侧管理员职责边界清晰
- 层级数值用于优先级判断,新旧体系独立运作
### 10.2 现有角色映射
| 旧角色 | 新角色 | 说明 |
|--------|--------|------|
| `admin` | `super_admin` | 完全对应层级100 |
| `owner` | `supply_admin` | 权限范围重新定义为供应侧,不含平台运营权限 |
| `viewer` | `viewer` | 完全对应层级10 |
**权限边界变化说明**
- 原 owner 可管理供应侧账号、套餐、结算(对应 supply_admin
- 原 owner 不可执行平台级操作(由 org_admin/super_admin 专属)
- supply_admin(40) < org_admin(50) 是合理设计,因为 org_admin 管理范围更广
### 10.3 Token 兼容处理
```go
// RoleMapping 旧角色到新角色的映射
var RoleMapping = map[string]string{
"admin": "super_admin",
"owner": "supply_admin",
// viewer 保持不变
}
// 在Token验证时自动转换
func normalizeRole(role string) string {
if newRole, exists := RoleMapping[role]; exists {
return newRole
}
return role
}
```
---
## 11. 实施计划
### 11.1 Phase 1: 数据模型扩展
1. 创建 `iam_roles`, `iam_scopes`, `iam_role_scopes`, `iam_user_roles`
2. 初始化预定义角色和Scope数据
3. 提供数据迁移脚本
### 11.2 Phase 2: 中间件扩展
1. 扩展 `ScopeRoleAuthzMiddleware` 支持新角色层级
2. 新增 `RoleHierarchyMiddleware`
3. 新增 `UserTypeMiddleware`
4. 更新 Token Claims 结构
### 11.3 Phase 3: API 实现
1. 实现角色管理 API
2. 实现 Scope 查询 API
3. 更新现有 API 的权限校验
### 11.4 Phase 4: 向后兼容
1. 实现角色映射逻辑
2. 提供迁移指导文档
---
## 12. 验收标准
1. [ ] 角色层级清晰super_admin > org_admin > operator/developer/finops > viewer
2. [ ] Scope权限校验正确精确匹配路由与所需Scope
3. [ ] 继承关系正确子角色自动继承父角色Scope
4. [ ] 向后兼容:现有 owner/viewer/admin 角色正常工作
5. [ ] 审计完整:角色变更和权限拒绝事件全量记录
6. [ ] API契约更新新增角色管理API符合RESTful规范
---
## 13. 关联文档
- `docs/token_runtime_minimal_spec_v1.md`TOK-001
- `docs/token_auth_middleware_design_v1_2026-03-29.md`TOK-002
- `docs/llm_gateway_prd_v1_2026-03-25.md`
- `docs/database_domain_model_and_governance_v1_2026-03-27.md`
- `docs/api_naming_strategy_supply_vs_supplier_v1_2026-03-27.md`
---
**文档状态**:设计稿(待评审)
**下一步**:提交评审,根据反馈修订后进入实施阶段