From 7157e59c48007481a87e153995e1b6df7abdaeac Mon Sep 17 00:00:00 2001 From: Codex Agent Date: Fri, 5 Jun 2026 13:19:22 +0800 Subject: [PATCH] docs: distill v02 access cleanup state --- docs/reference/spec-user-access.md | 8 +++++-- docs/reference/spec-v02-cicd.md | 5 ++++ .../spec-v02-openfga-authorization.md | 23 ++++++++++++++----- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/docs/reference/spec-user-access.md b/docs/reference/spec-user-access.md index 74766ee5..82a7b979 100644 --- a/docs/reference/spec-user-access.md +++ b/docs/reference/spec-user-access.md @@ -132,6 +132,8 @@ CREATE TABLE IF NOT EXISTS device_pods ( - 不新增 `capability`、`scope`、`expires_at` 字段;细粒度 relation 不回写到该表,统一写 OpenFGA。 - 在 OpenFGA `enforce` 模式下,撤销授权就是删除对应 tuple;该表若仍有 legacy 行也不能放行请求。 - AgentRun runner 不使用跨用户共享的 device-pod 系统 key。runner 内 `hwpod` 只能使用映射到 Code Agent session owner 的 `HWLAB_API_KEY`,并按同一用户的 OpenFGA device pod relation 与 tool capability 授权。 +- 当前 schema 和 runtime schema ensure 必须以 `DROP TABLE IF EXISTS device_pod_grants` 表达收敛,不得重新出现 `CREATE TABLE IF NOT EXISTS device_pod_grants`。如果 live Postgres 中仍存在该表,应按历史迁移残留处理,迁移或确认无效后删除;不能把它作为健康检查、授权回退或 Admin Access 展示来源。 +- 代码中允许保留的 `device_pod_grants` 引用只限于历史说明、`DROP TABLE` 和“不得创建旧表”的测试断言。Web、CLI、Cloud API 和 AgentRun 路径不得新增旧表读写 helper、旧 grant fallback 或旧 route 兼容入口。 ## 权限矩阵 @@ -203,6 +205,8 @@ browser admin Access UI 撤销授权走 `DELETE /v1/admin/access/users/{userId}/device-pods/{devicePodId}/{relation}`。`/v1/admin/device-pod-grants` 旧全权限入口不再保留;管理员只能通过 Admin Access API 写入或删除 OpenFGA relation。 +旧 `hwpod admin grant`、`device-pod-cli admin grant` 或等价本地全权限 grant 命令不属于 v0.2 授权路径。需要给用户开通 device pod 或工具能力时,统一使用 Admin Access API、Admin Access WebUI 或同路径 `hwlab-cli client access ...`,并按具体 relation 或 `tool:*#can_use` 写入 OpenFGA tuple。 + ### 用户列出 device pod ```text @@ -325,6 +329,6 @@ Kubernetes 只做运行时隔离和资源兜底,不承载 HWLAB 用户权限 | admin/user 两角色模型 | 部分实现 | cloud-api 已实现 `/auth/*`、bootstrap admin、admin/user 创建和 admin-only 路由。 | | `users`、`user_sessions`、OpenFGA relation 和 job 表 | 部分实现 | access-control bootstrap 覆盖 users、sessions、device_pods、access_tuples 和 jobs;Device Pod 强副作用 job 已接入 reason 校验,真实硬件执行仍依赖 gateway/device-host-cli 在线。 | | Code Agent owner 绑定 | 已实现 | 已在 `agent_sessions` 写入 `owner_user_id`、conversation/thread/trace 和脱敏 session evidence;trace/result cache 也按 owner/admin 限制访问。 | -| OpenFGA 细粒度授权模型 | 目标状态 | 需要按 [spec-v02-openfga-authorization.md](spec-v02-openfga-authorization.md) 实现 device pod relation、tool capability、Access API/WebUI/CLI 和 enforce 运行面。 | -| legacy device pod grant 兼容 | 已退出目标路径 | `/v1/admin/device-pod-grants` 和旧全权限 grant fallback 不再保留;历史表只可作为一次性迁移输入,不作为正式授权 authority。 | +| OpenFGA 细粒度授权模型 | 核心已实现/持续约束 | v0.2 enforce runtime 已通过 Admin Access API 和同路径 CLI 管理 device pod relation 与 tool capability;后续扩展仍必须按 [spec-v02-openfga-authorization.md](spec-v02-openfga-authorization.md) 保持同一 authority。 | +| legacy device pod grant 兼容 | 已退出目标路径 | `/v1/admin/device-pod-grants`、旧全权限 grant fallback 和 `device_pod_grants` authority 不再保留;历史表只可作为一次性迁移输入,当前 schema 只允许 `DROP TABLE IF EXISTS device_pod_grants`。 | | 不用 Kubernetes 表达用户权限 | 已实现/持续约束 | 规格明确禁止普通用户持有 kubeconfig 或直连 Service 权限。 | diff --git a/docs/reference/spec-v02-cicd.md b/docs/reference/spec-v02-cicd.md index 746093a7..d0af0ef3 100644 --- a/docs/reference/spec-v02-cicd.md +++ b/docs/reference/spec-v02-cicd.md @@ -78,6 +78,8 @@ CI/CD 内部由 UniDesk 受控触发入口、CI/CD 专用 source repo、devops-i 旧 commit 记忆、`G14`/`G14-gitops` DEV/PROD 产物、D601 legacy 路径、GitHub 上游尚未 flush 的短暂落后、source branch 中历史 generated 文件、固定开发 workspace 脏状态和临时 worktree 只能作为线索,不能作为 `v0.2` 发布通过证据。 +source workspace 中被 `.gitignore` 忽略的 `deploy/gitops/g14/runtime-v02/**` 文件只可能是本地生成缓存。若这类文件与 `v0.2-gitops` 或 live runtime 不一致,应删除本地缓存并以 `v0.2-gitops`、Argo 和 live ConfigMap/Deployment 为准;不要在 source branch 修补 ignored generated 文件,也不要把它们的内容写入 issue closeout 作为发布证据。 + ## Workspace 与 CI/CD 分离 `v0.2` 开发 workspace 和 CI/CD repo 必须分离。`/root/hwlab-v02` 是人工开发、短连接 `hwlab-cli` 和问题复现的固定 workspace;它允许出现并行任务产生的 untracked `.worktree/`、本地 dirty 文件或临时落后状态。CI/CD 不从该 checkout 的 `HEAD`、工作树 clean 状态或本地 branch 读取待发布 commit,也不得因为该 workspace 脏而跳过、误判或复用旧 PipelineRun。 @@ -101,6 +103,8 @@ devops-infra git mirror 仍是 PipelineRun 和 Argo CD 的集群内读写源。` - Tekton/Argo 的 rendered runtime desired state。 - image digest、publish state、reuse evidence 或 CI 生成的 rollout metadata。 +如果权限、schema 或 runtime desired state 发生迁移,必须分别核对 source schema/代码、`v0.2-gitops` rendered YAML 和 live runtime。以 `device_pod_grants` 这类旧路径为例:source branch 应只保留当前 migration/ensure 逻辑,`v0.2-gitops` 与 live ConfigMap 应体现发布后的 rendered state,fixed workspace 下 ignored `runtime-v02/postgres.yaml` 即使存在也不能代表真相。 + `v0.2-gitops` branch 必须包含: - `deploy/artifact-catalog.v02.json`,记录 image tag、digest、source commit、component identity、publish/reuse 状态。 @@ -500,6 +504,7 @@ registry 与 git mirror/relay 分属不同基础设施边界。registry 保持 - runtime path 必须是 `deploy/gitops/g14/runtime-v02`。 - Argo Application 必须是 `hwlab-g14-v02`,且只能部署到 `hwlab-v02`。 - source branch publish 后不得出现 `deploy/artifact-catalog.v02.json` 或 `deploy/gitops/g14/runtime-v02/**` 变更。 +- source workspace 下若残留 ignored `deploy/gitops/g14/runtime-v02/**` 生成物,不能作为 source diff、PR 内容、回归证据或人工修补目标;发现和当前 `v0.2-gitops` 不一致时删除本地缓存。 - GitOps promotion 的 changed paths 只能落在 `deploy/artifact-catalog.v02.json` 与 `deploy/gitops/g14/runtime-v02/**` 及必要的 v02 Argo/GitOps 元数据。 - 公网验收只能使用 `19666/19667`。 - `v0.2` 不得创建或依赖 k8s CronJob;`hwlab-v02-branch-poller`、`hwlab-v02-control-plane-reconciler` 或同类调度器出现时应清理,而不是接入发布链路。 diff --git a/docs/reference/spec-v02-openfga-authorization.md b/docs/reference/spec-v02-openfga-authorization.md index a070898e..ac9ce3f3 100644 --- a/docs/reference/spec-v02-openfga-authorization.md +++ b/docs/reference/spec-v02-openfga-authorization.md @@ -148,6 +148,8 @@ Cloud Web 和 CLI 只能通过 cloud-api 的 admin API 管理授权。第一版 所有 write API 必须要求当前 actor 具备 `access_manager system:hwlab` 或 admin tuple;普通 `user` 不可调用。响应必须包含结构化 `authorization` 字段:`mode`、`allowed`、`decisionSource`、`storeId`、`modelId`、`relation`、`object` 和 redacted actor。 +Cloud Web 必须把 Admin Access 读写 API 作为同源代理路径转发给 cloud-api,包括 `POST /v1/admin/access/check`、`PATCH /v1/admin/access/users/{userId}`、device pod relation 的 `PUT/DELETE` 和 tool capability 的 `PUT/DELETE`。不得在 Cloud Web 本地保留 `/v1/admin/device-pod-grants`、旧全权限 grant fallback 或旧表读取逻辑;旧 route 只可在迁移排查时作为“不存在”的负向烟测,不得作为兼容 API 合同维护。 + ## Admin Access WebUI Cloud Web 新增 ActivityRail 顶层入口 `Access`,只对具备 access manager/admin 权限的用户显示。它不是 Keycloak 管理后台,也不放在 Settings 子页里。 @@ -183,6 +185,10 @@ Cloud Web 新增 ActivityRail 顶层入口 `Access`,只对具备 access manage CLI 输出必须是 JSON,包含 `runtimeEndpoint`、HTTP route、actor 摘要、mode、decision 和变更后的 effective matrix 摘要。它不能直接调用 OpenFGA API,不能手动传 OpenFGA token,不能把 `--base-url 19667` 作为 WebUI 等价验收路径。 +权限变更的真实入口验收必须以 Cloud Web 同源 origin 为准。最小闭环是:`client access summary` 确认 `openfga.mode=enforce` 且 ready;对一个普通用户执行某个 device pod relation 的 `check false -> grant -> check true -> revoke -> check false`;对至少一个工具能力执行同样闭环,`trans_cmd` 必须覆盖;最后 `users inspect` 确认测试 tuple 已撤回。验收报告必须记录 `baseUrl`、method/path、actor、relation/object、HTTP status、OpenFGA decision 和最终 effective matrix 摘要。 + +旧路径清理的验收不以旧 API 兼容为目标。可以用 `POST /v1/admin/device-pod-grants` 返回 Cloud Web `404` 证明旧入口不存在,但源码测试不应为了历史 route 维护长期行为;长期测试只表达 Admin Access/OpenFGA 当前目标路径。 + ## AgentRun 工具能力边界 Cloud API 在创建 AgentRun command/runner 时必须按 OpenFGA 决策装配 transient env 和工具说明: @@ -223,14 +229,19 @@ Cloud API 在创建 AgentRun command/runner 时必须按 OpenFGA 决策装配 tr 阅读 docs/reference/spec-v02-openfga-authorization.md,然后在 runtime endpoint locked 环境运行 `hwlab-cli client access summary/users/check/grant/revoke`,确认全部走 Cloud Web 同源 `19666` path,输出 JSON、route、actor、mode、decision 和 effective matrix;不手动传 OpenFGA URL/token,不直连 `19667` 作为最终 Web 等价验收。 +## T8 + +阅读 docs/reference/spec-v02-openfga-authorization.md 和 docs/reference/spec-user-access.md,然后检查 source schema、`v0.2-gitops` rendered ConfigMap 和 live Postgres:确认 source 不创建 `device_pod_grants`,render/live schema 包含 `DROP TABLE IF EXISTS device_pod_grants`,live `information_schema.tables` 中该表数量为 `0`。只允许历史说明、DROP 和“不得创建旧表”的测试断言引用该名称。 + ## 规格的实现情况 | 规格项 | 状态 | 说明 | | --- | --- | --- | -| OpenFGA 作为 v0.2 内部授权服务 | 目标状态 | 需要 GitOps resource、Postgres backend、migration 和 cloud-api readiness。 | -| Cloud API OpenFGA client/bootstrap/check/write | 目标状态 | 需要 `enforce`、store/model 指针、tuple write 和 structured decision。 | -| 细粒度 device pod / session / tool 授权 | 目标状态 | 替代旧“device pod grant 即全权限”口径。 | -| Admin Access WebUI | 目标状态 | 新增 admin-only ActivityRail 页面,不直接调用 OpenFGA。 | -| 同路径 CLI | 目标状态 | 新增 `client access ...`,走 Cloud Web 同源 path。 | -| AgentRun 工具注入按用户权限过滤 | 目标状态 | `hwpod`、`unidesk_ssh`、`trans_cmd`、GitHub 写工具都必须独立授权。 | +| OpenFGA 作为 v0.2 内部授权服务 | 已实现/持续约束 | v0.2 runtime 以 `enforce` 模式运行,summary 暴露 redacted store/model 和 readiness;OpenFGA 不向公网、浏览器或 CLI 暴露。 | +| Cloud API OpenFGA client/bootstrap/check/write | 已实现 | Admin Access API 可 check/write tuple,响应包含 structured decision 和 redacted OpenFGA 状态。 | +| 细粒度 device pod / session / tool 授权 | 核心已实现/持续扩展 | device pod relation 和 tool capability 已替代旧全权限 grant;后续 session/tool 扩展必须继续写 OpenFGA tuple。 | +| Admin Access WebUI | 部分实现/持续约束 | Cloud Web Access 页面使用同一 Admin Access API;浏览器交互深测可作为专项验收,但不得新增第二条授权路径。 | +| 同路径 CLI | 已实现 | `client access ...` 走 Cloud Web 同源 path,已覆盖 summary、users、check、device pod relation grant/revoke 和 tool grant/revoke。 | +| AgentRun 工具注入按用户权限过滤 | 部分实现/持续约束 | `hwpod`、`unidesk_ssh`、`trans_cmd`、GitHub 写工具必须独立授权;实现和验收不得退回共享系统 key。 | +| legacy `device_pod_grants` authority | 已退出目标路径 | source schema 不再创建旧表,runtime schema ensure 保留 DROP,旧 `/v1/admin/device-pod-grants` 不作为 API 合同。 |