Don't miss your chance to take the Fabric Data Engineer (DP-600) exam for FREE! Find out how by watching the DP-600 session on-demand now through April 28th.
Learn moreJoin the FabCon + SQLCon recap series. Up next: Power BI, Real-Time Intelligence, IQ and AI, and Data Factory take center stage. All sessions are available on-demand after the live show. Register now
The Trap Nobody Documents
You configure row-level security on your gold Lakehouse. You test it as a non-admin user rows filter correctly. You ship it.
Two weeks later, another team creates a shortcut from their workspace pointing at your Lakehouse tables to build their own reports. Their reports work. But when you inspect what their users actually see, you discover something uncomfortable: the RLS you carefully configured isn't applying. They're seeing every row.
This isn't a Fabric bug. It's the consequence of conflating three distinct security layers Power BI RLS, SQL endpoint row-level security, and OneLake Security and assuming they propagate through shortcuts the same way.
They don't. And the wrong assumption leaks data.
This article is the reference I wish I'd had when I first hit this. It lays out the three layers, the three architectures I see most often on the forum (two of which leak), the pattern that actually holds up, and a concrete checklist to test whether your setup is safe.
90-Second Refresher: The Three Security Layers
Fabric has three distinct places where you can enforce row-level access control, and they do not do the same thing:
Layer Enforcement point Bypassed by
And shortcuts are a virtual pointer: when a consumer reads a shortcut, the query is effectively executing against the target item's files under the consumer's identity (in most cases). Whether your RLS applies depends entirely on which layer you configured it at.
The Three Architectures I See Every Week
Pattern A : Power BI RLS only (leaks)
RLS in the semantic model only runs when someone queries through that model. A user with ReadData permission on the Lakehouse SQL endpoint or on the shortcut can issue a plain SELECT * and bypass the DAX filter entirely. Giving a consumer workspace a shortcut to your Lakehouse implicitly grants access paths that don't go through your semantic model.
Pattern B : SQL endpoint security policy only (leaks)
T-SQL security policies run inside the SQL engine. A Spark notebook that reads the underlying Delta files either directly in the source workspace or through a shortcut bypasses the SQL engine entirely and sees every row. Shortcuts don't copy the SQL security policy; they point to the files.
Pattern C : OneLake Security (holds up)
OneLake Security enforces at the storage layer below every compute engine in Fabric. The policy travels with the table regardless of which engine queries it or whether access is direct or through a shortcut, because the check happens before any engine sees the rows.
This is the only pattern I recommend in production when shortcuts are in play.
The Pattern That Holds Up Step by Step
1. Enable OneLake Security on the workspace
OneLake Security must be enabled at the tenant/workspace admin level before you can define policies. Confirm in the workspace settings → OneLake security pane that the feature is on.
2. Define the row-filter policy on the sensitive table
Policy name: rls_customer_region
Type: Row filter
Expression: region = GET_USER_ATTRIBUTE('department')
Applies to: role:"Regional Analysts"
The GET_USER_ATTRIBUTE() function reads from the user's Entra ID attributes, so you don't hardcode users you drive the filter from the directory.
3. Grant the consumer role data access
Role: "Regional Analysts"
Members: Entra group "fabric-regional-analysts"
Permission: ReadData (NOT ReadAll)
ReadData is the crucial setting. ReadAll bypasses OneLake Security row filters it's an admin-tier permission. Most consumers should have ReadData only.
4. Let consumers create shortcuts
When a consumer workspace creates a shortcut to this table, the OneLake Security policy travels with it. No additional configuration is needed on the consumer side, provided the consumer's users are in the Regional Analysts role on the source Lakehouse.
How to Verify Your RLS Actually Doesn't Leak
This is the checklist I run every time I configure RLS. Assume a test user alice@contoso.com whose department attribute in Entra is EMEA, and the customer table has rows where region IN ('EMEA', 'APAC', 'AMER').
Test 1: SQL endpoint on source Lakehouse (Alice's session)
SELECT DISTINCT region FROM customer;
-- Expected: only 'EMEA'.
Test 2: Spark notebook on source Lakehouse (Alice's session)
spark.read.table("customer").select("region").distinct().show()
# Expected: only 'EMEA'.
Test 3: Shortcut in a consumer workspace, read via Spark
spark.read.table("customer_shortcut").select("region").distinct().show()
# Expected: only 'EMEA'.
Test 4: Shortcut via SQL analytics endpoint in the consumer workspace
SELECT DISTINCT region FROM customer_shortcut;
# Expected: only 'EMEA'.
Test 5: Direct Lake Power BI report over the shortcut
Publish a simple table visual with region as a column. Connect as Alice. The visual should show only EMEA.
If all five pass under Alice's identity and fail open under a full-admin identity, your policy is enforced at the OneLake layer correctly. If any test under Alice returns rows from other regions, the most common cause is the consumer's workspace granting ReadAll instead of ReadData.
The Grey Zones Microsoft Hasn't Fully Clarified
1. Cross-tenant shortcuts.
If a consumer in tenant B creates a shortcut to a table in tenant A, the OneLake Security policy references Entra attributes from tenant A. Consumer users from tenant B don't have those attributes in my tests it defaults to deny, but confirm for your own setup.
2. Shortcuts to non-OneLake storage (ADLS Gen2, S3).
OneLake Security policies are defined on OneLake tables. A shortcut from OneLake to external ADLS does not inherit OneLake Security the external storage is governed by its own ACLs.
3. Interaction with workspace roles.
A Contributor on the source workspace has implicit ReadAll-equivalent permissions on Lakehouse tables, which bypass row filters. If you want RLS to apply to a user, they must not be a Contributor or higher they should be a Viewer with explicit ReadData granted through a role.
Why This Matters
RLS on a lakehouse with shortcuts is one of those configurations where "it looks like it works" and "it actually works" can diverge silently for months. A leak discovered in a quarterly audit is far more expensive than an hour spent running the five verification queries up front.
OneLake Security is the only layer that genuinely propagates through shortcuts, and ReadData (not ReadAll) is the only permission setting that honours the row filters. Get those two things right, run the tests, and you have an RLS configuration that survives contact with consumer workspaces.
If you find a grey zone I haven't covered, drop a reply in the comments below.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.