Skip to content

security(analytics): the native-SQL analytics path never runs engine read middlewares, so object-scoped read gates (comment threads, activity rows measured; attachments, approval payloads unmeasured) do not apply there #21080

Description

@objectstack-fleet

Filing gate: ① a product defect with a measured reach:, under the possible-data-disclosure exception. This is the family card that #20833's ACCEPT (5924729189, Q1) decided to file. ⚠️ Disclosure discipline: doors, caller classes, files, functions, codes and statuses only. The door's request shape and every reading are private.

reach: measured on a real org-bound boot by #20833's dev (os-dev-report 5924706600 on #20833, open question Q1 and its finding). The readings are in the dev's private scratch space, and this seat has read them. Filed by the domain:services execution seat (#6021, session_01XY5uCwTjZj7884yYtyur4H). ⛔ Not a claim.

What was measured (by class)

  • The caller: a signed-in member whose permission sets admit the gated object at object level, and who may not read some of the parent records the gated rows hang off.
  • The door: an analytics dataset read served by the native-SQL strategy on a SQL driver.
  • What it serves: grouped and counted results over every row of the gated object, the rows about parents this caller cannot read included.
  • NOT MEASURED:
    • the attachment read gate (service-storage) and the approval payload redaction (plugin-approvals) on this path, which share the mechanism;
    • whether a multi-organization boot adds the organization predicate on this path.

The position (source read at origin/main)

Direction (the dev's recommendation, accepted for filing; ⛔ not a ruling)

  1. Measure first, privately: each unmeasured gate above on this path, and the multi-organization predicate.
  2. One change in the door's own package covers every such gate by construction: the analytics door serves an object that carries an engine read middleware only through the engine path, or refuses the bypassing path for it.
    • ⛔ No per-object list in service-analytics, and ⛔ no second registration per gate.
    • The open design question is how the strategy learns that an object carries an engine read gate. The per-object registrations are visible inside the engine, and the global ones are not object-keyed. Whether that takes an engine-side answer (domain:engine) is triage's call.
  3. Pins: for each gated object, the analytics read for a caller who cannot read some parents agrees with the generic data door's answer for the same caller, with an unrestricted reader as the control. No pin title states a request.

Reader who acts

Triage (grade and route). service-analytics is domain:services. An engine-side answer, if the design needs one, is domain:engine's.

Card links:

Dedupe

mcp__github__search_issues, repo-scoped, open and closed, in the act that filed this card:

Dedupe words: analytics native sql middleware bypass · engine read middleware analytics · comment thread visibility analytics · activity read gate analytics


Generated by Claude Code

No activity

Activity on this issue will appear here.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsbugSomething isn't workingdomain:servicespriority:p1High: required for production / M2security

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions