mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
# ADR-0210:Owner 围栏化 Local Identity/Credential 查询
|
||||
|
||||
- 状态:Accepted
|
||||
- 日期:2026-07-29
|
||||
- 关联 RFC:QL-RFC-0001 D-05、D-27、D-37、D-65、D-72、D-73、D-175、
|
||||
D-197、D-198、D-199、D-200
|
||||
- 关联 ADR:ADR-0074、ADR-0075、ADR-0077、ADR-0086、ADR-0185、
|
||||
ADR-0207、ADR-0208、ADR-0209
|
||||
|
||||
## 背景
|
||||
|
||||
ADR-0209 已提供 Identity/Credential mutation 的产品入口,但每次 mutation 都要求
|
||||
`expectedCurrentVersion`。部署者若只能直接查询 SQLite 才能取得该版本,会产生三个
|
||||
问题:
|
||||
|
||||
- 运维流程必须知道存储表结构,产品契约与实现泄漏;
|
||||
- 普通 credential 行包含 secret digest 和 pepper provenance,直接查询扩大敏感面;
|
||||
- 查询没有复用 Owner authorization、credential fence 与 Security Audit。
|
||||
|
||||
单纯在服务层 authorize 后调用普通 `resolve` 也不安全。actor credential 或 Owner
|
||||
RoleBinding 可能在 authorization 与读取之间变化,造成已撤权主体继续读取管理状态。
|
||||
|
||||
## 决策
|
||||
|
||||
### 1. 扩展既有边界,不新增 package 或 migration
|
||||
|
||||
能力分别进入既有精确 subpath:
|
||||
|
||||
- runtime-core 定义 authorized inspection repository contract;
|
||||
- local-admin 提供 Owner-only inspection service;
|
||||
- local-sqlite 实现事务围栏读取与 audit;
|
||||
- local-owner-cli 在既有 `ql3-identity` 增加产品命令。
|
||||
|
||||
不新增第 23 个 package、数据库表、第三方依赖、daemon、timer、watcher、listener 或
|
||||
远程管理 API。Edge/Standalone 常驻 application closure 不导入该 authority。
|
||||
|
||||
### 2. v1 只提供精确查询
|
||||
|
||||
开放:
|
||||
|
||||
- `identity.inspect`:按 exact `{subject.type, subject.id}` 查询;
|
||||
- `credential.inspect`:按 exact credential ID 查询。
|
||||
|
||||
command 使用 current UID `0600` private file。request 只包含 `projectId`、target 或
|
||||
credential ID、`requestId` 和 UUIDv4 `auditEventId`。查询不是 mutation,不接受
|
||||
mutation ID、failure-audit ID 或 expected version。
|
||||
|
||||
本切片不提供 list/search/pagination。精确查询足以获得后续 CAS 所需版本,同时避免
|
||||
为低配设备引入目录扫描、游标状态或大结果集。
|
||||
|
||||
### 3. Owner authorization 与读取在最终事务重新围栏
|
||||
|
||||
服务要求 strong User Principal,并固定申请 `project.manage`。deny、
|
||||
approval-required 和 policy-unavailable 先写低敏 audit,再返回统一错误。
|
||||
|
||||
SQLite 使用 `BEGIN IMMEDIATE`,在读取前重新验证:
|
||||
|
||||
1. 本命令认证 credential 的 version/state、Identity、时间窗与 pepper provenance;
|
||||
2. Project active 状态和 Policy fence project version;
|
||||
3. actor 最新 RoleBinding 的 version/state/Owner role。
|
||||
|
||||
随后读取最新 Identity 或 credential revision、写入 allowed audit,并一次提交。任一
|
||||
围栏漂移都回滚读取对应的 allowed audit,并失败关闭。
|
||||
|
||||
### 4. 不存在语义和输出必须低敏
|
||||
|
||||
只有完成 Owner authorization 与事务围栏后,精确对象不存在才返回 `found:false`。
|
||||
未授权请求不得根据对象是否存在返回不同结果。
|
||||
|
||||
允许输出:
|
||||
|
||||
- Identity:subject、status、version、created/updated time;
|
||||
- credential:ID、subject、subject status、state、version、created/not-before/
|
||||
expires time。
|
||||
|
||||
禁止输出 secret digest、pepper key ID、token、credential presentation、数据库路径、
|
||||
绝对交付路径或内部 mutation/audit 行。
|
||||
|
||||
## 替代方案
|
||||
|
||||
### 直接提供 SQLite 查询文档
|
||||
|
||||
拒绝。它把 schema 变成产品 API,绕过权限与 audit,并暴露本来无需展示的敏感列。
|
||||
|
||||
### authorize 后调用普通 repository resolve
|
||||
|
||||
拒绝。authorization 与读取不共享最终数据库 transaction,存在 credential revoke
|
||||
或 Owner demotion TOCTOU。
|
||||
|
||||
### 新建只读管理 daemon 或 HTTP API
|
||||
|
||||
拒绝。当前需求是本机短生命周期运维;常驻进程会增加路由设备内存、端口和攻击面,
|
||||
Cluster 也有独立 transport/authority。
|
||||
|
||||
### 立即提供 Identity/Credential list
|
||||
|
||||
暂不采用。list 需要分页、稳定 cursor、容量与枚举策略;精确 inspect 已解决 CAS
|
||||
版本发现,不应扩大本切片。
|
||||
|
||||
## 影响
|
||||
|
||||
正向影响:
|
||||
|
||||
- 部署者不再直接访问 SQLite 即可完成 inspect → CAS mutation;
|
||||
- 查询与 mutation 使用相同 Owner、credential 和 Policy fence;
|
||||
- 已授权 not-found 有明确机器可读语义,输出不暴露 credential 验证材料;
|
||||
- 低配设备没有新增常驻成本,workspace 保持 22 package。
|
||||
|
||||
代价与限制:
|
||||
|
||||
- 每次 inspect 都是短写事务,因为 allowed audit 必须与读取 authority 同事务;
|
||||
- 相同 `auditEventId` 不作为可重复消费的查询 cursor,重复人工执行应生成新 command;
|
||||
- v1 不支持批量列表,operator 必须知道 exact subject 或 credential ID;
|
||||
- Cluster 仍需独立实现 PostgreSQL/RBAC 查询 transport。
|
||||
|
||||
## 验证
|
||||
|
||||
- strict targeted TypeScript 编译覆盖 runtime contract、local-admin、local-sqlite 与 CLI;
|
||||
- service 测试证明 Owner allow、admin/non-Owner deny 与 deny audit;
|
||||
- 真实 SQLite/CLI 测试证明 Identity/Credential 当前 version、已授权
|
||||
`found:false`、allowed audit 与低敏 JSON;
|
||||
- TOCTOU 测试在 policy authorize 后追加较新 non-Owner binding,最终 transaction
|
||||
必须抛出 authorization fence conflict;
|
||||
- dependency audit 继续证明能力没有进入 Edge/Standalone 常驻 closure;
|
||||
- 完整 workspace、artifact/RSS 与 PostgreSQL HA 门在锁定依赖恢复后重跑。
|
||||
Reference in New Issue
Block a user