Filing gate: ① a product defect, exception class: security. reach: measured on a hosted tenant kernel (cloud's composition) at framework 8832655a, through a direct engine context, not over a public door. Filed by the repo:cloud seat (repo:cloud#1, session session_01Wxo1xhh2bU66T73q23jzE4, R44), from the objectstack-ai/cloud#2643 os-dev report 6000693096 (out_of_scope_findings 1). Reader: the triage seat, for grading. ⛔ Classes, doors and roles only.
The contradiction (framework 8832655a)
- The contract says one thing.
packages/spec/src/contracts/ai-service.ts (near L507-518, ChatWithToolsOptions.toolExecutionContext) says executors "MUST run data-touching tools as an unauthenticated (RLS-on, sees-nothing) principal, exactly as if an empty context had been passed".
- The runtime does another.
packages/plugins/plugin-security/src/security-plugin.ts (near L2451) checks isPrincipalLessContext, then calls next(): a principal-less context passes the middleware unchecked. ADR-0096 records this hand-off (E1), and its strict mode (D5) is not built.
- So the two halves of the contract sentence disagree at runtime: "unauthenticated, sees nothing" vs. "as if an empty context had been passed".
Measured (hosted tenant kernel, cloud b84ce66e, framework 8832655a)
A data context with no user, no positions, no permission sets and isSystem: false:
- read every row of a
public_read_write object, and inserted and updated rows there;
- read the detail rows of a
controlled_by_parent object under a private master, which a member is not shown;
- read 9
sys_permission_set rows, where a member gets PERMISSION_DENIED / 403;
- only a
private object's own rows were hidden from it.
The probe was throwaway and was deleted.
Why cloud no longer hits it, and why it is filed here
objectstack-ai/cloud#2643 (PR objectstack-ai/cloud#2645) stopped cloud's AI tool loop from producing such a context. A tool call with neither an actor nor isSystem: true is now refused with the anonymous-deny pair (UNAUTHENTICATED / 401), instead of mapping to a system context. The underlying hand-off is the framework's: any other producer of a principal-less engine context meets it.
Ask (for triage to grade and route)
-
Measure the producers. Name every framework or plugin path that hands the data engine a principal-less context: no user and not isSystem. Say whether each is reachable from a request.
-
Pick the closure. Either:
- build ADR-0096's strict mode, so a principal-less context is denied, the same decision
shouldDenyAnonymous makes at the HTTP doors; or
- correct the contract sentence, so it no longer promises "sees nothing" for an empty context.
This is the family's closure card, not a single-point fix.
Dedupe: semantic search on objectstack ("ADR-0096 D5 strict mode principal-less execution context fall-open isPrincipalLessContext") returned 0 open hits.
Generated by Claude Code
Filing gate: ① a product defect, exception class: security. reach: measured on a hosted tenant kernel (cloud's composition) at framework
8832655a, through a direct engine context, not over a public door. Filed by therepo:cloudseat (repo:cloud#1, sessionsession_01Wxo1xhh2bU66T73q23jzE4, R44), from the objectstack-ai/cloud#2643 os-dev report 6000693096 (out_of_scope_findings1). Reader: the triage seat, for grading. ⛔ Classes, doors and roles only.The contradiction (framework
8832655a)packages/spec/src/contracts/ai-service.ts(near L507-518,ChatWithToolsOptions.toolExecutionContext) says executors "MUST run data-touching tools as an unauthenticated (RLS-on, sees-nothing) principal, exactly as if an empty context had been passed".packages/plugins/plugin-security/src/security-plugin.ts(near L2451) checksisPrincipalLessContext, then callsnext(): a principal-less context passes the middleware unchecked. ADR-0096 records this hand-off (E1), and its strict mode (D5) is not built.Measured (hosted tenant kernel, cloud
b84ce66e, framework8832655a)A data context with no user, no positions, no permission sets and
isSystem: false:public_read_writeobject, and inserted and updated rows there;controlled_by_parentobject under aprivatemaster, which a member is not shown;sys_permission_setrows, where a member getsPERMISSION_DENIED/ 403;privateobject's own rows were hidden from it.The probe was throwaway and was deleted.
Why cloud no longer hits it, and why it is filed here
objectstack-ai/cloud#2643 (PR objectstack-ai/cloud#2645) stopped cloud's AI tool loop from producing such a context. A tool call with neither an actor nor
isSystem: trueis now refused with the anonymous-deny pair (UNAUTHENTICATED/ 401), instead of mapping to a system context. The underlying hand-off is the framework's: any other producer of a principal-less engine context meets it.Ask (for triage to grade and route)
Measure the producers. Name every framework or plugin path that hands the data engine a principal-less context: no user and not
isSystem. Say whether each is reachable from a request.Pick the closure. Either:
shouldDenyAnonymousmakes at the HTTP doors; orThis is the family's closure card, not a single-point fix.
Dedupe: semantic search on objectstack ("ADR-0096 D5 strict mode principal-less execution context fall-open isPrincipalLessContext") returned 0 open hits.
Generated by Claude Code