Repository navigation
Closed
Closed
Copy link
Labels
area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsPermissions that actually hold — RLS/FLS, sharing model, write-path guardsdomain:servicesRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landedRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landedpriority:p1High: required for production / M2High: required for production / M2securitytarget:v18
Description
Ruled: 6094985249 · letter A · 2026-10-10T07:11Z
Filing gate ②:只有维护者能做的决定。这是一条安全边界,放宽必须由维护者裁。分诊席(seat post #6015,session_01AavokzJ5DndAwitDXvKy4U)立卡。起因是总监记录 6094171670(objectui#7611,batch #310 第 1 项)里的一个前提,与代码实测不符。⛔ 不是认领。读者:总监席呈报。 Ruled A (6094985249); carriers objectui#7611, #15204, #22619.
维护者速读
你上一小时问「以后岗位、权限集是不是就不能在界面上添加了?」,总监答「组织管理员照旧能在 Setup 里新建和编辑」。实测今天的情况是:组织管理员从来不能改岗位和权限集,它们对这几张表只读,这是专门防止组织管理员给自己挂上「全权管理员」权限集的防提权规则。今天能在 Setup 里建岗位的是平台管理员,切换后平台管理员照样能建,服务端不用改。
所以问题变成:切换后要不要新放开给组织管理员?
- A:不放开,保持今天的权限;
- B:新增一个窄权限,可以授给指定的安全管理员;
- C:在单租户下直接放开给组织管理员。
推荐 A。选 A、B 还是 C?
背景(实测:objectstack origin/main e22315238f,hotcrm、cloud main)
- 组织管理员今天是只读:
packages/plugins/plugin-security/src/objects/default-permission-sets.ts:426-431注明 RBAC 表禁止写入,「Allowing them would let an org admin bindadmin_full_access… to themselves」。:475-477把sys_position、sys_permission_set、sys_position_permission_set都设为只读。单租户下组织管理员拿到的是派生变体organization_admin_no_bypass,它照抄这几条(auto-org-admin-grant.ts:84-90)。组织管理员也不持有manage_metadata(:418)。 - 平台管理员今天能写:
admin_full_access持有manage_metadata(packages/spec/src/identity/eval-user.zod.ts,ADMIN_FULL_ACCESS_CAPABILITIES.systemPermissions),元数据门的写闸metaWriteCapabilityVerdict(metadata-core/src/meta-write-capability.ts:79-93)只放行系统调用和持有manage_metadata的人。 - 撤表之后: 「对目录对象的增删改授权」随四张表一起消失,写入只剩元数据门这一条路,闸就是
manage_metadata。 - 影响面实测为 0: objectstack、hotcrm、cloud 里没有任何声明的权限集授予这四个对象的新建或编辑权限(只有上面那几条只读)。运行时在 Studio 里建的自定义权限集无法从代码测量。
Governing text
- ADR-0131 D2:Setup「keeps the security-administration authority an organization admin holds today (the object grants on the catalog)」。今天组织管理员持有的授权就是只读。
- 防提权注释(上引
:426-431)。 - 规矩:安全边界由维护者定,放宽一律升级。
选项 × 真实代价 × 开发工作量
| 选项 | 做什么 | 客户能感知的后果 | 工作量 |
|---|---|---|---|
| A 保持今天的权限 | 切换后只有持 manage_metadata 的人(平台管理员)能在 Setup 和 Studio 写岗位、权限集、能力;组织管理员只读 |
与今天一致,无人感知变化 | 0 行服务端代码;C9 的对等验收按此改写 |
| B 新增窄权限 | 新增一个只管安全目录的系统权限,元数据门对这三类元数据接受它;平台管理员默认持有,可授给指定人 | 可以设立不碰 Studio 的「安全管理员」 | spec 新增一个系统权限,元数据门闸加一类,约 300–600 行;新增公开面 |
| C 单租户下放开给组织管理员 | 元数据门在单租户下接受组织管理员对这三类的写入 | 组织管理员可以给自己挂上全权管理员权限集,等于提权 | 约 200–400 行;⛔ 推翻防提权规则 |
四轴(从业务看)
- 项目长远合理性: A 保持一条规则:定义由元数据作者管。B 多一个窄权限,属于真实的权限分层,但目前没有人在用。C 打破防提权边界。
- 实际业务拉动: 声明面实测为 0,今天没有任何应用把目录写权交给非平台管理员。
- 防 AI 犯错: A 和 B 都是响亮拒绝(403 并说明需要的权限)。C 会让 AI 生成的组织管理员角色悄悄拿到提权路径。
- 创业阶段不扩散: A 什么都不加。B 加一个永久权限。C 最危险。
os-decision-facets
- ① 项目长远合理性:A 一条规则,不增生;B 增生一个窄权限;C 打破防提权边界。
- ② 实际业务拉动:声明面实测为 0,今天没人把目录写权交给非平台管理员。
- ③ 防 AI 犯错:A、B 响亮拒绝;C 静默提权。
- ④ 创业阶段不扩散:A 不加东西;B 加一个永久权限;C 不可取。
Prior rulings read: ADR-0131 D2/D3/D7; 6094171670(objectui#7611 的对等验收文字); 6094045326(#22601 B); 防提权注释 default-permission-sets.ts:426-431; thread: none.
推荐:A,回退 B(有具名用户需要「不碰 Studio 的安全管理员」时再加)。
- 自检:只看①选 A;②③④ 是否翻转:否。
- 置信缺口:已部署环境里在 Studio 建的自定义权限集是否授予了目录对象的写权,代码测不到。切换的升级仪式(C7)可以在
--plan里点名列出这类授权。
裁后执行
- 选 A:
- objectui#7611 的对等验收改写为:单租户下平台管理员(持
manage_metadata者)在 Setup 新建、编辑、停用和重新启用岗位与权限集,与今天一致;组织管理员只读,界面说明原因。 - 切换计划(refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write under
singleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204)里不再有「元数据门对组织管理员放行」这一项。 - C7a(C7a (ADR-0131 D10, split from #15211): the migration inventory file, the read-only
os migrate --plan, and the design of the ceremony's completion marker #22617)的--plan列出授予目录对象写权的自定义权限集。
- objectui#7611 的对等验收改写为:单租户下平台管理员(持
- 选 B: 立 spec 卡加这个窄权限,并入切换批次。
- 选 C: 先立 ADR 修订卡,写明防提权规则的例外与守卫。
Metadata
Metadata
Assignees
Labels
area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsPermissions that actually hold — RLS/FLS, sharing model, write-path guardsdomain:servicesRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landedRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landedpriority:p1High: required for production / M2High: required for production / M2securitytarget:v18
Activity
objectstack-fleet commentedon Oct 10, 2026
Ruling: batch #311 item 1 · letter A · maintainer 「同意」 2026-10-10T07:10Z
Director seat, summon #36,
session_019fWAt2renophxLVg5aJXMH(GitHubhotlong; written asobjectstack-fleet[bot]via the relay). Batch #311 (three cards, this one first) was presented in chat with this seat's own readings and the recommendation A, fallback B; the maintainer answered 「同意」, which takes the recommendation. Freshness gate: the body (6,054 bytes, unedited since filing) and the comment list (none) were re-read before this record. Thread-read: none on this card.The ruling
metaWriteCapabilityVerdict: a system write, or a caller holdingmanage_metadata(the platform administrator, throughadmin_full_access). Organization administrators stay read-only on the catalog in every posture, as the anti-escalation rule indefault-permission-sets.ts(lines 426–431 and 475–479 onorigin/maine22315238f) has had it: letting them write would let an organization administrator bindadmin_full_accessto themselves. Setup's catalog pages show them the catalog read-only and say why.single: a privilege-escalation path and a reversal of the anti-escalation rule, never a seat's to grant).Why A on the first axis
One rule: definitions belong to metadata authors, and the authority to author metadata is
manage_metadata. A adds nothing and corrects a premise rather than a boundary. ADR-0131 D2's "the security-administration authority an organization admin holds today (the object grants on the catalog)" names an authority that, read against the code, is read-only, so A is the literal reading of D2, and D7's "for capability holders" is the accurate wording. B and C both widen; only B is ever admissible, and only on pull.Corrections this ruling makes
single) as owed by the cutover. The premise was the ADR's sentence, not the code; the triage seat measured the code (this card), and the objectui lane already amended its copy (objectui#7611, 6094498192). The parity gate on objectui#7611 reads instead: undersingle, the platform administrator (amanage_metadataholder) creates, edits, deactivates and reactivates positions and permission sets from the same Setup page as today; an organization administrator sees the catalog read-only, with the reason. The "server half" item is withdrawn from the cutover plan (refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write undersingleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204).singlerequiresmanage_metadata; D7's "for capability holders" is the accurate wording. No decision of the record changes.Prior rulings read: ADR-0131 D2/D3/D7; the anti-escalation rule (
default-permission-sets.ts:426-431,:475-479);metaWriteCapabilityVerdict(metadata-core/src/meta-write-capability.ts:79-93);ADMIN_FULL_ACCESS_CAPABILITIES(eval-user.zod.ts:141,manage_metadata); S7's system-context definition write (position-write-through.ts:112); #22601 B (6094045326); batch #310 item 1 (6094171670); thread: none. 自检:只看①选 A;②③④是否翻转:否。State and execution
completedin this act;needs-user-decisionleaves with the close;priority:p1,security,domain:services,target:v18,area:accessstay. The body gains itsRuled:line in the same act.singleand refused under a wall (ADR-0131 D2/D3/D5/D13) #15204 (the cutover plan drops the server-half item; C7a's--planon C7a (ADR-0131 D10, split from #15211): the migration inventory file, the read-onlyos migrate --plan, and the design of the ceremony's completion marker #22617 lists any custom permission set that grants a write on the four catalog objects), docs(adr-0131): §8/D14 execution-plan note — C2's remainder and C3 land as one cutover, C7 splits into C7a/C7b, and C12 moves to the 18.x line (rulings 6094045326, 6094175435, 6094183024) #22619 (the D2/D3 dated sentence). Workload of the chosen option, as the rule requires: zero server lines; C9's acceptance text rewritten.Generated by Claude Code
refactor: remove the retired permission-set catalog object's special …