8.3 KiB
8.3 KiB
v0.2 多用户访问模型
本文是 HWLAB v0.2 多用户系统的长期参考口径。目标是先用最少概念支持真实用户使用 code agent session 和管理员分配 device pod 权限,同时避免把用户体系、Kubernetes 租户、设备授权和硬件证据链混成一套复杂门禁。
设计边界
- 用户角色只保留
admin和user。不引入viewer、platform_admin、device_admin、group 或 project。 code agent session直接归属于创建它的用户;普通用户只能查看、继续和取消自己的 session。device pod由admin管理;普通用户只有在被admin授权后才能看到和使用对应 device pod。- device pod 授权不拆分
read、operate或其他 capability;授权关系存在即代表该用户拥有该 device pod 的完整使用权限。 - MVP 不新增产品级
audit_events表,也不把用户权限设计依赖到 audit。现有 M3 trace/evidence/audit 字段属于硬件闭环验收证据,不是多用户权限模型的一部分。 device lease可以保留,但它只解决物理设备并发互斥,不表达用户权限。- 普通用户不获得 Kubernetes 用户、kubeconfig、namespace 管理权或直接访问 device pod Service 的权限;所有用户权限判断在 cloud-api 应用层完成。
简化前后
| 模块 | 复杂方案 | v0.2 MVP 方案 |
|---|---|---|
| 用户角色 | platform_admin、device_admin、developer、viewer |
admin、user |
| 用户组 | groups、group_members |
不引入 |
| 项目隔离 | projects、project_members |
不引入 |
| Code Agent 会话 | ownerUserId + projectId + sessionId |
ownerUserId + sessionId |
| Device Pod 管理 | 平台管理员和设备管理员分工 | admin 统一管理 |
| Device Pod 授权 | 可按 group/project/user 授权 | 只按具体 userId 授权 |
| 设备权限粒度 | device.view、io.read、io.write、debug.reset 等 capability |
授权即全权限 |
| Viewer | 单独只读角色 | 不引入 |
| Audit | 独立用户审计表 | 不引入 |
| Lease | 权限和互斥可能混用 | 只作为设备互斥锁 |
核心数据模型
MVP 只需要以下长期对象:
| 表 | 关键字段 | 说明 |
|---|---|---|
users |
id、username、role、status |
role 只能是 admin 或 user;停用用户不能创建 session 或使用 device pod。 |
code_agent_sessions |
id、owner_user_id、status、created_at、updated_at |
记录 code agent session 的一等归属。 |
device_pods |
id、name、status、profile_ref、gateway_ref |
admin 管理的设备能力单元;profile 仍遵循 device-pod.md。 |
device_pod_grants |
device_pod_id、user_id、created_by_admin_id、created_at |
授权关系表;存在即全权限,不含 capability、scope 或 expires 字段。 |
device_leases |
device_pod_id、holder_session_id、expires_at |
可选互斥锁;防止两个 session 同时烧录、复位或占用同一物理设备。 |
device_pod_grants 应以 (device_pod_id, user_id) 作为唯一约束。撤销授权就是删除该行;如果被撤销用户还有活动 lease,撤销流程必须先释放或标记失效该 lease。
权限矩阵
| 操作 | admin |
user |
|---|---|---|
| 管理用户 | 可以 | 不可以 |
| 创建自己的 code agent session | 可以 | 可以 |
| 查看、继续、取消自己的 code agent session | 可以 | 可以 |
| 查看、取消别人的 code agent session | 可以 | 不可以 |
| 创建、更新、删除 device pod | 可以 | 不可以 |
| 给用户授权或撤销 device pod | 可以 | 不可以 |
| 查看 device pod | 可以查看全部 | 只能查看被授权的 device pod |
| 使用 device pod 的 workspace/debug/io 能力 | 可以使用全部 | 只能使用被授权的 device pod |
| 获取 device lease | 可以 | 只能对被授权的 device pod 获取 |
请求授权链路
cloud-api 每个用户态请求都按同一顺序处理:
authenticate -> actor -> authorize(actor, action, resource) -> optional lease check -> execute
authenticate只负责把 cookie、JWT 或可信 edge identity 解析成本地actor。authorize只使用本地users、code_agent_sessions、device_pods和device_pod_grants判断权限。- code agent result、trace、cancel 和 resume 接口必须校验
session.owner_user_id === actor.id,除非 actor 是admin。 - device pod list/status/job 接口必须校验 actor 是
admin,或device_pod_grants中存在(device_pod_id, actor.id)。 - code agent 调用 device pod 时,cloud-api 必须同时校验 session owner 和 device pod grant,避免用户把自己的 session 指向未授权设备。
Kubernetes 落点
Kubernetes 只做运行时隔离和资源兜底,不承载 HWLAB 用户权限模型:
v0.2默认仍使用单 namespacehwlab-v02,不按用户创建 namespace。- 普通用户不直接持有 Kubernetes RBAC、ServiceAccount token 或 kubeconfig。
- code agent worker、session Pod/PVC/Job 必须带稳定 label,例如
hwlab.pikastech.local/owner-user-id、hwlab.pikastech.local/session-id。 - device pod 工作负载必须带
hwlab.pikastech.local/device-pod-idlabel,并通过 Service 暴露稳定内部地址。 - code agent 到 device pod 的访问应优先收敛到
code agent -> cloud-api -> device-pod,避免普通 session Pod 直接调用 device pod Service 绕过应用层授权。 - ResourceQuota、LimitRange、Pod Security 和 NetworkPolicy 只作为高价值兜底;不要为了多用户 MVP 引入租户级控制面或复杂 admission 门禁。
中间件选择
v0.2 的推荐接入顺序是“先应用层清晰,再逐步加 Kubernetes 兜底”:
- PostgreSQL:作为
users、code_agent_sessions、device_pods、device_pod_grants和device_leases的 source of truth。授权查询简单、可迁移,也能与现有 cloud-api runtime store 收敛。 - OIDC 身份源:需要正式多用户登录时优先选 Keycloak;它同时提供用户、角色和管理控制台。若只需要接入外部 IdP,可用 Dex 做 OIDC broker。
- oauth2-proxy 或等价 edge auth:适合快速保护 Cloud Web,并把 OIDC identity 传给上游;cloud-api 仍必须校验 JWT 或只信任受控内网代理注入的签名身份。
- Kubernetes ServiceAccount + RBAC:只给 HWLAB 服务组件和 session worker 使用,不暴露给最终用户。
- NetworkPolicy:用于阻止 code agent Pod 横向直连 device pod Service;若当前 CNI 不支持,应先作为计划项,不把它伪装成已生效门禁。
- ResourceQuota、LimitRange、Pod Security Standards:防止 session worker 抢占集群资源或使用越权 Pod 配置。
- Kyverno 或 Gatekeeper:仅在需要集群 admission 兜底时引入,第一批策略只覆盖必需 label、禁止 privileged/hostPath、限制镜像来源等高价值规则。
暂不作为 MVP 起点的组件:
- OpenFGA:适合后续出现组织、项目、继承、临时共享或委托授权后再接入;当前
device_pod_grants足够。 - Capsule:适合团队自服务 namespace 多租户;HWLAB 当前不把普通用户映射成 Kubernetes tenant。
- vCluster:适合给租户独立虚拟 Kubernetes API;对 v0.2 权限模型过重。
- Service mesh:可做 mTLS 和细粒度流量治理,但不是两角色 device pod 授权 MVP 的第一依赖。
实现路径
- 先实现本地
users、role、server session/JWT actor 解析,并保留一个 bootstrapadmin。 - 给 code agent session registry 和持久层增加
owner_user_id,所有 result/trace/cancel/resume 路由按 owner 校验。 - 增加
device_pods和device_pod_grants,把/v1/device-pods的 list/status/job 响应改成按 actor 过滤。 - 把 device pod 操作统一封装到 cloud-api 授权入口,禁止 code agent prompt 或 runner 绕过 cloud-api 直连 device pod Service。
- 增加
device_leases互斥逻辑;下载、复位、长时间采样等操作先拿 lease,完成或超时后释放。 - 在
hwlab-v02namespace 添加最小资源兜底:session label、ServiceAccount 边界、resource requests/limits、必要的 NetworkPolicy 和 Pod Security。 - 身份从 bootstrap 用户升级到 OIDC 时,保持
users.id和授权表稳定,只把登录来源替换为 Keycloak/Dex/oauth2-proxy/JWT。