Files
qinglong/docs/adr/ADR-0272-bounded-authorized-cluster-automation-inspection.md
T

82 lines
6.1 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.
# ADR-0272:有界且授权原子的 Cluster Automation Inspection
- 状态:Accepted
- 日期:2026-08-04
- 关联:D-85、D-207、D-208、D-239、D-241、D-242、D-253、ADR-0259
## 上下文
Cluster Automation Management 已能通过独立的 TLS 1.3、mTLS、用途绑定 OIDC 进程发布
TaskDefinition 与 Trigger,但部署者无法通过同一受支持产品面检查当前定义或做有界列表。让用户直接查询
PostgreSQL、把读取能力放进常驻 `cluster-control`,或返回 Task/Trigger 的完整 spec,都会分别绕过
Policy/audit、扩大 runtime authority,或泄漏脚本正文和调度表达式。
读取也存在撤权竞态:仅在事务外完成 Policy precheck,然后读取 Task/Trigger,会允许 Project、RoleBinding
或 Identity 在两个动作之间变化。另一方面,Edge/Standalone 已有短生命周期本机入口,不能为了 Cluster
能力给路由设备增加 listener、Pool 或依赖闭包。
## 决策
1. 在既有 `ql3-automation-manage``ql3-automation-client` 中增加
`task.inspect``task.list``trigger.inspect``trigger.list`;不新增 workspace package、进程、端口、
Pool、migration、表、timer 或 watcher。
2. 所有读取继续要求 TLS 1.3、mTLS、`automation-management` 用途绑定 OIDC 与 strong UserTask 使用
`task.read`Trigger 使用 `trigger.read`。request 必须携带独立 UUID v4 `auditEventId`;列表上限复用
Runtime Core 的 256 硬上限和稳定 keyset cursor,禁止 offset 与无界列表。
3. 新的 Runtime Core administration-source contract 只表达授权后的 inspect/list,不赋予 mutation。PostgreSQL
adapter 在一个 SERIALIZABLE 快照事务中复验 exact active Project 与 latest active RoleBinding
version、拒绝重复 auditEventId、
读取 current head/一页结果、append-only 写 allowed audit,再提交。
4. PostgreSQL 读取必须通过独立只读 `PostgresTaskDefinitionSource`/`PostgresTriggerSource` 执行;management
service 不取得裸 SQLruntime/control 不取得 automation-manager 权限。事务失败、围栏变化、重复审计或
存储损坏均失败关闭。
5. 产品响应只返回低敏 summary:稳定 ID、current revision、kind/enabled、content digest、更新时间与
Trigger 的 Task pin;不返回 name、description、labels、spec、mutationId、createdAt、Principal、
authenticationId、Policy reason 或 audit identity。不存在返回显式 `absent`,列表始终返回固定形状的
`tasks|triggers/truncated/next`
6. Edge/Standalone 保持现有短生命周期本机入口和零 Cluster 常驻成本。Cluster HA 继续使用既有两个
management Pod、每 Pod Pool 2、port 8445 与已有数据库角色;本决策不把管理面装入路由 Profile。
7. 读取不是弱一致的“免费查询”:每次 inspect/list 都必须原子持久化 allowed audit。生产 HA 使用
`synchronous_commit=remote_apply` 时,如果主库已提升但尚无同步备库,读取会在事务超时后失败关闭,
不允许为了查询可用性绕过审计耐久性或降为异步提交。旧主完成 `pg_rewind`、以只读同步备库重入后,
同一产品入口恢复成功;客户端应以新的 request/audit identity 重试。
## 被拒绝的方案
- **让 Cluster Control 直接读取 Automation 表**:扩大常驻执行面的数据库权限与攻击面。
- **读取不记 audit**:无法解释谁在何时枚举了可执行定义。
- **Policy precheck 后用独立查询读取**:存在 RoleBinding/Project/Identity 撤权竞态。
- **返回完整 Task/Trigger record**:会把脚本正文、参数、标签和 cron expression 带出管理边界。
- **新增只读管理 package/service**:现有用途隔离进程、身份、限流和 Pool 已是正确部署 owner。
- **offset pagination 或客户端指定 revision**:前者不稳定且可能无界,后者把当前 head 选择权外移。
## 验证要求
- Runtime contract 覆盖 exact-shape、UUID v4 audit identity、cursor/page hard bound 与 audit/fence binding
- PostgreSQL adapter 证明 Project snapshot→RoleBinding fence→read→audit→COMMIT 顺序,
fence 变化、重复 audit 与读取失败均无部分提交;
- management service/transport/client 覆盖四个命令、Policy permission、absent、分页与 content-free 输出;
- process composition 证明 disabled 仍不开 Pool/文件,enabled 只复用既有 Pool/HTTPS
- 完整 package/back、dependency/package-boundary/edge/local-image、十档 artifact 与 PostgreSQL HA 门保持通过。
## 验证结果
- Runtime Core 435/435、Cluster PostgreSQL 275 pass/1 条件 skip、Cluster Admin
256 pass/2 条件 skip;四个 inspection 命令的 exact-shape、分页、低敏结果、Policy 与事务失败关闭均已覆盖;
- 完整 19-package 门退出 0,后端为 1,095 pass/2 条件 skip/0 fail;十档 Edge/Standalone
artifact 均为 compatible,最小 Edge 为 3,514,849 bytes/324 files/10,665,984 bytes RSS,最大
Standalone Application AI 为 5,882,164 bytes/474 files/20,578,304 bytes RSS
- dependency、package-boundary、edge-import、cluster-deployment 与 local-image 审计均为 compatible
workspace 保持 19 个 package;未增加 dependency、migration、表、进程、listener、port、Pool、timer
或 watcher
- PostgreSQL 18.4 arm64 physical-streaming HA 门总 `passed=true`allowed audit 与读取结果原子提交、
提升前 `remote_apply` 复制、无同步备库时读取失败关闭、timeline 1→2 promotion,以及旧主
`pg_rewind`/同步重入后的 Task/Trigger inspect/list 恢复均已由独立 gate 证明;
- 受保护的 `ql3-cnpg-evidence-control-plane` 未被测试夹具纳入资源集合,启动状态、restart policy
与 restart count 保持不变;本轮随机 `ql3-ha-*` 容器、网络与卷由 fixture 精确清理。
## 影响
Cluster 部署者可以通过同一用途隔离管理入口发现发布后的 Task/Trigger 当前状态,不再需要数据库直连。
能力成本只由显式启用 Cluster Automation Management 的部署承担;路由器与 Standalone 不增加常驻开销。