Part of #5852 (contract-first 拆分第二棒,由分诊座位拆)。
Blocked-by: #5858
事实(已核 origin/main)
packages/plugins/plugin-sharing/src/sharing-service.ts:875-880:
const ids = await resolver . resolveOwnerIds (
{
userId : me ,
organizationId : ( context as any ) . organizationId ?? null ,
tenantId : ( context as any ) . tenantId ?? null ,
} ,
scope ,
) ;
真实 HTTP boot 下 spy 抓到的实参是 { userId, organizationId: null, tenantId: "97579948-…" } —— 即 producer 从不填 organizationId,而企业版 resolver 只读它。整条 DEPTH 租户隔离于是永不生效,实测后果见 #5852 (group 姿态下普通成员对兄弟组织 记录 POST /data/:obj/:idB/shares 得 201 ;去掉 BU 锚后同一请求 403,对照行证明翻转的正是 DEPTH 分支)。
爆炸半径不止共享管理:resolveOwnerScopeIds 同样喂给 matchesOwnerScope → canEdit / canDelete / buildWriteFilter。探针那个 app 的写路径另被 member_default 的 owner_only_writes(keyed on created_by)挡下,所以只观测到共享管理一路;不带这条 owner-only RLS 的部署,跨组织 edit/delete 同样放行 。
完成范围(本单)
按 [#5852 契约半边] HierarchyScopeContext 未声明 organizationId / tenantId 哪个权威 —— producer 只填一个、consumer 只读另一个,两边都「符合契约」 #5858 定下的权威字段 填充 resolver context(⛔ 不是在 consumer 侧加 ?? tenantId 兜底 —— 那是 ADR-0057 hierarchy DEPTH: the resolver's tenant isolation never engages — plugin-sharing passes organizationId: null while the active org rides in tenantId #5852 明确不推荐的宽容消费者模式);
补一条断言/门 :真实 exec context 进来时 resolver 收到的权威 org 非空 ;权威字段为空时按 [#5852 契约半边] HierarchyScopeContext 未声明 organizationId / tenantId 哪个权威 —— producer 只填一个、consumer 只读另一个,两边都「符合契约」 #5858 的 doc 义务 fail-closed ,⛔ 不得继续按「无租户约束」构建 owner set;
测试必须用真实 seam 产生的 context ,⛔ 不许再手工构造 { userId, organizationId } —— 这正是本缺陷躲过全部单测的原因(cloud resolver-org.test.ts 喂的是运行时从不产生的形状;framework 侧 canManageShares 的 DEPTH 单测用 stub resolver)。与 fix(security): resolve the issuer's real grants when authorizing invitation placement (ADR-0105 D8) #3695 (authority-less gate context)同一族。
阻塞理由
权威字段由 #5858 定;在它落地前填哪个字段没有权威答案,先做等于把猜测钉进代码。#5858 合入后本单即解锁。
Refs:ADR-0057、ADR-0111 D1 DEPTH、ADR-0105 D2/D6;cloud#919(已 pm:blocked 等本族)、cloud#921
Part of #5852(contract-first 拆分第二棒,由分诊座位拆)。
Blocked-by: #5858
事实(已核
origin/main)packages/plugins/plugin-sharing/src/sharing-service.ts:875-880:真实 HTTP boot 下 spy 抓到的实参是
{ userId, organizationId: null, tenantId: "97579948-…" }—— 即 producer 从不填organizationId,而企业版 resolver 只读它。整条 DEPTH 租户隔离于是永不生效,实测后果见 #5852(group姿态下普通成员对兄弟组织记录POST /data/:obj/:idB/shares得 201;去掉 BU 锚后同一请求 403,对照行证明翻转的正是 DEPTH 分支)。爆炸半径不止共享管理:
resolveOwnerScopeIds同样喂给matchesOwnerScope→canEdit/canDelete/buildWriteFilter。探针那个 app 的写路径另被member_default的owner_only_writes(keyed oncreated_by)挡下,所以只观测到共享管理一路;不带这条 owner-only RLS 的部署,跨组织 edit/delete 同样放行。完成范围(本单)
HierarchyScopeContext未声明organizationId/tenantId哪个权威 —— producer 只填一个、consumer 只读另一个,两边都「符合契约」 #5858 定下的权威字段填充 resolver context(⛔ 不是在 consumer 侧加?? tenantId兜底 —— 那是 ADR-0057 hierarchy DEPTH: the resolver's tenant isolation never engages — plugin-sharing passesorganizationId: nullwhile the active org rides intenantId#5852 明确不推荐的宽容消费者模式);HierarchyScopeContext未声明organizationId/tenantId哪个权威 —— producer 只填一个、consumer 只读另一个,两边都「符合契约」 #5858 的 doc 义务 fail-closed,⛔ 不得继续按「无租户约束」构建 owner set;{ userId, organizationId }—— 这正是本缺陷躲过全部单测的原因(cloudresolver-org.test.ts喂的是运行时从不产生的形状;framework 侧canManageShares的 DEPTH 单测用 stub resolver)。与 fix(security): resolve the issuer's real grants when authorizing invitation placement (ADR-0105 D8) #3695(authority-less gate context)同一族。阻塞理由
权威字段由 #5858 定;在它落地前填哪个字段没有权威答案,先做等于把猜测钉进代码。#5858 合入后本单即解锁。
Refs:ADR-0057、ADR-0111 D1 DEPTH、ADR-0105 D2/D6;cloud#919(已
pm:blocked等本族)、cloud#921