Learn › Power BI & Fabric › 3 · Governance & security

Row-level and object-level security

RLS and OLS live in the semantic model and decide which ROWS and which TABLES/COLUMNS each user can see through the same report. They are powerful and easy to get subtly wrong — which is why the testing discipline matters as much as the rules.

RLS: filtering rows by who's asking

Row-level security is defined in the semantic model as roles, each carrying a DAX filter on one or more tables. A user mapped to a role sees only the rows the filter allows. Two styles:

  • Static RLS — a role per audience with a hard-coded filter (e.g. one role per region). Simple, but multiplies as audiences grow.
  • Dynamic RLS — one role whose filter uses USERPRINCIPALNAME() (or USERNAME()) against a mapping table, so a single role resolves the right rows per logged-in user. Scales cleanly, but the mapping table is now security-critical.

Roles are assigned to users or security groups in the service. RLS applies to report viewers — importantly, workspace members/admins and users with Build/edit on the model bypass RLS; RLS protects consumers, not editors.

OLS: hiding tables and columns entirely

Object-level security goes further — it can hide entire tables or columns from a role, so restricted users don't even see the object's metadata (a sensitive salary column, say, simply doesn't exist for them). OLS and RLS compose, but OLS interacts with report visuals referencing hidden objects (they break for restricted users), so it needs careful report design.

The testing discipline (non-negotiable)

Because a mistake here is a silent data leak, testing is part of the deliverable:

  • 'View as role' in Desktop/service to impersonate each role and confirm the row set.
  • Test the no-role and multiple-role cases — a user in two roles gets the union of their access, which can accidentally over-grant.
  • Re-test after model changes; a new relationship or a bidirectional flag can open an RLS bypass.

Failure modes

  • Bidirectional relationships defeating RLS. A filter on one table doesn't propagate as expected, and restricted rows leak through a related table.
  • Editors bypassing RLS unnoticed. Someone in a Contributor/Member role 'tests' and sees everything, concluding RLS works — it doesn't for consumers.
  • Union over-grant. Assigning a user to multiple roles silently widens their access.
  • Broken mapping table. Dynamic RLS keyed on a stale/incorrect user→data table shows people the wrong (or all) rows.
  • RLS not applied to the right assignment. A role defined but no users mapped, or mapped to the wrong group — data open to all.
  • OLS breaking visuals for restricted users, prompting someone to 'fix' it by removing the security.

What to watch (proofs)

  • Which models carry RLS/OLS: the admin scanner (admin/workspaces/getInfo) reports roles defined on each semantic model — models with sensitive data and NO RLS are the gap.
  • Role membership: role-assignment listings per model reconciled against the intended audience — orphaned or over-broad role mappings.
  • Editor population on secured models: Get-PowerBIWorkspace -Scope Organization cross-referenced with RLS models — every Member/Contributor is an RLS bypass by design.
  • Export controls alongside RLS: a user restricted by RLS but allowed to 'Export data' or 'Analyze in Excel' can still be constrained — verify export tenant settings (governance concept) match the RLS intent.

PowerShell for this concept

Discussion

No messages yet — start the thread.

Sign in with your email to join the discussion — we send a one-time link, no password.