Skip to content

tracking(authz): 双轨赛道下的授权改进开发任务 v2(内核链 ADR 待编号 + 补齐轨 + 地基) #2920

Description

@os-zhuang

背景:双轨赛道决策

授权系统竞争力赛道已拍板 = 双轨:主轨打「AI-native / 开源」叙事(结构化授权可 lint/explain/diff + 开源自托管 + 包 provenance),补齐轨只挑 2 项接近「能卖」的企业能力。据此重排开发任务,「层级 RLS 开源落地」删除(留企业侧当卖点,IHierarchyScopeResolver 可插拔 seam 已就位、开源版 fail-closed 到 owner-only)、合规认证 / PSG 不排期(按需触发 / 后置)。

已拆出的独立 issue:#2917(管理员手册)、#2918(行写护栏)。本 issue 汇总其余全部开发任务,交由接手 agent 执行。

修订说明

v2(2026-07-14):原版经落点级核实后重写,核实证据见评估评论。要点:「内核链 ADR-0094」引用失效(编号被占)改为新前置任务 B0;B1 落点更正(rls-engine.ts 不存在);原 B3 并入 B2;原 A5 前提不成立已重写;A3 已完成过半估算下调;「待核实 Q7」无出处移除。

v2.1(2026-07-14)

  1. B0 已落地:ADR-0095 成文,PR docs(adr): ADR-0095 — authz kernel chain: tenant isolation as Layer 0, posture ladder, capability-derived posture (B0 of #2920) #2924(draft,评审中)。起草过程中发现新证据 W1compileFilter 把含 tenant_isolation 在内的全部适用策略 OR 合并rls-compiler.ts),与 ADR-0066 文档的「tenant-global AND 在上」语义存在分歧——一条宽松业务 RLS 策略在 RLS 层足以放行跨租户行(是否实际暴露取决于 driver 层 applyTenantScope 半缝是否兜住)。这使 B1 同时是「修复文档与实现的语义分歧」,ADR-0095 已把该修复列为行为保持工作中唯一的、显式声明的行为变更(安全修复)。
  2. B5 已否决(maintainer 决策,2026-07-14):PG 原生 RLS 兜底不做,理由记入 ADR-0095 Alternatives(cloud 拓扑已物理隔离;唯一受益方是 EE shared-DB 模式,代价是 PG-only 防线破坏可移植性 + GUC/连接池风险 + 测试矩阵翻倍)。仅当 shared-DB SaaS 形态成为一等产品时重启。
  3. C1 解锁:cloud 仓库已接入本会话 scope,可以评估与执行。

v2.2(2026-07-18,收口):全部开发任务已交付合并并随 15.1.0(2026-07-17)发布,checkbox 补勾;完成状态逐项核实见复核评论。唯一移交的开发缺口——ADR-0099 P0–P2 实现——已另立 #3211 跟踪。本 issue 关闭。


依赖与执行顺序

  • 立即并行开工(不碰内核热路径):A3、A4、A5 + C2-α(explain 契约扩展)+ C1。
  • 串行主线(工程日历瓶颈):B0(评审中)→ B1 → B2 → B4。B1 动手前先把矩阵门下沉到单元层。
  • C2-β(双端实现):契约定稿后可与 B 后段并行。

估算:本 issue 剩余范围合计 ≈ 35–59 PD(B0 已出稿;B5 已否决;含 C1 5–8 PD 待复核)。B 组内核链是关键路径,加人压不动。


A. 地基层(独立并行)

  • A3 — 用户页一站式分配入口(剩余部分)feat(platform-objects): A3 — 用户页 Permission Sets + Business Units 分配入口 (#2920) #2927

    • 现状:Positions tab 已落地packages/platform-objects/src/pages/sys-user.page.ts L141-177,ADR-0090 D3,即目标 record:related_list + add.picker 模式本身)。
    • 剩余:照抄该模式补 Permission Sets(直接授权,junction sys_user_permission_set,picker 对象 sys_permission_set)+ Business Units(junction sys_business_unit_member,picker 对象 sys_business_unit)两个 tab。两 junction 对象定义均已存在(plugin-security / platform-objects/identity)。
    • objectui:零改动plugin-detail/src/RelatedList.tsx 的 add.picker 与 name-keyed junction 已完整支持)。
    • 判据:管理员在单个用户页完成岗位/权限集/BU 三类分配;直授路径须过 delegated-admin gate(浏览器 dogfood 验证被拦/放行两侧)。
    • 估:1–2 PD
  • A4 — 权限来源三态统一 + 露出(platform / package / admin) → framework feat(plugin-security): A4 — managed_by 三态统一 + listView 露出 (#2920) #2934 + objectui Dashboard-level filters (date / region) driving multiple charts #2501

    • 真实工作是三态语义统一,不只是加列。现状不一致:sys_capability = platform/package/admin(select,listView 已有列);sys_permission_set = platform/package/user(text,列已有);sys_position = system/config/user(text,listView 缺列)。
    • 内容:(1) 统一三对象 managed_by 取值词表与字段类型(以 sys_capability 的 select 三态为准,migration/兼容映射 user→admin、system/config→platform/package 需在实现时确认历史数据);(2) sys_position listView 补列;(3) objectui 二态徽标扩三态(PermissionMatrixEditor.tsx L529-538 现仅 Package/Custom)+ i18n key(metadata-admin/i18n.ts)。
    • 注意:Studio AccessPillar 按 provenance 过滤掉 platform 默认集(StudioDesignSurface.tsx L2979-2986),三态徽标落 Setup 记录页链路而非 Studio 矩阵。
    • 判据:管理员一眼分清「平台发的 / 应用发的 / 自己建的」(与 feat(plugin-security): 内置行写护栏 — sys_position / sys_capability 平台/应用托管行可被删改 #2918 互补);三对象词表一致。
    • 估:2–3 PD
  • A5 — 包级 capability 声明 API(原「声明链打通」重写)feat(spec,plugin-security): A5 — 包级 capability 声明 API (#2920) #2932

    • 现状更正:capability 单一真源已成熟(packages/spec/src/security/capabilities.ts + bootstrap-system-capabilities.ts 从 permission set 的 systemPermissions 自动派生 seed);不存在「应用声明又复制进 spec」的重复,契约名是 requiredPermissions/systemPermissions(无 inputs)。
    • 重写后的目标:给一个正式的 capability 声明入口(如 defineCapability),使应用/包自带的 capability 带 managed_by:'package' + package_id provenance 流入 registry,而非依赖「从 systemPermissions 隐式派生」;配套文档明确「capability ≠ contract,资源用 requiredPermissions 引用、包用声明 API 定义」。呼应 ADR-0094 D5 的「managed_by:'user' 类逐步退役」方向。
    • 判据:示例应用演示包级声明→boot seed→sys_capability 带包 provenance 全链;文档/skill 更新。
    • 估:2–4 PD

B. 主轨 · 内核链(严格串行,ADR-0095)

高 blast-radius,动的是授权热路径。每步落在 role × object × expected-visible-rows 矩阵快照门后推进。矩阵雏形在 packages/dogfood/test/authz-conformance.matrix.ts(集成层)——B1 动手前先把矩阵门下沉/复制到单元层plugin-security 测试内)。行为契约与 W1 例外见 ADR-0095。

  • B0 — 内核链 ADR 成文ADR-0095docs/adr/0095-authz-kernel-tenant-layer-and-posture-ladder.md),PR docs(adr): ADR-0095 — authz kernel chain: tenant isolation as Layer 0, posture ladder, capability-derived posture (B0 of #2920) #2924 评审中。回答了拓扑问题(Layer 0 的承重场景 = ADR-0093 multi shared-DB 模式;ADR-0073 的「跨租户 RLS 不存在」声明限定于物理拓扑);否决 PG 兜底;记录 W1 分歧。

  • B1 — 拆租户隔离为 Layer 0(ADR-0095 D1)feat(plugin-security): B1 — 租户隔离拆为 Layer 0(ADR-0095 D1 + 四处授权 delta)(#2920) #2933

    • 落点:packages/plugins/plugin-security/src/rls-compiler.ts(租户过滤与业务 RLS 现为同一 pass、OR 合并 = W1)+ security-plugin.ts computeRlsFilter(posture-gated bypass 是唯一短路点,一个 bit 同时短路两层 = W2)+ objects/default-permission-sets.tstenant_isolation 通配策略,Layer 0 落地后从 seed 退役)+ packages/core/src/security/resolve-authz-context.ts
    • 内容:专属 tenant-layer 模块,消费 ADR-0093 tenancy service;multi 模式对租户对象无条件 AND organization_id == ctx.organization_id,始终在先、与业务 RLS 分离代码路径;豁免规则按 ADR-0095 D1(PLATFORM_ADMIN posture × 对象 posture 允许)。
    • 判据:矩阵快照门锁行为;唯一允许的 delta 是 W1 修复(宽松业务策略 × 异租户行 → 不可见),作为显式安全修复带专属矩阵行。
    • 估:8–13 PD。依赖 B0 合并。
  • B2 — posture 阶梯(ADR-0095 D2,含 EXTERNAL 档位预留)feat(core,plugin-security): B2+B4 — posture 阶梯 + capability 派生 (ADR-0095 D2/D3, #2920) #2938(与 B4 同 PR)✅

    • 落点:packages/core/src/security/resolve-authz-context.ts
    • 内容:单调 enum PLATFORM_ADMIN > TENANT_ADMIN > MEMBER > EXTERNAL,每档恰好一条注入规则、严格嵌套(rung n 可见集 ⊇ rung n-1,作为被测不变量)。EXTERNAL 语义现在锁死(仅显式共享、永不 OWD、误配只能更少),实现等 portal/external 主体类型出现后另立 issue(对齐 ADR-0093 membership)。
    • 判据:resolve-authz-context.test.ts 升级为 role×object×expected-rows 矩阵快照 + 嵌套不变量断言;EXTERNAL 有枚举级语义锁测试。
    • 估:8–13 PD。依赖 B1。
  • B4 — posture 从 capability 派生(ADR-0095 D3)feat(core,plugin-security): B2+B4 — posture 阶梯 + capability 派生 (ADR-0095 D2/D3, #2920) #2938

  • B5 — Postgres 原生 RLS backstop已否决(v2.1 修订说明第 2 条;理由见 ADR-0095 Alternatives)。


C. 补齐轨 · 企业能力(只挑 2 项)


执行须知(踩过的坑 / 约束)

  1. worktree-first(Prime Directive Migrate documentation site to Fumadocs with monorepo structure and shared content #11:改文件前每仓开专属 worktree(framework / cloud / objectui 各自),别在共享 main checkout 上动手,会被并发 agent reset 抹掉。guard hook 会拦 Edit/Write。
  2. 双轨约束:层级 RLS 留企业侧(C1),别放进开源;PSG 聚合层、合规认证不在本轮排期
  3. B 组矩阵门:B 组是行为保持的分层加固,不是改「谁能看什么」;除 ADR-0095 声明的 W1 修复外,矩阵快照暴露的任何 delta 是 bug 不是 feature。先把矩阵门下沉到单元层再动 B1
  4. ObjectQL 键是 where 不是 filterfindOne/find 的过滤键写错会被静默忽略(历史上锁错 admin,dogfood 才抓到)。
  5. 谓词裸字段会 fail-closed 静默隐藏按钮/行:写 visible/RLS 谓词先查 objectstack-ui / objectstack-formula skill,os build 现会拦裸字段。
  6. 验证:改动要浏览器 dogfood 实测 + 截图,别只读代码推断(尤其 A3/A4/C2 的 UI)。

关联

#2917 · #2918 · epic #2776(Permission Model v2 parking lot)· #2909(两存储类型审计)· ADR-0095 / PR #2924(B0)· ADR-0066 / 0073 / 0090 / 0093 / 0094 · v1→v2 评估评论 · #3211(ADR-0099 P0–P2 实现,收口移交)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions