Skip to content

Multi-org analytics RLS: SecurityPlugin to expose getReadFilter (ADR-0021 D-C) #1645

@os-zhuang

Description

@os-zhuang

Background (ADR-0021 D-C)

The analytics dataset semantic layer (PR #1643) hardens the cross-object analytics SQL path so the tenant/RLS read scope is injected per joined object. The mechanism is in place and unit/integration-tested:

  • StrategyContext.getReadScope (context-aware, returns a FilterCondition)
  • NativeSQLStrategy injects the scope on the base AND every joined table; rejects undeclared joins
  • read-scope-sql fail-closed FilterCondition→SQL compiler
  • AnalyticsServicePlugin auto-bridges getReadScope to a security service exposing getReadFilter(object, context)

What is missing: plugin-security does not yet expose that getReadFilter service method, so in production the auto-bridge finds nothing and the raw-SQL analytics path runs unscoped for cross-object dataset queries. Single-org and single-object paths are unaffected (single-object goes through the RLS middleware; single-org has no cross-tenant surface).

Task

Extract the existing middleware logic (permission-set resolution → collectRLSPolicies → field-existence filtering → RLSCompiler.compileFilter) into a reusable getReadFilter(object, operation, context) => FilterCondition | null, register it as the security service so AnalyticsServicePlugin auto-bridges to it. The live middleware behaviour must not change — factor out a shared helper that both the middleware and the new method call (single source of truth, no divergence).

Why it needs review

Touches the security middleware hot path (highest-impact risk R1: a mistake leaks cross-tenant rows). Requires: unit tests that the extracted method matches middleware output; a multi-tenant end-to-end test with a real sqlite driver asserting a cross-object dataset query returns no other-tenant rows.

Scope

  • packages/plugins/plugin-security — expose getReadFilter + register security service
  • Multi-tenant e2e test (driver-sql)
  • No change to service-analytics (the bridge seam is already in place)

Follow-up to #1643. See ADR-0021 §D-C.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions