Repository navigation
[Decision] authz: after #21516, a composition that serves authenticated requests without registering the security objects answers 503, not "zero capabilities" — keep it loud (A), or read an unregistered authz object as "not provisioned" (B)? #21599
Description
Ruled: 5974491232 · letter A · 2026-10-03T23:14Z
Filing gate: ② a decision only the maintainer can make. It touches the region of a maintainer-ruled security predicate (2026-08-30, 第 5 场总监席决裁批 #9). Filed by the director seat, summon #32 (session_016tKoy8NJa35Yih1FdzrVmn), from PR #21545's at-tier contract review (record 5969221098, finding R2, "escalate to the maintainer; not blocking"). ⛔ Not a claim.
维护者速读
#21516 让引擎拒绝「注册表里没有的对象名」,已于今天合入(PR #21545)。
副作用:
- 场景:一个组合没有装安全插件的那组系统对象,却在处理已登录用户的请求。
- 以前:读权限表时得到「表不存在」,按你 08-30 的裁决当作「没有开通,零权限」,安静地拒绝每个操作。
- 现在:同样的读取得到「对象未注册」,不再被认作「表不存在」,于是报 503「权限存储不可用」。
影响面:正式发布的启动方式都不受影响,CLI 和 bootStack 都自带安全插件。只有 5 个测试夹具为此补注册了这组对象。
选项:
- A:保持现状(响亮的 503)。没装安全模型属于组合配置错误,应当报出来。
- B:把「对象未注册」也当作「未开通」,回到安静的零权限。
推荐 A。请回一个字母(A / B)。
Background
-
The ruled predicate.
packages/core/src/security/resolve-authz-context.ts,tryFind. The 2026-08-30 ruling (verbatim in the source):- 「
tryFind仅对未被判定为「表未 provision」的读失败抛AuthzStoreUnavailableError(SERVICE_UNAVAILABLE / 503)」; - signed-off risk: 「真 outage ⇒ 响;真未 provision ⇒ 零能力为真答案,不响」.
The source also says "⛔ Do NOT add a second predicate here". The predicate is
isMissingTableError. - 「
-
What [finding] [security] An in-process engine verb passes an object name the registry does not resolve to the driver as a raw table name, so a sandboxed body reads a protected table by a name the data door refuses #21516 changed. The engine's in-process verbs now refuse an unregistered name with
OBJECT_NOT_FOUNDbefore any driver is asked. So an authz read of an object the composition never registered no longer reaches the driver's missing-table error.isMissingTableErrordoes not recogniseOBJECT_NOT_FOUND, sotryFindraises the 503. -
What did not change. The deliberately tested shape
ABSENT_AUTHZ_TABLES(notifications.hono.integration.test.ts): a wired engine whose authz objects are registered but whose tables were never created. It still answers zero capabilities, quietly, through the missing-table path. -
Measured:
- shipped boots are unaffected: the CLI depends on
@objectstack/plugin-security, andserveand bootStack compose it; - in PR fix(objectql): an in-process engine verb refuses an object name the registry does not resolve (#21516) #21545, five harnesses register the authz read set for exactly this reason: four plugin-security files and http-conformance.
- shipped boots are unaffected: the CLI depends on
Options
| What it does | What an operator or author sees | |
|---|---|---|
| A. Keep loud (no change) | An unregistered authz object is a composition error. tryFind keeps its one predicate. |
A host serving authenticated requests without the security model gets a 503 that names the unavailable authz store. Registered-but-unprovisioned keeps the quiet zero-capability answer. |
| B. Read "unregistered" as "not provisioned" | tryFind also treats an OBJECT_NOT_FOUND attributed on the read's own authz object as "not provisioned", so zero capabilities, quiet. That is a second recognised case, in the region the source forbids a second predicate. |
The lean host quietly denies every action again, and a missing security model looks like an empty grant table. |
Business meaning:
- A: a building with no security desk installed reports "security system offline". It does not pretend every visitor was checked and refused.
- B: a missing security desk is treated the same as a desk with an empty guest list.
四维分析
os-decision-facets
- ① 项目长远合理性: 注册表是对象存在与否的唯一事实来源。「未注册」表示这个组合根本没有安全模型,和「已注册但表未建」(08-30 裁决的安静分支)不是一回事。A 让两者各有其答案;B 把配置错误伪装成「零授权」,并且要在明令禁止第二谓词的地方加第二种认定。
- ② 实际业务拉动: 零。正式启动方式都带安全插件,只有 5 个测试夹具受影响,已在 fix(objectql): an in-process engine verb refuses an object name the registry does not resolve (#21516) #21545 内补注册。
- ③ 防 AI 犯错: A 响亮:组合漏装安全插件时立即 503,并点名原因。B 安静:漏装会表现成「所有操作都被拒」,难以定位。
- ④ 创业阶段不扩散: A 什么都不改;B 要在安全谓词区新增一种认定和对应的钉子测试。
Prior rulings read: isMissingTableError / tryFind / AuthzStoreUnavailableError / 2026-08-30 批 #9 → the ruling quoted above; #21516 triage 5964437602 ("refuse"); thread: 0.
推荐:A。 终态句:两年后,「对象是否存在」只问注册表,「表是否建好」只问驱动,安全路径对两者各给一个诚实的答案。只看①选 A;②③④ 是否翻转:否(②零拉动、③响亮、④零改动,均同向)。
回退: B,前提是你认为「未注册」应等同「未开通」。届时须修订 08-30 裁决的谓词描述,而不是在旁边另加一个谓词。
置信缺口: 仓外的嵌入式或精简组合(cloud 的测试宿主等)是否有不装安全插件、却处理已登录请求的情况,未实测。
After the ruling
- A: this card closes
completed, citing the ruling. Optionally, one sentence is added beside the predicate's comment saying an unregistered authz object stays loud, by this ruling. That rides any next change to that file. - B: a
domain:engine/ security card amends the predicate region, with pins for both directions plus the new case, and an at-tier contract review.
Related
#21516 · PR #21545 · the 2026-08-30 ruling (第 5 场总监席决裁批 #9) · notifications.hono.integration.test.ts (ABSENT_AUTHZ_TABLES).
Dedupe: MCP search_issues, scoped to this repo, for 「resolve-authz-context tryFind isMissingTableError unregistered security objects AuthzStoreUnavailableError zero capabilities OBJECT_NOT_FOUND」 → 2 hits, both closed and on other subjects (#15353, #15350).
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 3, 2026
Ruling: batch #275 item 3 · letter A · maintainer 「同意」 2026-10-03T23:13Z
Director seat, summon #32,
session_016tKoy8NJa35Yih1FdzrVmn. Written asobjectstack-fleet[bot]through the relay.The ruling
A: an unregistered authz object stays loud.
AuthzStoreUnavailableError(503), as it does since [finding] [security] An in-process engine verb passes an object name the registry does not resolve to the driver as a raw table name, so a sandboxed body reads a protected table by a name the data door refuses #21516 (PR fix(objectql): an in-process engine verb refuses an object name the registry does not resolve (#21516) #21545,eb9ef791bd).tryFindkeeps its one predicate,isMissingTableError, as the 2026-08-30 ruling (第 5 场总监席决裁批 [WIP] Create a new release version #9) wrote it.ABSENT_AUTHZ_TABLES) keeps the 08-30 quiet zero-capability answer.OBJECT_NOT_FOUNDas "not provisioned". That means a second recognised case in the region the source forbids it, and it disguises a missing security model as an empty grant table.四棱(本裁决新记录)
Execution
completedin this act, citing this record.resolve-authz-context.tsthat an unregistered authz object stays loud by this ruling. It rides the next change to that file.Generated by Claude Code