Skip to content

High: Policy adapter does not propagate resource domain context, weakening tenant isolation enforcement #148

@dligthart

Description

@dligthart

Summary

Runtime policy enforcement currently cannot enforce tenant-boundary checks reliably because adapter resource payloads omit resource.domainId in most paths.

Evidence

In src/services/policy-adapters.ts:

  • buildOperationContext requires principal domainId (line 26), but does not enrich resource with domain.
  • resolveRestResource returns { type, id } only (lines 68-76); no domainId is attached.

In src/services/policy.ts:

  • Tenant isolation check is conditional on resource.domainId !== undefined.
  • If resource.domainId is absent, the TENANT_ISOLATION_VIOLATION path does not execute.

Current effect: route-level SQL filtering is carrying most tenant isolation, while policy-layer isolation is partially dormant for REST/GraphQL/MCP resources that don't inject domain context.

Impact

  • Weakens the stated architecture guarantee that policy is the centralized cross-protocol authorization geometry.
  • Increases risk of regressions when new routes are added with incomplete SQL scoping.
  • Tenant isolation behavior becomes implementation-fragile and protocol-dependent.

Proposed Fix

  1. Extend adapters/wrappers to include resource.domainId by default from authenticated principal for tenant-bound resources.
  2. Where resource IDs are provided, resolve and verify domain ownership before policy evaluation (or annotate as unresolved + fail-closed for writes).
  3. Add integration tests proving policy denies cross-tenant access in real REST/GraphQL/MCP request paths (not only unit-level PolicyEngine tests).

Acceptance Criteria

  • Runtime policy evaluation receives domain-aware resources for tenant-scoped operations.
  • Cross-tenant request attempts are denied by policy even before handler-side mutations.
  • Integration tests validate the deny behavior end-to-end across protocols.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions