Power BI
Advanced 15 min read Power BI

Power BI Security and Row-Level Security

Right rows, right people, right places

Securing Power BI means controlling access at four layers: data source, model (row-level security via roles), report/workspace permissions, and sharing. RLS filters rows by the viewer's identity or attributes.

Power BI securityRLSrolesrow-level securityDynamic RLSpermissions
Prerequisites: Power BI Service
Before we start

What you will learn

  • Apply static and dynamic row-level security
  • Layer RLS with workspace permissions and OLS
  • Test RLS as a consumer before publishing
Introduction

What is this?

Power BI security is layered: sources are accessed with credentials; the model can restrict rows via row-level security (RLS) using DAX roles (static like 'region = EU' or dynamic via USERPRINCIPALNAME matching a dimension); workspace/app permissions control artifact access; object-level security (OLS) hides columns. RLS is enforced server-side in the service, not in the visual.

Motivation

Why do you need it?

  • Regulatory and commercial walls require row and column restrictions.
  • One shared dataset can serve many audiences if RLS is correct.
  • Dynamic RLS means new users are secured without editing roles.
  • Testing as a consumer catches leaking rules before regulators do.
Think about it

Mental model

Imagine

A club with a bouncer who reads your ID

Think of

RLS

Everyone walks into the same club (shared model) but the bouncer (DAX role) limits which tables (rows) you get by checking your ID (USERPRINCIPALNAME/attributes). Change the list once, every door checks it.

Mechanics

How it works

  • Model roles contain DAX filter expressions; membership is users/groups.
  • Static RLS: hard-coded filter ('region = "EU"').
  • Dynamic RLS: filter references the viewer's identity or a mapping table (USERNAME()).
  • The service applies roles at query time; DirectQuery/import both enforce.
  • Workspace roles (Viewer etc.) and OLS layer above/below row rules.

Four layers of Power BI security.

Data source
RLS roles
OLS
Workspace/app
Viewer
Hands-on

Examples

Dynamic row-level security

Dynamic row-level security
RegionManager =
VAR me = USERPRINCIPALNAME()
RETURN FILTER(
dim_manager,
dim_manager[email] = me
)
-- then link fact data to that manager's allowed regions via the dim
-- Static alternative
EUOnly = 'dim_region'[region] = "EU"

Dynamic RLS reads who's logged in and matches their mapping row, so adding a new manager's mapping secures them without role edits.

Real world

In production

  • A finance dataset: 'RegionManager' role shows VPs only their regions' rows via a manager map.
  • Support data shares one dataset, restricting rows by team membership tags.
  • Marketing hides strategic columns with OLS while sharing the dataset engine-wide.
Guidelines

Best practices

  • Model RLS on mapping tables (dynamic) with documented role names.
  • Test RLS as a viewer using the 'View as role' feature against expected numbers.
  • Keep RLS in the model, not in report-level filters users can clear.
  • Audit who the roles grant access to and review membership quarterly.
Watch out

Common mistakes

  • Using report page filters as 'security' — users can clear them.
  • Static roles duplicated per region instead of one dynamic mapping.
  • Testing only in Desktop, where USERNAME() may differ from the service.
  • Over-wide workspace permissions bypassing RLS intent for exports.
Root cause analysis

Common issues

Error
User sees another region's rows
Root cause

RLS role missing membership or the mapping row lacks their email

Fix

Add the user to the role; correct the mapping; re-test with View-as.

Error
RLS works in Desktop but not in the app
Root cause

App audience membership differs from role membership

Fix

Verify app audience and dataset role membership align.

When things break

Debugging tips

  • Blank rows under a role → the role filter matches nothing; check mapping email/cases.
  • 'View as role' passes but service fails → check membership and USERNAME() format.
  • Export leaks → block exports or enforce RLS on the export source.
Interviews

Interview checkpoint

Practice

Hands-on lab

Design Dynamic Row-Level Security
45 min · advanced
In progress
Objectives
  • Build a manager→region mapping for dynamic RLS
  • Simulate per-user row access with SQL
  • Draft and verify the DAX role logic textually

Design Dynamic Row-Level Security

45 min · advanced

0/5 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/2
1

Where is row-level security enforced?

2

A report page filter is an acceptable substitute for RLS.

Go deeper

Official documentation