Published: 10 Mar 2026 | Author: James Beresford
Updated 22 October 2026: OneLake Security is now generally available, and the recommendations below reflect that.
Most Fabric and Power BI estates hold personally identifiable information (PII) that only some teams should see. Controlling PII access in Microsoft Fabric and Power BI comes down to one design decision – your semantic model's storage mode – and since OneLake Security reached general availability in May 2026, the recommended answer for Direct Lake has changed. There are four practical approaches, each breaks somewhere different, and one of them is now the clear default for Direct Lake.
Short answer: if your Power BI semantic model uses Import mode, hide PII with semantic model Object-Level Security (OLS) on separate PII tables. If it uses Direct Lake on OneLake, use OneLake Security column-level security (CLS), generally available since May 2026.
Controlling PII access in Microsoft Fabric and Power BI is rarely about hiding a few columns. Customer names, email addresses, phone numbers and physical addresses are exactly the data specific teams need for their work, and exactly the data everyone else shouldn't see. The part that takes design is doing it in a way that scales, doesn't create maintenance overhead, and still gives report builders a workable experience.
Consider a common pattern: a Fabric Lakehouse holds transactional data with a customer dimension. Most users work with anonymised identifiers and aggregated metrics. But certain business groups – customer service, marketing, compliance – need specific PII attributes alongside the same core data. Crucially, these groups often need different subsets of PII, and they aren't just report consumers. They're report builders who need to see, and work with, the relevant fields in the Power BI field list.
Because it determines where security can be enforced. This is the single most consequential architectural decision in PII access control design.
Import mode brings data into an in-memory copy inside Power BI. Security must be enforced within the semantic model itself, and OneLake Security roles have no effect because queries don't read from OneLake at runtime.
Direct Lake on OneLake queries the Delta Parquet files directly from OneLake, so OneLake Security – including column-level and row-level security – is enforced by the engine at query time. Security defined once at the data layer flows through to Power BI, Spark and the SQL analytics endpoint (in user identity mode, now the default for new endpoints).
If you're on Direct Lake, the full range of options is open. If you're on Import, your choices are narrower – but still workable.
Almost never.
The idea is simple: publish a different semantic model for each PII access group, each containing the base data plus only that group's PII columns. In Direct Lake mode the fact tables aren't physically copied – they reference the same Delta Parquet files – so the storage overhead is modest.
The cost is operational. Every model carries its own measures, relationships, calculated columns and security definitions, so a change to a core measure has to be replicated across every model. Report builders may need to rebuild work if they move between groups. The maintenance burden grows linearly with the number of PII groups, and model drift becomes a genuine risk. It can work as a quick tactical fix for a single extra group, but it isn't a sustainable architecture.
For Import mode, yes.
Within a single semantic model, PII fields are extracted from the main customer dimension into narrow, purpose-built tables – one per access group. Each table holds only a linking key and that group's PII columns, and Object-Level Security (OLS) in the semantic model hides the tables a given user shouldn't see. The field list might contain:
Each PII table relates back to the main dimension via the shared key, so visuals and measures resolve correctly. The trade-off is the authoring experience: PII-authorised builders see PII in a separate table rather than alongside the other customer attributes. Clear display names, display folders, pre-built measures and documentation make that manageable, but it's a visible seam. Users without PII access see a completely clean model with no hint that restricted tables exist.
The limits are worth stating plainly. OLS roles are static metadata definitions, and security is scoped to the semantic model only – Spark and the SQL analytics endpoint aren't covered.
Since May 2026, yes – with caveats.
OneLake Security reached general availability on 5 May 2026 and is now enabled by default on new supported items. Roles are defined at the Lakehouse layer, and column-level security hides PII columns from unauthorised users directly at the storage tier.
For report builders, this is the cleanest experience on offer. All columns live in a single table and the engine shows or hides them based on role membership – no separate PII tables, no split field list, no relationship workarounds. A user in the marketing role sees name and email in the customer dimension; a user in the general role doesn't see them and doesn't know they exist. One nuance: a select * against a partially restricted table returns an error in semantic models and the SQL analytics endpoint, while Spark simply returns the allowed columns. Field-list users won't notice; anyone writing queries will.
CLS works by columnar projection, excluding restricted columns from the Parquet read path, so the performance overhead is negligible. Row-level security can be layered on within the same role using SQL WHERE predicates.
General availability doesn't remove the design constraints:
When your row-level rules differ materially between PII groups.
This hybrid splits PII columns into separate Lakehouse tables, as in Option 2, but secures them with OneLake Security's table-level access rather than semantic model OLS. Each PII table can carry its own RLS predicate without interacting with CLS rules on the same table, which sidesteps the single-role constraint. It also inherits OneLake Security's cross-engine enforcement. The downside is the same split field list as Option 2, plus the overhead of maintaining extra tables in the Lakehouse pipeline.
| Approach | Storage modes | Status | Field-list experience | Engines covered | Main limitation |
|---|---|---|---|---|---|
| 1. Separate semantic models | All | GA | Clean, per model | Power BI only | Model drift; effort grows with every group |
| 2. Semantic model OLS + PII tables | Import, DirectQuery, Direct Lake | GA | Split – PII in separate tables | Power BI only | Visible seam for PII users |
| 3. OneLake Security CLS | Direct Lake on OneLake | GA (May 2026) | Single table | Power BI, Spark, SQL analytics endpoint | CLS and RLS must share one role |
| 4. OneLake Security table access + PII tables | Direct Lake on OneLake | GA (May 2026) | Split – PII in separate tables | Power BI, Spark, SQL analytics endpoint | Extra pipeline tables to maintain |
No.
Fabric Warehouses and Lakehouse SQL analytics endpoints support Dynamic Data Masking (DDM) via T-SQL, and it's tempting to treat it as a PII solution. Microsoft explicitly advises that DDM shouldn't be used alone to secure sensitive data: users with query access can infer masked values through predicate-based probing. More critically, DDM doesn't propagate to Direct Lake semantic models – Power BI queries bypass the masking entirely – and it only applies through the SQL analytics endpoint or Warehouse engine, not Spark or direct OneLake access. It has a place as defence in depth for ad hoc SQL, not as a primary control.
Over the top of whichever approach you choose. Microsoft Purview sensitivity labels can classify columns containing PII, Data Loss Prevention policies can flag semantic models or Lakehouses holding sensitive data, and lineage shows how PII flows through your architecture. None of it replaces a technical access control, but it's the audit and compliance layer your security team will expect.
If you're on Import mode, semantic model OLS with separate PII tables remains the best option. OneLake Security can't help you, because Import models never read OneLake at query time.
If you're on Direct Lake on OneLake, OneLake Security with CLS is now the recommended design. It's generally available, it keeps PII in a single table, and it enforces the same rules across Power BI, Spark and the SQL analytics endpoint. Design each role to be self-contained, and keep PII-controlled users out of the Contributor, Member and Admin workspace roles.
If you built semantic model OLS as a stopgap while CLS was in preview, now is the time to plan the migration: consolidate the PII columns back into the main table, define CLS roles, and retire the split tables.
Whichever path you take, prove it with non-production data first. Validate enforcement end to end, test the report builder experience, and confirm the operational model works for your team. PII is not the place to skip validation.
OneLake Security's general availability changes the default answer more than it changes the hard parts. Storage mode still decides what's possible, the single-role rule still shapes role design, and a PII user sitting in the wrong workspace role still undoes everything.
If you're planning the move from OLS split tables to OneLake Security CLS, or want a second pair of eyes on a PII role design before it reaches production, Talos would be glad to help – email [email protected].
Yes. Microsoft made OneLake Security generally available on 5 May 2026, and it's now enabled by default on new supported Fabric items. It supports table, column and row-level security, defined once at the data layer and enforced across Fabric engines.
No. Import models hold their own in-memory copy of the data and don't read OneLake at query time, so OneLake Security roles have no effect on them. Security for Import models has to be defined in the semantic model itself, using row-level and object-level security.
Yes, but only within a single role. If a user belongs to one role with RLS and another with CLS on the same table, their queries fail. Make each role self-contained, or split PII into separate tables if row filters differ materially between groups.
Yes. OneLake Security uses a grant model, so workspace Admins, Members and Contributors aren't restricted by it. Anyone subject to PII controls should hold the Viewer role or have items shared with them directly.
Object-Level Security hides whole tables, so PII has to sit in separate tables and authorised users see a split field list. Column-level security hides specific columns within one table, so authorised users see PII alongside the other attributes and everyone else simply doesn't see those columns.
No. Microsoft advises against relying on Dynamic Data Masking alone, because users with query access can infer masked values by probing with predicates. It also doesn't apply to Direct Lake semantic models or Spark. Treat it as defence in depth for ad hoc SQL only.
Yes. Talos designs and tests semantic model OLS and OneLake Security role models for Fabric and Power BI, including migrating from split PII tables to column-level security. Email [email protected] to start the conversation.
Get the latest Talos Newsletter delivered directly to your inbox
Automation & Analytics Technologies for Business
Talos helps organisations build modern data and analytics platforms using Databricks, Microsoft Fabric and Power BI. We work from strategy through implementation, ensuring you get value from the platform without unnecessary complexity.
Talos helps organisations build reporting solutions using Jet Analytics
Australian councils face backlogs, staff turnover, and rising community expectations. We help you improve service delivery and operational efficiency through process automation — integrated with TechnologyOne, Civica, and Pathway.
It depends on the semantic model's storage mode. With Import, move PII into separate narrow tables and hide them using semantic model Object-Level Security. With Direct Lake on OneLake, use OneLake Security column-level security, which hides columns within the same table and is enforced across Power BI, Spark and the SQL analytics endpoint.