Case study 02
Multi-Tenant Access Scoping
Built tenant-scoped access patterns for a multi-tenant reporting service. Foundational work, and I'll say plainly where it stops.
Snowflake · SQL · dbt
Context
A multi-tenant reporting service needed customers to only see their own data. I built account-based row scoping into the reporting queries to enforce that. This work started after the core platform was already in production, so it had to fit an existing system rather than get designed in from day one.
What I built
Row scoping keyed on account, applied consistently across the reporting layer, so a query for one tenant’s data can’t leak into another’s.
Illustrated generically, today versus the next maturity step:
-- today: query layer. correct only if
-- every query goes through this filter.
select *
from curated.orders
where account_id
= current_setting('app.account_id');
-- next step: the warehouse enforces it,
-- not each query author.
create row access policy account_scope
as (account_id varchar)
returns boolean ->
account_id
= current_setting('app.account_id');
alter table curated.orders
add row access policy account_scope
on (account_id);
Where this stands honestly
This is foundational, not a mature, fully built out native warehouse-level RBAC or row-level-security implementation. I want to be direct about that rather than imply more than what’s there. It’s the right pattern to start with, and it’s not the end state a platform eventually needs as tenant count and query surface grow.
How I think about it
Access control on a data platform is something that matures in stages. You start with something correct and understandable, account-based scoping at the query layer is that. As the platform grows, that evolves toward native database-level enforcement (row access policies, and eventually more attribute-based control) so correctness doesn’t depend on every query being written right. I’d rather describe the stage I’m actually at than round up to a stage I’m not.