← issue #2297 (split mTLS cell allow-set)· 来源 PR #2481 review finding F2 (pm:pr-review)· /fix #2481 深挖后维护者决策:延后至下一 PR、采用 Tier3 。
现状
cellmodules/celltls 的 cert↔hosted-cells 最小权限 guard 在默认 / monolith 拓扑 下不生效,#2297 的最小权限承诺只在显式 split(role) 拓扑成立。
证据
cellmodules/celltls/celltls.go:172 validateCertCoversColocated:hosted := topo.ColocatedCells(); if len(hosted) == 0 { return nil } —— 空集直接跳过精确匹配。
framework/runtime/bootstrap/deployment_topology.go:77-89 SpecForRole:role=="" 且 len(groups)<=1 → 返回空 DeploymentTopologySpec{}。
cmd/corebundle/modules_gen.go:107 generatedTopologyGroups() 返回 nil(assembly 无 topology.groups)→ corebundle shared_deps.go:156-160 SpecForRole(nil, "") → 空 spec → ColocatedCells() 空。
examples/ssobff/app.go:396-400 直接 NewDeploymentTopology(DeploymentTopologySpec{})(空 spec)。
guard 仅在 TLS material 已配置时(celltls.Resolve case 4)才会到达;即「monolith + 配了 mTLS material」时校验被静默跳过。
三维根因
代码层 :DeploymentTopologySpec.Colocated 被重载——split 时 = role 的 group cells(本进程承载的子集,guard 正常);monolith 时 = 空(但语义其实是「全部本地 cell」)。
架构层 :同一个空 DeploymentTopologySpec 同时表达「all-colocated 但本地 cell set 未知」与「确无本地 hosted cells」,TLS guard 没有可靠输入。
历史层 :[auth] split mTLS per-caller-cell 身份 resolver(解除一进程一 cell 限制) #2297 引入 guard 时 ColocatedCells() godoc 注明「bootstrap has no assembly cell set」——但 composition root 其实有 :corebundle 的 generatedCellModules()(codegen,modules_gen.go:15,每个 CellModule.ID() 即 cell id)、ssobff 的已知 cell 集 / 后续 asm.CellIDs()(app.go:901)。缺口只在 monolith 分支。
影响 :monolith / 默认拓扑 + 配 mTLS material 的进程,其「本地 workload cert 的 cell-SAN 集合 == 本进程承载 cell 集合」最小权限校验当前被静默跳过 → 一张多签或欠签的 cert 不会在启动期 fail-closed。P1 安全缺口(opt-in 边界:仅当配置了 TLS material 才触及;显式 split 拓扑不受影响)。
修复方向(深挖记录见 PR #2481 pm:fix + /fix 讨论)
Tier1 最小 :两个 composition root 各自在 monolith 时把本地 cell 集合塞进 spec.Colocated。改动小,但「monolith → 全部本地 cell」规则在两 root 重复、第三个 root 易漏,非单源。
Tier2 彻底 :SpecForRole(groups, role, localCells)——monolith 分支 Colocated=localCells(split 分支不变,role cells 已正确);规则单源在 SpecForRole,两 root 各喂自己的 codegen/已知 cell 集。
★ Tier3 重构(本 issue 选定方向) :把 deployment topology 拆为两个 sealed 值——placement-routing (哪些 cell 远程 + endpoint)与 local-hosted-identity-set (本进程承载的 cell 集合,恒有值)。TLS 最小权限 guard 只消费后者,ColocatedCells() 恒非空,彻底消除 Colocated 的「role 子集 vs 全部本地」重载。
需配套:ADR 修订(202606131142-1423 cell-deployment-topology + 202606171200-2263 cross-cell-transport-mtls,同步重评威胁矩阵 ,per ai-robust「ADR amendment 落地时必须同步重评原 ADR 安全模型」);更新/解冻 archtest DEPLOYMENT-TOPOLOGY-SEALED-FIELD-FROZEN-01(字段集变更);改 corebundle + ssobff 接线。独立 PR。
Files
cellmodules/celltls/celltls.go:162-202(validateCertCoversColocated / certExtraCells / certCellSet)
framework/runtime/bootstrap/deployment_topology.go(DeploymentTopology / DeploymentTopologySpec / SpecForRole / ColocatedCells / IsColocated)
cmd/corebundle/shared_deps.go:156-160,254-259 + cmd/corebundle/modules_gen.go:15,107(generatedCellModules / generatedTopologyGroups)
examples/ssobff/app.go:396-400
tools/archtest(DEPLOYMENT-TOPOLOGY-SEALED-FIELD-FROZEN-01)
docs/architecture/202606131142-1423-adr-cell-deployment-topology.md + docs/architecture/202606171200-2263-adr-cross-cell-transport-mtls.md
Source
PR #2481 review finding F2 [P1·Cx3·安全/权限](pm:pr-review,← issue #2297 )。/fix #2481 修复了同轮 F1/F3/F4 并深挖 F2;维护者决策:F2 延后至下一个 PR、采用 Tier3 重构。
现状
cellmodules/celltls的 cert↔hosted-cells 最小权限 guard 在默认 / monolith 拓扑下不生效,#2297 的最小权限承诺只在显式 split(role) 拓扑成立。证据
cellmodules/celltls/celltls.go:172validateCertCoversColocated:hosted := topo.ColocatedCells(); if len(hosted) == 0 { return nil }—— 空集直接跳过精确匹配。framework/runtime/bootstrap/deployment_topology.go:77-89SpecForRole:role==""且len(groups)<=1→ 返回空DeploymentTopologySpec{}。cmd/corebundle/modules_gen.go:107generatedTopologyGroups()返回nil(assembly 无topology.groups)→ corebundleshared_deps.go:156-160SpecForRole(nil, "")→ 空 spec →ColocatedCells()空。examples/ssobff/app.go:396-400直接NewDeploymentTopology(DeploymentTopologySpec{})(空 spec)。celltls.Resolvecase 4)才会到达;即「monolith + 配了 mTLS material」时校验被静默跳过。三维根因
DeploymentTopologySpec.Colocated被重载——split 时 = role 的 group cells(本进程承载的子集,guard 正常);monolith 时 = 空(但语义其实是「全部本地 cell」)。DeploymentTopologySpec同时表达「all-colocated 但本地 cell set 未知」与「确无本地 hosted cells」,TLS guard 没有可靠输入。ColocatedCells()godoc 注明「bootstrap has no assembly cell set」——但 composition root 其实有:corebundle 的generatedCellModules()(codegen,modules_gen.go:15,每个CellModule.ID()即 cell id)、ssobff 的已知 cell 集 / 后续asm.CellIDs()(app.go:901)。缺口只在 monolith 分支。影响:monolith / 默认拓扑 + 配 mTLS material 的进程,其「本地 workload cert 的 cell-SAN 集合 == 本进程承载 cell 集合」最小权限校验当前被静默跳过 → 一张多签或欠签的 cert 不会在启动期 fail-closed。P1 安全缺口(opt-in 边界:仅当配置了 TLS material 才触及;显式 split 拓扑不受影响)。
修复方向(深挖记录见 PR #2481 pm:fix + /fix 讨论)
spec.Colocated。改动小,但「monolith → 全部本地 cell」规则在两 root 重复、第三个 root 易漏,非单源。SpecForRole(groups, role, localCells)——monolith 分支Colocated=localCells(split 分支不变,role cells 已正确);规则单源在SpecForRole,两 root 各喂自己的 codegen/已知 cell 集。ColocatedCells()恒非空,彻底消除Colocated的「role 子集 vs 全部本地」重载。202606131142-1423cell-deployment-topology +202606171200-2263cross-cell-transport-mtls,同步重评威胁矩阵,per ai-robust「ADR amendment 落地时必须同步重评原 ADR 安全模型」);更新/解冻 archtestDEPLOYMENT-TOPOLOGY-SEALED-FIELD-FROZEN-01(字段集变更);改 corebundle + ssobff 接线。独立 PR。Files
cellmodules/celltls/celltls.go:162-202(validateCertCoversColocated/certExtraCells/certCellSet)framework/runtime/bootstrap/deployment_topology.go(DeploymentTopology/DeploymentTopologySpec/SpecForRole/ColocatedCells/IsColocated)cmd/corebundle/shared_deps.go:156-160,254-259+cmd/corebundle/modules_gen.go:15,107(generatedCellModules/generatedTopologyGroups)examples/ssobff/app.go:396-400tools/archtest(DEPLOYMENT-TOPOLOGY-SEALED-FIELD-FROZEN-01)docs/architecture/202606131142-1423-adr-cell-deployment-topology.md+docs/architecture/202606171200-2263-adr-cross-cell-transport-mtls.mdSource
PR #2481 review finding F2 [P1·Cx3·安全/权限](
pm:pr-review,← issue #2297)。/fix #2481修复了同轮 F1/F3/F4 并深挖 F2;维护者决策:F2 延后至下一个 PR、采用 Tier3 重构。