One Copy of the Data Isn't One Source of Truth
“Storage was never the hard part. Proving row-level security holds up the same way for every tenant, every time, is the promise a unified lake actually has to keep.”
Every enterprise I've seen eventually grows a fleet of shadow warehouses — a copy for finance, a copy for the data science team, a copy someone spun up in 2021 for one report that's now load-bearing. Unified-lake architectures exist to kill that fleet: one copy of the data, one security model, every team reading from the same source. The pitch is simple. The execution lives or dies on one unglamorous question: does the security model actually hold up the same way for every tenant, or does it quietly leak at the edges?
Storage was never the hard part
Copying data into one place is a solved problem — it's been solved for years. What's hard is governing it once it's there. A single shared lake means row-level security, column-level security, and object-level permissions all have to compose correctly for every combination of user, role, and dataset — not just the three you tested. The moment two teams share one physical copy of a table, "who can see what" stops being a per-report setting and becomes an architectural property you have to prove, not assume.
Zero-copy is a promise, not a default
"Zero-copy" architectures let multiple teams query the same underlying data without duplicating it — which is exactly the point, and exactly the risk. Skip the copy and you also skip the natural checkpoint that used to force someone to think about permissions: standing up a new extract. Get the security model wrong once, upstream, and every consumer downstream inherits the mistake instantly, at full fan-out, with no separate copy acting as a blast-radius wall. The efficiency and the risk are the same architectural decision.
The three-level test
Before a table goes into a shared lake, it should pass the same test dashboards should pass before they ship: name the boundary, name who enforces it, name what breaks if it's wrong.
- Object-level — can this role see the table exists at all?
- Row-level — of the rows it can see, which ones actually belong to it?
- Column-level — of those rows, which fields are safe for this role, and which need to be masked or dropped?
Most incidents I've seen weren't object-level failures — those get caught in review. They were row- or column-level gaps: a join that quietly widened access to rows a team wasn't supposed to see, or a "temporary" wildcard grant that outlived the ticket that created it.
Conformed dimensions, but for permissions
The same principle that makes a data model trustworthy applies here: define the access rule once, in one governed place, and reference it everywhere, rather than re-implementing "can this tenant see this row" per report, per team, per tool. A security model that has to be reasoned about fresh for every new consumer is a security model that will eventually be reasoned about wrong.
One copy of the data was always going to be the easy half of "one source of truth." One copy of the permission logic is the half that actually earns the trust the architecture promises — and you don't have to take that on faith. Pick one table in your shared lake and run the three-level test against it, in that order. Any table that can't clear all three cleanly is the one to fix before it goes any further.