Editor's note (2026-05-12). When this post was published, Auraa used Databricks Synced Tables (managed DLT pipelines) to mirror Delta → Lakebase. In May 2026, we replaced Synced Tables with GovernanceWriter parallel fan-out: the repository layer dual-writes to silver Delta and Lakebase as a single unit of work. The architectural decision (selective Lakebase mirroring, Delta as sole write authority) is unchanged; only the mechanism shifted from infrastructure-managed sync to application-managed fan-out. References to "Synced Tables" below now mean GovernanceWriter dual-write.
Multi-tenant data platforms face a tension that every platform team navigates differently. Every tenant wants strong isolation guarantees. Every agent, analyst, and API endpoint wants seamless retrieval. The conventional resolution is a middleware layer: row-level security filters that rewrite every query to inject a WHERE tenant_id = ? predicate.
This works. It also fails in subtle ways. A missed filter exposes cross-tenant data. A new query path that bypasses the interceptor creates a vulnerability. A direct table access skips the rewrite entirely. You end up auditing middleware rather than trusting architecture.
Auraa uses a different approach. There are no row-level filters in the critical path. Isolation is enforced by addressing, not filtering.
The architecture rests on three foundational choices:
Each decision is independently valuable. Their compounding is what makes the architecture interesting.
When a component calls TenantPathResolver.resolve("customer", project_id="alpha", layer="silver"), the resolver returns a fully qualified path:
# Strategy: Schema per Project aura_tenant_acme.project_alpha_silver.customer
# Strategy: Catalog per Project aura_project_acme_alpha.silver.customer
# Strategy: Environment-Catalog, Source-Schema aura_tenant_acme_prod.crm.customer
The path encodes the tenant boundary. There is no tenant_id column to forget. There is no filter to misconfigure. A component that resolves paths correctly cannot access another tenant's data, because the other tenant's data lives at a different Unity Catalog address.
This property holds for both writes and reads. DataDuct writes ingested data to the resolved path. An agent retrieves metadata from the resolved path. The same resolver, the same isolation, applied uniformly to every operation.
Because metadata is data, platform state and business data follow the same medallion pattern through the same tenant-scoped paths:
governance.tenant_principal_roles (Bronze → Silver)registry.tools (published by Foundra at init, read by MCP at runtime)An agent asking "which tables have data quality failures?" queries the same Delta tables, through the same resolver, with the same isolation guarantees as an analyst asking "what were last month's sales?" The retrieval pattern is uniform; only the payload differs.
Delta as the single write authority doesn't mean Delta is the only retrieval surface. The Lakehouse provides multiple modes:
| Consumer | Retrieval Mode | Latency |
|---|---|---|
| Spark SQL analytics | Direct Delta read | Seconds |
| Agent tool invocation | SQL Warehouse via MCP | Sub-second |
| REST API | SQL Warehouse endpoint | Sub-second |
| Auth middleware (high-concurrency) | Lakebase via GovernanceWriter dual-write | Read-your-own-write |
The auth middleware which must resolve tenant and role on every API request is a perfect example. Role assignments are written to Delta (preserving the full append-only audit trail). In the same unit of work, GovernanceWriter mirrors the current-state Silver row to Lakebase. The middleware queries Lakebase for sub-second, connection-pooled point lookups. The write path and the read path are independently optimized without violating the single-source-of-truth invariant.
The environment-as-catalog model means dev, staging, and prod each have their own catalog, their own data, their own roles but the same code:
aura_tenant_acme_dev.crm.customer ← dev data, dev roles
aura_tenant_acme_prod.crm.customer ← prod data, prod roles
Pipeline code never contains environment-specific paths. The TenantPathResolver injects the correct catalog at runtime. Quality rules defined in dev apply in prod same rule, same resolver, different catalog. Agents tested in dev work in prod same tool definitions, correct context from the resolver.
This is the compounding effect. Once you commit to treating organization as configuration and metadata as data, environment portability falls out naturally from the architecture rather than requiring explicit tooling to manage.
The TenantPathResolver becomes critical infrastructure. A resolver bug means writes land in the wrong location. Auraa mitigates this through immutable frozen dataclass design (the resolver is a pure function over immutable inputs), exhaustive strategy testing, and factory-only construction that validates the strategy before returning an instance.
Strategy migration post-onboarding is non-trivial by design. Changing a tenant's organization strategy requires data movement, metadata re-registration, and grant re-application. The choice of strategy is foundational, not a runtime toggle. Choose carefully at onboarding.
Each Lakebase-mirrored table adds a parallel write to every mutation. Tables serving API endpoints or high-concurrency reads justify the dual-write cost. Tables consumed only by Spark batch jobs don't. The judgment isn't hard for clear cases; it requires more thought for tables with mixed access patterns. (Pre-May 2026 this was a DLT compute cost; with GovernanceWriter it's a write-latency cost paid by the mutating component.)
Decide how to store early (metadata is data everything goes through Delta and the medallion). Decide where to store flexibly (organization as configuration let tenants choose the right isolation model). Decide how to retrieve pragmatically (selective sync optimize reads for each consumer without duplicating the write path).
The result is a system that is simpler to reason about, harder to misconfigure, and more flexible for tenants with different requirements.
The path is the policy. Delta is the authority. The Lakehouse is the surface.
Configurable Organization Meets the Lakehouse: How Tenant-Scoped Delta Paths Enable Single-Source-of-Truth Retrieval examines all three architectural decisions in depth, with production patterns for tool registries, metadata extraction, role-based auth, and data quality.
Read the Whitepaper →You enforce isolation by addressing instead of filtering. Each tenant's data lives at a distinct Unity Catalog path, so a component that resolves the correct path cannot reach another tenant's data because that data sits at a different catalog address. There is no tenant_id column to forget and no WHERE-clause rewrite to misconfigure. Auraa implements this with a TenantPathResolver that returns fully qualified Unity Catalog paths at runtime, applied uniformly to every read and write.
Row-level security filters create silent failure modes. A missed filter exposes cross-tenant data, a new query path that bypasses the interceptor opens a vulnerability, and direct table access skips the rewrite entirely. The result is that you end up auditing middleware rather than trusting the architecture. Isolation enforced through Unity Catalog addressing removes the middleware from the critical path, so the boundary holds by construction rather than by interception.
Yes. Delta remains the sole write authority, and selected tables are dual-written to Lakebase in the same unit of work through a component called GovernanceWriter. High-concurrency consumers such as auth middleware query Lakebase for sub-second, connection-pooled point lookups, while the full append-only audit trail stays in Delta. The write path and the read path are optimized independently without breaking the single-source-of-truth invariant.
Treat project structure as per-tenant configuration rather than something hardcoded. Auraa supports schema-per-project, catalog-per-project, and environment-catalog models, all resolved at runtime by the TenantPathResolver into fully qualified Unity Catalog paths. The trade-off worth knowing: strategy migration after onboarding requires data movement, metadata re-registration, and grant re-application, so the isolation model is a foundational choice made at onboarding, not a runtime toggle.
Give each environment its own catalog with its own data and roles, and inject the correct catalog at runtime instead of writing environment-specific paths into pipeline code. With an environment-as-catalog model, the same code, the same quality rules, and the same agent definitions run unchanged across dev and prod because the resolver supplies the right catalog for each environment. Environment portability falls out of the architecture rather than requiring separate tooling to manage.
You can keep platform metadata in the lakehouse rather than a separate operational store. Auraa treats metadata as data: user roles, tool registries, quality rules, execution logs, and lineage all flow through the same Bronze, Silver, and Gold medallion pattern as business data, with Delta Lake as the single write authority for both. An agent asking which tables have data quality failures queries the same Delta tables, through the same resolver, with the same isolation guarantees as an analyst asking about last month's sales.
Each mirrored table adds a parallel write to every mutation, so the cost is paid as write latency by the mutating component. Tables that serve API endpoints or high-concurrency reads justify that cost; tables consumed only by Spark batch jobs do not. The judgment is straightforward for clear cases and takes more thought for tables with mixed access patterns, which is why mirroring is selective rather than applied to every table.
Auraa is built natively on Databricks and assumes Unity Catalog as the governance and addressing layer, Delta Lake as the write authority, and the medallion architecture for both business and platform data. It fits teams that already run, or are committing to, a Databricks lakehouse and want tenant isolation, environment portability, and low-latency reads without a row-level-security middleware layer. Positioned simply, it is the fastest path to AI-ready data on Databricks.