mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(ql3): materialize package secret bindings
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
|
||||
- D-304/ADR-0392(已接受):Plugin Package 进入安全 quarantine 时,Workflow/Prompt automation publication 不再仅依赖运行时 start guard 间接拒绝,而是与 quarantine event、Package-owned Task disabled revisions、Project Tool snapshot 和 withdrawal receipt 在同一 SQLite/PostgreSQL 事务中收敛为 `withdrawn`。原先仅能引用普通 lifecycle event 的外键升级为 append-only disposition-event 联合引用,历史 migration 与 publication digest schema 保持不变;SQLite edge/standalone 崩溃矩阵覆盖 automation publication insert 后、event/task/receipt/COMMIT 前后,PostgreSQL 通过触发器在既有 `SECURITY DEFINER` quarantine commit 内登记 disposition,再由同一外层 SERIALIZABLE transaction CAS publication head。能力位为 `plugin_package_automation_security_withdrawal@1`;不新增 package、daemon、timer、连接或常驻缓存,适用于低配路由设备和集群节点。SQLite 全量 228/228;PostgreSQL package 311 pass/1 条外部 URL 条件 skip;完整 18-package build/test 退出 0,backend 1,188 pass/2 skip,package/dependency boundary 零 finding;PostgreSQL 18.4 arm64 HA 125 项 gate 全绿、timeline `1→2`,报告 SHA-256 为 `ab156901b9c96ec5a62259c44d83d24ded011e0616dc827d928f3e13efd11786`。
|
||||
- D-305/ADR-0393(已接受):Plugin Package Manifest 的逻辑 Secret requirement 获得按 resource generation 固定的不可变 binding。binding 精确覆盖 Manifest requirements,只保存同 Project、显式 version 的 `qlsecret://` 引用与 `approved-action-execution|local-owner-confirmation` authority evidence digest,不保存 Secret 明文;required 不可为空,optional 可显式为 `null`。发布由当前 active installation head、lock、generation 与 Manifest digest 联合 fencing,相同事实幂等、不同事实冲突;domain-separated digest、最多 64 项和 64 KiB 单行预算同时约束 Local 与 Cluster。SQLite 追加 `0091` ledger 与 capability v46,PostgreSQL 追加 `pg-0059`、capability v58,并只向 package executor 授予 `SELECT, INSERT`。不新增 package、daemon、timer、watcher、连接、缓存或集群 workload,低配路由设备只承担一个有界表和三个索引。D-305 不冒充 Secret 已进入执行路径:现有 materialization 拒绝仍保留,D-306 再完成用户授权、Secret resolution、runtime consumption 与 lifecycle/rebinding 语义。core 509/509、SQLite 232/232、PostgreSQL 316 pass/1 条件 skip;完整 18-package clean build/test 退出 0,backend 1,188 pass/2 skip,五项边界审计零 finding,workspace 仍无 single-source/shallow-source package。PostgreSQL 18.4 arm64 HA 125 项 gate 全绿、timeline `1→2`,报告 SHA-256 为 `acf0fea7ca7699989dfe70f5dd0061cdf5fb1968c691094331fea06ce01b96dc`。
|
||||
- D-306A/ADR-0394(已接受):Package Task source 以 `package-secret` placeholder 引用逻辑 requirement,materialization 只用当前 generation 的 D-305 binding 编译为已有、固定 version 的 Task `SecretRef`;Package source 直接携带 SecretRef、缺失 binding、未批准 `secret.use`、跨 binding 引用和 optional/required 漂移全部失败关闭。binding 快照不含明文并进入 materialized revision digest,Local/Cluster 启动发布复用既有 repository/pool,Task dispatch、Local 短时解密和 Cluster offer/lease-fenced delivery 不另造协议。SQLite/PostgreSQL INSERT trigger 同时防止直接写库绕过;Local 只读 readiness 继续不加载 DDL。Local contract v47、Cluster v59;不新增 package、表、索引、连接、daemon、watcher、timer、cache 或 workload。完整 18-package clean build/test 退出 0;backend 1,188 pass/2 条件 skip/0 fail;五项 package/dependency/edge/service-manager/local-image 审计零 finding,workspace 仍无 single-source/shallow-source package,两个有序 migration ledger 精确为 PostgreSQL 61、SQLite 95 个 source;PostgreSQL 18.4 arm64 HA 125 项 gate 全绿、timeline `1→2`,报告 SHA-256 为 `f9107e8e54892a788779758f0573ac8d6a80f6d086516a1f5f5bbacb59bbb4be`。D-306A 不冒充产品闭环:Local bind/rebind 命令、Cluster Approved Action/API 与新 generation rotation/revocation 编排属于 D-306B。
|
||||
- D-302/ADR-0390(已接受)
|
||||
Cluster operator context 增加无网络、无 mutation 的内建 `ql3-cluster-admin context validate` 预检。它先复用 owner-private context
|
||||
reader,再让每个 entry 经过与真实请求相同的 production HTTPS/Kubernetes configuration preparation,验证精确 route、hostname、CA、
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# ADR-0394:按 Generation 固定的 Plugin Package Secret Materialization
|
||||
|
||||
- 状态:Accepted
|
||||
- 日期:2026-08-13
|
||||
- 关联 RFC:QL-RFC-0001 D-306A
|
||||
- 关联 ADR:ADR-0151、ADR-0153、ADR-0393
|
||||
|
||||
## 问题
|
||||
|
||||
D-305 已把 Package 的逻辑 Secret requirement 固定为不可变、按 generation 绑定的版本化 `qlsecret://` 引用,但 Task source 仍不能消费该绑定。若在 dispatch 时才按 requirement 名称查找,会使 materialized revision 与实际 Secret 版本脱节;若允许 Package source 直接携带部署方 SecretRef,又会绕过安装方授权。
|
||||
|
||||
Local/Edge 还要求只读 readiness 不加载 migration 执行模块,且不能因 Secret-aware Package 引入 watcher、缓存、连接或常驻进程。Cluster 必须在直接数据库写入时也拒绝未绑定或越权的 SecretRef。
|
||||
|
||||
## 决策
|
||||
|
||||
1. Package Task source 以 `{kind:"package-secret", requirement:"NAME"}` 引用 Manifest 的逻辑 requirement,不允许直接写 `kind:"secret"` 或 `qlsecret://`。
|
||||
2. materialization 读取当前 generation 的 D-305 binding,把逻辑 requirement 编译为已有、固定版本的 Task `SecretRef`;optional 且显式绑定为 `null` 的环境项被省略。普通 Task dispatch、Local 短时解密和 Cluster offer/lease-fenced delivery 继续复用现有执行链,不增加新的 Secret 传输协议。
|
||||
3. materialized revision 嵌入完整 binding 快照但不含明文,binding 与最终资源共同进入 revision digest。任何 Task SecretRef 必须属于该快照;Manifest 声明 Secret 时缺失 binding 或 `secret.use` capability 均失败关闭。
|
||||
4. SQLite 与 PostgreSQL 在 materialized revision INSERT 边界增加触发器,拒绝畸形 Secret 声明、未解析 placeholder、缺失/不匹配 binding 和 binding 外 SecretRef,防止绕过 core repository 直接写库。
|
||||
5. SQLite 的触发器 SQL 真源位于非执行型 schema contract;migration 与 readiness 共同引用,保持只读 readiness 和 rollout-safety 不加载 DDL 模块。Local contract 升至 v47,Cluster 升至 v59。
|
||||
6. 实现复用既有 SQLite authority、PostgreSQL pool、Task Secret resolution 与 Worker delivery,不增加 package、表、索引、连接、timer、watcher、cache、Pod 或 daemon。Local 仅增加一个 INSERT trigger,Cluster 增加一个 trigger function 与一个 INSERT trigger。
|
||||
|
||||
## 生命周期与阶段边界
|
||||
|
||||
- binding 与 materialized revision 均按 generation 不可变;Secret 新版本不会静默改变既有 generation。
|
||||
- Package disable/quarantine/uninstall 继续由现有 generation/lifecycle start guard 阻止新执行;已开始执行仍遵循既有 Run/Worker 清理语义。
|
||||
- D-306A 完成 runtime consumption 和数据库防绕过,不宣称产品授权闭环完成。面向用户的 Local bind/rebind 命令、Cluster Approved Action/API,以及通过新 generation 执行 rotation/rebinding/revocation 的编排属于 D-306B。
|
||||
|
||||
## 资源与部署影响
|
||||
|
||||
| Profile | 增量 | 常驻开销 |
|
||||
| --- | --- | --- |
|
||||
| Edge / Standalone | 一个 INSERT trigger;启动发布按需点查一个既有 binding row | 无新增进程、连接、缓存、timer 或 watcher |
|
||||
| Cluster | 一个非 `SECURITY DEFINER` trigger function 和一个 INSERT trigger;复用 executor pool | 无新增角色、连接、workload、sidecar 或 worker |
|
||||
|
||||
## 验证
|
||||
|
||||
- core:placeholder 编译、optional-null、省略、直接 SecretRef/缺失 binding/越权引用拒绝、revision digest 与 normalize round-trip。
|
||||
- SQLite:真实 migration、畸形声明与未绑定 SecretRef 直接 INSERT 拒绝、readiness DDL lazy boundary、rollout safety、edge/standalone contract。
|
||||
- PostgreSQL:migration checksum、trigger/function、固定 search path、权限撤回、schema/readiness 与 physical-streaming HA gate。
|
||||
- 完整 18-package clean build/test 退出 0;backend 共 1,190 项,1,188 pass、2 条件 skip、0 fail。
|
||||
- package boundary、cluster dependency、edge import、service-manager bridge import、local image 五项审计零 finding;workspace 保持 18 package、1,090 source、1,072 nested source,`singleSourcePackages=[]`、`shallowSourcePackages=[]`。两个经审查的 `ordered_ledger` 目录精确为 PostgreSQL 61 与 SQLite 95 个 migration source,通用密集目录门禁未放宽。
|
||||
- PostgreSQL 18.4 arm64 HA Docker gate 共 125 项全绿,timeline `1→2`;私有报告 SHA-256 为 `f9107e8e54892a788779758f0573ac8d6a80f6d086516a1f5f5bbacb59bbb4be`。
|
||||
@@ -397,6 +397,7 @@
|
||||
| [ADR-0391](./ADR-0391-read-only-cluster-operator-context-readiness.md) | Read-only Cluster Operator Context Readiness | Accepted |
|
||||
| [ADR-0392](./ADR-0392-atomic-plugin-package-automation-security-withdrawal.md) | Plugin Package Automation 安全隔离原子撤回 | Accepted |
|
||||
| [ADR-0393](./ADR-0393-generation-bound-plugin-package-secret-binding-ledger.md) | 按 Generation 固定的 Plugin Package Secret 绑定账本 | Accepted |
|
||||
| [ADR-0394](./ADR-0394-generation-bound-plugin-package-secret-materialization.md) | 按 Generation 固定的 Plugin Package Secret Materialization | Accepted |
|
||||
|
||||
## 规则
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
"reviewedDenseDirectories": [
|
||||
{
|
||||
"kind": "ordered_ledger",
|
||||
"maxDirectSourceFiles": 60,
|
||||
"maxDirectSourceFiles": 61,
|
||||
"path": "packages/ql3-cluster-postgres/src/migrations",
|
||||
"rationale": "PostgreSQL migrations are an append-only version ledger whose ordering and discoverability are safer in one reviewed directory."
|
||||
},
|
||||
{
|
||||
"kind": "ordered_ledger",
|
||||
"maxDirectSourceFiles": 93,
|
||||
"maxDirectSourceFiles": 95,
|
||||
"path": "packages/ql3-local-sqlite/src/migrations",
|
||||
"rationale": "SQLite migrations are an append-only version ledger whose ordering and discoverability are safer in one reviewed directory."
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user