> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reflections.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# ADR-0015: Tenant isolation and database RLS boundary

> Define defense-in-depth tenant isolation across API authorization and database row-level policy boundaries.

<Info>**Status:** Accepted **Date:** 2026-02-06 **Deciders:** Reflections Maintainers</Info>

## Context

Reflection data is tenant-scoped. Today, the API enforces reflection membership/role checks before data access and mutation, while database policy hardening is being added for future PostgREST enablement and direct SQL misuse defense.

## Decision

Adopt a dual-layer tenant isolation model:

* **Application boundary:** all authenticated reflection-scoped endpoints enforce server-derived membership roles (`member`/`admin`/`owner`).
* **Public boundary:** explicitly scoped anonymous routes are isolated to share-link flows with constrained namespaces and expiry/use controls.
* **Database boundary:** enforce RLS policies and helper functions across tenant tables as defense in depth, independent of API route correctness.

## Alternatives considered

### Alternative 1: API-only authorization, no RLS

Pros:

* Simpler operational model.
* Less SQL policy maintenance.

Cons:

* Larger blast radius from API bugs or bypasses.
* Weak defense against accidental direct DB access paths.

### Alternative 2: RLS-only authorization, thin API checks

Pros:

* Centralized data policy model in DB.

Cons:

* Harder app-level intent checks and resource-specific semantics.
* More complex policy debugging at request boundaries.

### Alternative 3: Separate databases per tenant

Pros:

* Strong physical isolation.

Cons:

* Operationally expensive and complex at this stage.
* Significant deployment and migration overhead.

## Consequences

**Benefits:**

* Defense-in-depth against authz regressions.
* Clear delineation of authenticated, privileged, and anonymous access surfaces.
* Better long-term portability if API access patterns evolve.

**Costs:**

* Additional policy complexity and verification burden.
* Need to keep API and DB policy semantics aligned.

## Implementation notes

* API role enforcement is centralized in the authorization module.
* Anonymous share-path controls are in the public routes module.
* DB RLS policy layer is codified in dedicated migrations.

## Related ADRs

* [ADR-0008: Authentication and RBAC model](/decisions/adr-0008)
* [ADR-0009: API architecture and authorization enforcement](/decisions/adr-0009)
* [ADR-0004: Primary data platform: Supabase Postgres](/decisions/adr-0004)
