Obsidian·RegTech / Reporting·April 2025

Multi-Tenant Reporting Platform with Row-Level Security

Jurisdiction-precise reports for 180+ tenants in DACH, with guaranteed data isolation at the DB level.

180+
Tenants
12k
Reports/Month
<200ms
Query P95
DB-Level
Isolation
ReactNode.jsTimescaleDBAWSRLS

Starting Point

Obsidian delivered regulatory reports to 180+ financial institutions in DACH. The existing platform was single-tenant replicated — every new customer = separate DB instance, separate deployment pipeline, 3 weeks onboarding time. Not scalable.

Our Approach

Multi-tenancy on a single shared Postgres (TimescaleDB extension for time series), with Row-Level Security policies as hard isolation. Every query runs in the context of a tenant ID set via connection settings — data leaks are physically impossible, not just through application logic.

Architecture

  • TimescaleDB hypertables for report payloads (jurisdiction + period as composite keys)
  • RLS policies per table with current_setting('app.tenant_id')
  • Jurisdiction validation via PostgreSQL EXCLUDE constraints (no overlapping periods)
  • React dashboard with per-tenant themes (white-label ready)
  • AWS ECS deployment, Aurora Postgres backend

Result

180+ tenants on a single DB. Onboarding from 3 weeks to 15 minutes. 12,000 reports/month, P95 latency under 200ms. Zero data-leak incidents in 9 months of production.

What We Learned

RLS is underrated. Many teams write their own tenant isolation in the application layer — fragile, error-prone. Postgres-native RLS moves isolation to where it belongs: into the engine that holds the data.

Similar project?

Let's talk about it.

Start a project