You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Decision] secrets: should a read of a datasource's definition keep serving external.credentialsRef to every reader that can read the definition? (item 3 of #27818, the maintainer's) #27884
Ruled: 6522945866 · letter B · 2026-10-30T12:39Z
Ruling-ref: 6522945866
Filing gate: ③ maintainer decision split out of a card that is closing (security, rule level only).
From:#27818 item 3. Triage (6512259730) classed it as a security boundary and raised it with the maintainer directly. PR #27860 closes #27818's items 1 and 2, so this card keeps item 3 open. Rule-level text only; mechanism goes to the maintainer off GitHub.
The question
Today a read of a datasource's definition through the metadata read doors serves its external.credentialsRef to every caller that can read the definition. After #27762 and #27818 a reference can no longer be written through any non-system door unless it is the row's own. Should the read doors still serve it?
Option A, keep serving it. The GET → edit → PUT round trip keeps working unchanged, and the write doors hold the rule.
Option B, withhold it from readers below datasource administration (redacted the way the read decorations strip other server-held values). The save door then treats an omitted key as "keep the stored reference" for those callers.
Business reason
The reference is a handle to a stored secret. The write doors are now closed, so this is defence in depth: who needs to see it at all?
Reader: the maintainer. No seat acts on it until it carries a Ruled: line.
⛔ Not a claim. This is the maintainer's decision on a security boundary, split from #27818 item 3. Rule-level text only.
Triage's lean, already given to the maintainer directly: B, withhold the reference from readers below datasource administration, with an omitted key read as "keep".
Director seat, summon #54 continuation 1 (ledger objectstack#12708, opening mark 6493929869). Presented to the maintainer in batch #430 as item 1 of 2 — a security-boundary rule split from #27818 item 3; rule-level text only on GitHub, as the card and triage 6513852880 keep it.
Seat increment (re-read at origin/mainded67bfb, 2026-10-30T03:07Z):
Seat's letter: B — withhold external.credentialsRef from readers below datasource administration through the existing read-decoration seam; the save door treats an omitted key from such a caller as "keep the stored reference" (and still refuses any reference that is not the row's own). Not A: it serves a secret handle to every reader of the definition after the write side was closed to them.
Workload of B: domain:server · 1 PR · S (one redaction arm, one save-door reading, two pins: a non-admin read lacks the key; a non-admin PUT without the key keeps the stored reference) · Clause-②: no (narrowing) of the served read shape for non-admin callers ⇒ one contract-review-tier review before the queue · Metadata-protocol: none.
After the ruling: triage grades into pm:queue (domain:server, area:auth, p1) with Ruling-ref:; mechanism details stay off GitHub per the security discipline.
Ruling: batch #430 item 1 · letter B · maintainer 「27884 B」 2026-10-30T12:33Z
Director seat, summon #54 continuation 1 (ledger objectstack#12708, opening mark 6493929869, brief 6513971173). The maintainer answered in the summon chat, verbatim: 「27884 B」.
What the ruling binds (letter B, rule level): a read of a datasource's definition through the metadata read doors withholds external.credentialsRef from callers below datasource administration, through the read path's existing per-type redaction seam (the one that already strips other server-held values); callers at datasource administration keep seeing it. The save door treats a key omitted by such a caller as "keep the stored reference", so the GET → edit → PUT round trip keeps working for them, and it still refuses any reference that is not the row's own (#27762 / #27818's rule, unchanged). Not taken: A (serving a secret handle to every reader of the definition after the write side was closed to them). Mechanism details stay off GitHub per the security discipline triage 6513852880 keeps; the dev receives them through the lane's channel.
Governing text: #27582 / #27695 (a reference is a handle to a stored secret; own-reference rule), #27722, #27762, #27818 (write and restore doors), triage 6513852880. Premises re-read at origin/mainded67bfb (brief 6513971173).
Workload of the letter:domain:server · 1 PR · S (one redaction arm, one save-door reading, two pins: a non-admin read lacks the key; a non-admin PUT without the key keeps the stored reference) · Clause-②: no (narrowing) of the served read shape for non-admin callers ⇒ one contract-review-tier review before the queue · Metadata-protocol: none.
Execution:needs-user-decision → pm:queue in this act with triage's grade applied (domain:server, priority:p1, area:auth; security stays); the server lane dispatches with Ruling-ref: naming this comment.
os-decision-facets
① 长远:写侧已关闭的值不被永远写不了它的人读回;复用既有脱敏缝,不加第二套机制
② 拉动:本周连续裁定的密钥硬化线(#27582 → #27722 → #27762 → #27818)的读侧收口
③ 防错:密钥把手是侦察信息,隐去是结构性的;「省略即保留」让编辑数据源的作者不会误清空引用
④ 不扩散:不加键不加门禁;一条脱敏臂加一条保存门读法
Activity
objectstack-fleet commentedon Oct 30, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 真挡得住的权限 | none | P②
Triage: p1 ·
domain:server·area:auth· decision · 2026-10-30T02:58Z⛔ Not a claim. This is the maintainer's decision on a security boundary, split from #27818 item 3. Rule-level text only.
Ruled:line appears.Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
director#1 · os-bill · session_01Utp6CbQLcy8yg6vhJVXXi8
Brief-claimed-by: session_01Utp6CbQLcy8yg6vhJVXXi8 · batch #430 · 2026-10-30T03:07Z
Director seat, summon #54 continuation 1 (ledger objectstack#12708, opening mark 6493929869). Presented to the maintainer in batch #430 as item 1 of 2 — a security-boundary rule split from #27818 item 3; rule-level text only on GitHub, as the card and triage 6513852880 keep it.
Seat increment (re-read at
origin/mainded67bfb, 2026-10-30T03:07Z):external.credentialsRef(secrets: confirm the metadata save door for a datasource applies the #27582 own-reference rule toexternal.credentialsRef(a third write door beside #27722's two) #27762;protocol-datasource-credentials-ref.ts,protocol.tsL439 / L21293); secrets: hold a datasource's restore doors and already-stored rows to the #27582 own-reference rule forexternal.credentialsRef(the residue of #27762) #27818 (restore doors and stored rows) is closed by PR fix(metadata-protocol)!: a datasource restored or published from a stored body may name only the credentials reference its row holds now #27860 for its items 1–2, item 3 is this card; the metadata read path has a per-type redaction seam (stripReadDecorations, protocol.ts L183 / L203) that already withholds other server-held values from readers — option B reuses that seam rather than adding a second one.secret:ref from a non-system write, so it can name another record's credential row #27582 / fix(objectql)!: a non-system write to a secret field may only seal a new value or keep its own record's ref #27695 (theField.secret()family: a reference is a handle to a stored secret, and only the row's own reference may be written); secrets: confirm the other stored-reference families (settings-service handles, datasourceexternal.credentialsRef) apply the #27582 own-reference rule at their write doors #27722 (admin doors); secrets: confirm the metadata save door for a datasource applies the #27582 own-reference rule toexternal.credentialsRef(a third write door beside #27722's two) #27762 and secrets: hold a datasource's restore doors and already-stored rows to the #27582 own-reference rule forexternal.credentialsRef(the residue of #27762) #27818 (write and restore doors closed). None rules on the read side.check-prior-rulings.mjsnot run on this card at the seat's choice: the governing texts are the four cards above, all read.secret:ref from a non-system write, so it can name another record's credential row #27582 → secrets: confirm the other stored-reference families (settings-service handles, datasourceexternal.credentialsRef) apply the #27582 own-reference rule at their write doors #27722 → secrets: confirm the metadata save door for a datasource applies the #27582 own-reference rule toexternal.credentialsRef(a third write door beside #27722's two) #27762 → secrets: hold a datasource's restore doors and already-stored rows to the #27582 own-reference rule forexternal.credentialsRef(the residue of #27762) #27818); no customer named it. ③ a handle that names which secret a datasource uses is reconnaissance for anyone who later finds a writable door; withholding it below datasource administration is the loud, structural shape, and "omitted = keep" means an AI author editing a datasource definition cannot accidentally blank the reference. ④ B adds no key and no gate; one redaction arm plus one save-door reading.external.credentialsReffrom readers below datasource administration through the existing read-decoration seam; the save door treats an omitted key from such a caller as "keep the stored reference" (and still refuses any reference that is not the row's own). Not A: it serves a secret handle to every reader of the definition after the write side was closed to them.domain:server· 1 PR · S (one redaction arm, one save-door reading, two pins: a non-admin read lacks the key; a non-admin PUT without the key keeps the stored reference) ·Clause-②: no (narrowing)of the served read shape for non-admin callers ⇒ one contract-review-tier review before the queue ·Metadata-protocol: none.pm:queue(domain:server,area:auth, p1) withRuling-ref:; mechanism details stay off GitHub per the security discipline.Prior rulings read: credentialsRef, own-reference, read door, redaction → #27582, #27695, #27722, #27762, #27818; thread: 6513852880; repo: objectstack-ai/objectstack
objectstack-fleet commentedon Oct 30, 2026
director#1 · os-bill · session_01Utp6CbQLcy8yg6vhJVXXi8
Ruling: batch #430 item 1 · letter B · maintainer 「27884 B」 2026-10-30T12:33Z
Director seat, summon #54 continuation 1 (ledger objectstack#12708, opening mark 6493929869, brief 6513971173). The maintainer answered in the summon chat, verbatim: 「27884 B」.
What the ruling binds (letter B, rule level): a read of a datasource's definition through the metadata read doors withholds
external.credentialsReffrom callers below datasource administration, through the read path's existing per-type redaction seam (the one that already strips other server-held values); callers at datasource administration keep seeing it. The save door treats a key omitted by such a caller as "keep the stored reference", so the GET → edit → PUT round trip keeps working for them, and it still refuses any reference that is not the row's own (#27762 / #27818's rule, unchanged). Not taken: A (serving a secret handle to every reader of the definition after the write side was closed to them). Mechanism details stay off GitHub per the security discipline triage 6513852880 keeps; the dev receives them through the lane's channel.Governing text: #27582 / #27695 (a reference is a handle to a stored secret; own-reference rule), #27722, #27762, #27818 (write and restore doors), triage 6513852880. Premises re-read at
origin/mainded67bfb(brief 6513971173).Workload of the letter:
domain:server· 1 PR · S (one redaction arm, one save-door reading, two pins: a non-admin read lacks the key; a non-admin PUT without the key keeps the stored reference) ·Clause-②: no (narrowing)of the served read shape for non-admin callers ⇒ one contract-review-tier review before the queue ·Metadata-protocol: none.Execution:
needs-user-decision→pm:queuein this act with triage's grade applied (domain:server,priority:p1,area:auth;securitystays); the server lane dispatches withRuling-ref:naming this comment.os-decision-facets
① 长远:写侧已关闭的值不被永远写不了它的人读回;复用既有脱敏缝,不加第二套机制
② 拉动:本周连续裁定的密钥硬化线(#27582 → #27722 → #27762 → #27818)的读侧收口
③ 防错:密钥把手是侦察信息,隐去是结构性的;「省略即保留」让编辑数据源的作者不会误清空引用
④ 不扩散:不加键不加门禁;一条脱敏臂加一条保存门读法