Files
Edu/docs/architecture/issues/contracts/iam_contract.md

127 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# iam 对接契约
> 负责人ai06
> 关联:[matrix.md](./matrix.md)、[iam.proto](../../../packages/shared-proto/proto/iam.proto)、[events.proto](../../../packages/shared-proto/proto/events.proto)
> 裁决依据:[coord-final-decisions](../../coord-final-decisions.md) I1-I8、[president-final-rulings](../../president-final-rulings.md) §2.15/§2.16/§5.5
---
## §1 我提供什么(对外接口)
> **双入口策略**president §2.16REST 供 gateway 透传 + admin-portal 直连gRPC 供 BFF 聚合调用。同一 Application Service 同时被 REST Controller + gRPC Controller 调用业务逻辑不重复。gateway 保持 HTTP 透传(不改为 gRPC 客户端)。
### 1.1 gRPC 接口(供 BFF 聚合调用)
> 端口 50052P2 即启用I1 裁决)。⚠️ 当前 iam.proto 仅 4 RPC待 coord 补全至 12 RPCISSUE-005
| Service | RPC | 请求 | 响应 | 端口 | 消费方 |
| ---------- | ----------------------- | ------------------------------ | ---------------------------- | ----- | ---------------------------------------- |
| IamService | Register | RegisterRequest | AuthResponse | 50052 | api-gatewayREST 透传)/ admin-portal |
| IamService | Login | LoginRequest | AuthResponse | 50052 | api-gatewayREST 透传)/ admin-portal |
| IamService | RefreshToken | RefreshTokenRequest | TokenPair | 50052 | api-gatewayREST 透传) |
| IamService | Logout | LogoutRequest | LogoutResponse | 50052 | api-gatewayREST 透传) |
| IamService | GetUserInfo | GetUserInfoRequest | UserInfo | 50052 | teacher-bff / student-bff / parent-bff |
| IamService | BatchGetUsers | BatchGetUsersRequest | BatchGetUsersResponse | 50052 | teacher-bff / admin-portal |
| IamService | GetEffectivePermissions | GetEffectivePermissionsRequest | EffectivePermissionsResponse | 50052 | teacher-bff / student-bff / parent-bff |
| IamService | GetEffectiveAccess | GetEffectiveAccessRequest | EffectiveAccessResponse | 50052 | teacher-bff / student-bff / parent-bff |
| IamService | GetEffectiveDataScope | GetEffectiveDataScopeRequest | DataScopeResponse | 50052 | teacher-bff / data-ana |
| IamService | GetViewports | GetViewportsRequest | ViewportsResponse | 50052 | teacher-bff / student-bff / parent-bff |
| IamService | GetPublicKey | GetPublicKeyRequest | PublicKeyResponse | 50052 | api-gatewayJWKS 验签) |
| IamService | GetChildrenByParent | GetChildrenByParentRequest | ChildrenResponse | 50052 | parent-bff |
### 1.2 HTTP 端点(供 gateway 透传 + admin-portal 直连)
> REST 与 gRPC 双入口并存president §2.16。REST 路径统一加 `/v1` 前缀I7 裁决。gateway 路由 `/iam/v1/*` → iam 服务 `/v1/iam/*`(透传不改路径)。
| Method | Path | 权限 | 说明 | 消费方 |
| ------ | --------------------------------- | ----------------- | -------------------------------------- | -------------------- |
| POST | `/iam/v1/register` | 公开 | 注册 + 自动分配 teacher 角色 | api-gateway / admin |
| POST | `/iam/v1/login` | 公开 | 登录,返回 accessToken + refreshToken | api-gateway |
| POST | `/iam/v1/refresh` | 公开 | 刷新令牌(轮换 + 旧 token 黑名单) | api-gateway |
| POST | `/iam/v1/logout` | `IAM_USER_READ` | 登出refresh token 加黑名单) | api-gateway |
| GET | `/iam/v1/me` | `IAM_USER_READ` | 当前用户信息 | api-gateway / admin |
| GET | `/iam/v1/viewports` | `IAM_USER_READ` | 当前用户视口L1 导航) | api-gateway |
| GET | `/iam/v1/permissions/effective` | `IAM_USER_READ` | 当前用户有效权限I8 统一路径) | api-gateway |
| GET | `/iam/v1/.well-known/jwks.json` | 公开 | RS256 公钥 JWK SetGateway 拉取验签) | api-gateway |
| GET | `/iam/v1/children` | `IAM_USER_READ` | 当前家长的孩子列表I6 裁决) | api-gateway / parent |
| GET | `/iam/v1/roles` | `IAM_ROLE_MANAGE` | 角色列表(管理端) | admin-portal |
| GET | `/iam/v1/permissions` | `IAM_ROLE_MANAGE` | 权限点列表(管理端) | admin-portal |
| GET | `/healthz` | 无 | liveness | k8s / 监控 |
| GET | `/readyz` | 无 | readiness5 依赖检查) | k8s / 监控 |
| GET | `/metrics` | 无 | Prometheus 指标 | Prometheus |
### 1.3 GraphQL schema如 BFF
不适用。iam 是业务服务,不暴露 GraphQLGraphQL 由 BFF 层提供)。
### 1.4 Kafka 事件发布(如有)
| Topic | Event | 消费方 |
| --------------------- | ------------------------------------------------------------------------- | --------------------------------------------------------- |
| edu.iam.user.events | UserEventaction: created/updated/deleted/role_changed | core-edu / msg / push-gateway / teacher-bff / student-bff |
| edu.iam.role.events | RoleEventaction: created/updated | core-edu / teacher-bff |
| edu.iam.audit.created | AuditEventaction: create/update/delete/login/logout/permission_change | admin-portal |
### 1.5 错误码前缀
`IAM_`(如 IAM_UNAUTHORIZED、IAM_USER_NOT_FOUND、IAM_PERMISSION_DENIED
---
## §2 我消费什么(依赖上游)
### 2.1 gRPC 调用(同步)
无。iam 是身份根服务,不依赖其他业务服务。
### 2.2 Kafka 事件订阅(异步)
无。
### 2.3 HTTP 调用(如有)
无。
---
## §3 就绪信号
### 3.1 我依赖的上游就绪标志
iam 是身份根服务无业务上游依赖。但依赖以下基础设施契约coord 提供):
| 依赖项 | 提供方 | 就绪标志 | 状态 |
| ------ | ------ | -------- | ---- |
| iam.proto 补全至 12 RPC | coord | proto 含 12 RPC + 全部 message | ❌ 仅 4 RPCISSUE-005 |
| events.proto 补全 UserEvent/RoleEvent/AuditEvent | coord | proto 含 3 个 message | ❌ 缺失ISSUE-002 |
| shared-ts Outbox 工具包 | coord | outbox.service.ts 可导入 | ✅ 已就绪 |
### 3.2 我的就绪标志(供下游消费)
- [ ] iam gRPC 50052 启用HealthService.Check 返回 SERVING
- [ ] IamService 12 RPC 全部可调用Register/Login/RefreshToken/Logout/GetUserInfo/BatchGetUsers/GetEffectivePermissions/GetEffectiveAccess/GetEffectiveDataScope/GetViewports/GetPublicKey/GetChildrenByParent
- [ ] IamService.GetPublicKey 可用(返回 RS256 PEM 公钥,供 api-gateway 验签)
- [ ] IamService.GetChildrenByParent 可用(供 parent-bff 查孩子列表)
- [ ] edu.iam.user.events / edu.iam.role.events / edu.iam.audit.created topic 可发布
- [ ] JWT RS256 签发链路打通access_token 15min + refresh_token 7day 轮换)
- [ ] /iam/v1/* REST 端点可用(供 gateway 透传 + admin-portal 直连,双入口策略)
---
## §4 Mock 策略
### 4.1 我提供的 mock
在 iam 真实服务就绪前为下游api-gateway / 各 BFF / admin-portal提供以下 mock双入口
- **gRPC mock**(供 BFF使用 grpc-mock 拦截 50052 端口Register/Login 返回固定 AuthResponseuser.id="mock-user-001", tokens.access_token="mock-access-token"
- **REST mock**(供 gateway / admin-portalMSW 或 express mock 拦截 /iam/v1/* 路径,返回与 gRPC mock 一致的结构
- **GetPublicKey mock**:返回固定 RS256 公钥 PEM与 mock 私钥配对),供 api-gateway 验签 mock JWT
- **GetChildrenByParent mock**:返回固定 ChildInfo 列表2 个孩子)
- **JWKS mock**GET /iam/v1/.well-known/jwks.json 返回固定 JWK Set
- **Kafka mock**iam 服务就绪前不发布真实事件,下游订阅方使用本地 stub
### 4.2 我消费的 mock
不适用iam 是身份根服务,无业务上游依赖)。