Skip to content

[Decision] security(runtime): may an app-authored body still READ the stored-metadata family's tables, served projected, or is that refused too (#21454 option C) #21594

Description

@objectstack-fleet

Ruled: 5978653398 · question 1 letter A — host handlers keep the projected read; ruling B covers sandboxed bodies only · 2026-10-04T09:48Z

Ruled: 5974479930 · letter B · 2026-10-03T23:14Z

Filing gate: ② a decision only the maintainer can make. It is a security boundary, and the existing rules do not decide it. Filed by the triage seat (objectstack-wide, seat post #6015, session_01AavokzJ5DndAwitDXvKy4U). It carries option C of #21454 (5963137791, 5963161540). Triage named C as the maintainer's option and did not rule it (5963299937). #21454 closed completed on disposition A, so C had no carrier. ⛔ Not a claim, ⛔ not a dispatch. ⛔ Classes, doors and roles only.

Reader who acts: the maintainer, or the director seat. If the letter is B, the domain:cli seat dispatches it on this card.

维护者速读

Measured, read now (origin/main 901e7cf13a)

Governing text

一句话问题

应用代码现在能读到「元数据存储表」的遮蔽版内容。要保留这个读法,还是让应用代码彻底碰不到这组表、只能走元数据接口?

选项 × 真实代价

选项 做什么 客户可感知的后果
A 维持 什么都不做。读照常遮蔽,危险查询照常拒绝 无变化。平台继续维护接缝上的遮蔽、按列判定和搜索收窄,作为长期义务
B 读也拒绝 在同一接缝处,应用代码读这组表直接返回明确的拒绝,提示走元数据接口 实测零个应用代码读这组表,所以今天谁也不受影响。以后有人这么写,会立刻收到清楚的报错,而不是拿到半遮蔽的数据

业务含义直译

四轴(业务立场)

  • 实际业务需求: 实测零拉动,示例应用和 HotCRM 里都没有应用代码读这组表。A 维护的是一个没人用的能力;B 拒绝的也是没人用的读法,今天不伤任何人。
  • 项目长远合理性: B 让「应用代码与元数据存储表」只剩一条规矩:完全不碰,元数据走元数据接口。它和 [Decision] security(runtime): may an app-authored body touch the stored-metadata family's tables at all — a hook bound to them, or an elevated body writing them directly (#21454 items 3 and 4) #21520 的 A 对齐。A 留下「写不能、读可以但要遮蔽」的双轨,每新增一种查询形状,都要再判一次。
  • 防 AI 犯错: 出错时谁看到什么?A 下,AI 写的代码去读这组表,会拿到遮蔽后的数据并继续运行,作者以为拿到了真实内容,这是静默的。B 下,作者立刻看到一条点名元数据接口的拒绝,这是响亮的。
  • 创业阶段不扩散: B 是移除一个能力,A 是声明并长期维护一个能力。按「移除优于声明并维护」,B 更省。

os-decision-facets

Prior rulings read: 21454 option C, outright, refuse family reads, [Decision] stored-metadata → 2 hits (#21454 5963299937, which named C the maintainer's; #21520 5965059068, letter A, writes and hooks only); ADR none; thread: #21454.

推荐:B。 两年后的样子:应用代码通过元数据接口读到有类型、已遮蔽的定义,从不直接查原始存储表。参照 Salesforce:定义经 Schema describe 和 Metadata API 提供。但它的 Tooling 对象也能被查询,所以这只是方向参照,不是全封闭的先例。
回退:A。 已落地的遮蔽接缝原样保留,不加门,读侧零风险。
自检: 只看①选 B;②③④ 是否翻转:否。三轴同向,只影响时序:B 可以在 #21520 的认领之后单独一个 PR。
置信缺口: 我看不到私有客户的应用包,零拉动只覆盖 objectstack examples 和 hotcrm。常设规则「新门默认否」偏向 A。B 是新增的拒绝,所以维护者不回字时按 A 处理。

裁后执行

Activity

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

Metadata

Metadata

Assignees

Labels

area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsdomain:clipriority:p2Medium: important, M3security

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions