Security in Fabric is not optional — it is the difference between “our data platform” and “our data breach.” Every company that deploys Fabric must answer: who can see what data, who can modify what items, how do we track who accessed sensitive information, and how do we prove compliance to auditors.
This post covers every security layer in Fabric — from workspace roles (who enters the building) to row-level security (who sees which rows) to sensitivity labels (classifying data as Confidential/Internal/Public) to Purview integration (governance at scale). Each layer is explained with what it does, why it exists, when to use it, and how to configure it — with real-world scenarios throughout.
Real-life analogy: Think of Fabric security like a hospital. Workspace roles are the hospital badge — doctors, nurses, and visitors each have different access levels. Item permissions are department access — a cardiac nurse can enter the cardiac ward but not the pharmacy vault. OneLake data access roles are patient chart access — even within the cardiac ward, not every nurse can see every patient’s chart. Row-level security is the “need to know” principle — a nurse sees only their assigned patients, not the entire floor. Column-level security is field-level redaction — a billing clerk sees the patient name and insurance ID but not the medical diagnosis. Dynamic data masking is like partial redaction — the clerk sees “John D***” instead of “John Doe.” And sensitivity labels are the classification stamps on folders — “Confidential,” “Internal,” “Public” — that control what happens when someone tries to take information outside the hospital. Every layer narrows access further, and they all work together.
Table of Contents
- The Security Layers (Overview)
- Workspace Roles (Building Access)
- Admin, Member, Contributor, Viewer
- Who Gets Which Role
- Common Role Assignment Mistakes
- Item-Level Permissions
- Sharing Items (Read, ReadAll, Reshare, Build)
- When to Use Item Permissions vs Workspace Roles
- OneLake Data Access Roles
- How OneLake Security Works
- Creating Custom Data Roles
- DefaultReader Role
- Row-Level Security (RLS)
- RLS in Warehouse (T-SQL)
- RLS in Lakehouse (SQL Endpoint)
- RLS in Semantic Models (DAX)
- Testing RLS
- Column-Level Security (CLS)
- When to Use CLS vs Separate Tables
- Dynamic Data Masking
- Masking Functions
- Who Sees Masked vs Unmasked Data
- Sensitivity Labels
- Classifying Data (Confidential, Internal, Public)
- How Labels Flow Downstream
- Auto-Labeling Policies
- Microsoft Purview Integration
- Data Lineage
- Data Catalog
- Data Classification
- Endorsement (Promoted and Certified)
- Audit Logs
- Real-World Security Architecture
- Scenario: Multi-Team Data Platform
- Common Mistakes
- Interview Questions
- Wrapping Up
The Security Layers (Overview)
Fabric uses a defense-in-depth model with seven security layers. Each layer controls a different scope — from the broadest (workspace-level) to the finest (individual column masking). The layers are additive: a user must pass through ALL applicable layers to see data. If any layer denies access, the user cannot see the data — even if other layers allow it.
Layer 1: WORKSPACE ROLES
"Which workspace can you access?"
Admin / Member / Contributor / Viewer
→ Broadest control — applies to ALL items in the workspace
Layer 2: ITEM PERMISSIONS
"Which specific items (notebooks, pipelines, reports) can you use?"
Read / ReadAll / ReadData / Reshare / Build
→ Grants access to specific items WITHOUT workspace membership
Layer 3: ONELAKE DATA ACCESS ROLES
"Which tables/folders within a Lakehouse can you read?"
Custom roles on Tables and Files folders
→ Controls WHAT data a user sees within an item they can already access
Layer 4: ROW-LEVEL SECURITY
"Which rows within a table can you see?"
Filter predicates per user/role
→ Same table, different users see different rows
Layer 5: COLUMN-LEVEL SECURITY
"Which columns can you see?"
GRANT/DENY SELECT on specific columns
→ Hides sensitive columns (salary, SSN) from unauthorized users
Layer 6: DYNAMIC DATA MASKING
"What do masked values look like?"
Show partial/masked data to unauthorized users
→ User sees "nXXX@XXXX.com" instead of "naveen@company.com"
Layer 7: SENSITIVITY LABELS
"How is this data classified?"
Confidential / Internal / Public — flows to exports
→ Controls what happens when data LEAVES Fabric (exports, shares)
Real-life analogy: These seven layers are like a seven-gate fortress. Gate 1 (workspace role) lets you into the compound. Gate 2 (item permission) lets you into a specific building. Gate 3 (OneLake role) lets you into a specific room. Gate 4 (RLS) lets you see specific documents in that room. Gate 5 (CLS) lets you see specific fields on those documents. Gate 6 (masking) blurs certain fields you can see but should not fully read. Gate 7 (labels) controls whether you can photocopy and take documents outside the fortress. A visitor with a gate-1 pass cannot photocopy a classified document from gate 7 — every layer must allow it.
Workspace Roles (Building Access)
Workspace roles are the first and broadest security layer. Every user who accesses a Fabric workspace must be assigned a role. The role determines what they can do with ALL items in that workspace — notebooks, pipelines, lakehouses, warehouses, reports, and semantic models.
Admin, Member, Contributor, Viewer
| Capability | Admin | Member | Contributor | Viewer |
|---|---|---|---|---|
| View items and read data | ✅ | ✅ | ✅ | ✅ |
| Create new items (notebooks, pipelines, etc.) | ✅ | ✅ | ✅ | ❌ |
| Edit and run notebooks/pipelines | ✅ | ✅ | ✅ | ❌ |
| Delete any item in the workspace | ✅ | ✅ | ❌ (own items only) | ❌ |
| Share items with others | ✅ | ✅ | ❌ | ❌ |
| Add/remove workspace members | ✅ | ❌ | ❌ | ❌ |
| Change workspace settings | ✅ | ❌ | ❌ | ❌ |
| Delete the workspace | ✅ | ❌ | ❌ | ❌ |
| Read files in OneLake (Tables/Files) | ✅ (always) | ✅ (always) | ✅ (always) | ❌ (needs OneLake role) |
| Write files in OneLake | ✅ | ✅ | ✅ | ❌ |
| Manage OneLake security roles | ✅ | ✅ | ❌ | ❌ |
Key distinctions people miss:
- Admin vs Member: The only difference is that Admin can manage workspace access (add/remove members, change roles) and change workspace settings. Member can do everything else — create, edit, delete, share. In most teams, only 1-2 people need Admin.
- Member vs Contributor: Contributor cannot share items and can only delete items they created. This prevents a junior engineer from accidentally sharing raw data externally or deleting a colleague’s pipeline.
- Contributor vs Viewer: Contributor can create and modify items — they are “builders.” Viewer can only look — they are “consumers.” Analysts who build their own reports need Contributor (or item-level Build permission). Analysts who only view existing reports need Viewer.
- Viewer and OneLake: Viewers do NOT automatically get OneLake file access. They need explicit OneLake data access roles to read tables/files. Admin, Member, and Contributor always have full OneLake access.
Who Gets Which Role
| Person | Role | Why |
|---|---|---|
| Data Engineering Lead | Admin | Manages workspace access, settings, and governance |
| Senior Data Engineers | Member | Create/edit all items, share with stakeholders, run pipelines |
| Junior Data Engineers | Contributor | Build notebooks and pipelines but cannot share or delete others’ work |
| Data Analysts (self-service) | Contributor | Create their own reports and queries, but cannot share externally |
| Business Analysts (read-only) | Viewer | View dashboards, query SQL endpoint (read-only). Cannot modify anything |
| External Auditors | Viewer (temporary) | Time-limited read-only access during audit period. Remove after audit |
| Service Principals (CI/CD) | Contributor | Deploy artifacts via Git integration / deployment pipelines |
Common Role Assignment Mistakes
- “Everyone is Admin” — if all 15 team members are Admin, anyone can remove anyone else, delete the workspace, or change capacity settings. Limit Admin to 1-2 leads.
- “Analysts are Members” — Member can delete ANY item in the workspace. An analyst who accidentally deletes a production pipeline causes an outage. Give analysts Viewer or Contributor.
- “Using personal accounts for automation” — when “naveen@company.com” is the pipeline owner and Naveen leaves the company, the pipeline breaks. Use service principals for automated workloads.
Item-Level Permissions
Workspace roles are all-or-nothing — a Viewer sees ALL items in the workspace. But what if a finance analyst needs access to one specific report, without seeing every notebook and pipeline in the workspace? That is what item-level permissions solve. You can share a specific item (report, semantic model, warehouse, lakehouse) with a user who is NOT a workspace member.
Sharing Items (Read, ReadAll, Reshare, Build)
| Permission | What It Allows | Use Case |
|---|---|---|
| Read | View the item and see reports built on it | Business users viewing dashboards |
| ReadAll | Read ALL underlying data in OneLake (tables, files) | Analysts who need direct Delta/Parquet access |
| ReadData | Query data via the SQL compute engine (SQL endpoint) | Analysts running T-SQL queries against the SQL endpoint |
| Reshare | Share the item with other people | Team leads distributing access to their team |
| Build | Create new content (reports, models) on top of this item | Self-service analysts building their own reports on a shared semantic model |
Example: Sharing a Semantic Model with an analyst outside the workspace
Share with: analyst@company.com
Permissions granted:
✅ Read (can view existing reports built on this model)
✅ Build (can create their own reports using this model)
❌ ReadAll (cannot access raw Delta files in OneLake)
❌ Reshare (cannot share with others — you control distribution)
Result: The analyst sees only this semantic model in their "Shared with me" view.
They can build Power BI reports on it. They CANNOT see notebooks, pipelines,
or other items in the workspace. They CANNOT access the underlying Lakehouse data.
Important distinction — ReadAll vs ReadData:
- ReadAll = access to OneLake files directly (Delta tables, Parquet files, CSV files). The user can read data via Spark notebooks, OneLake APIs, or any tool that connects to OneLake. This is the broadest data access permission for an item.
- ReadData = access via the SQL compute engine only. The user can run T-SQL queries against the SQL analytics endpoint but cannot access the underlying files in OneLake. This is more restrictive — the user sees data through SQL but cannot download raw files.
If OneLake data access roles (preview) are enabled on the item, ReadAll alone is not sufficient — the user also needs an appropriate OneLake data access role to see specific tables/folders.
When to Use Item Permissions vs Workspace Roles
| Scenario | Use | Why |
|---|---|---|
| Engineer needs access to the whole workspace | Workspace role (Member) | Needs to create/edit/run everything in the workspace |
| Analyst needs one specific report | Item permission (Read) | Should not see notebooks, pipelines, or raw data |
| Team lead needs to share a dataset with their team | Item permission (Read + Reshare) | Can distribute access without being workspace Admin |
| Self-service analyst needs to build reports on a model | Item permission (Read + Build) | Can create reports but not modify the underlying model |
| Data scientist needs raw Delta table access | Item permission (ReadAll) + OneLake role | Reads raw files for ML training but cannot modify the Lakehouse |
OneLake Data Access Roles
How OneLake Security Works
OneLake data access roles control which tables and folders a user can see within a Lakehouse. Without OneLake roles, anyone with ReadAll permission to a Lakehouse sees ALL tables and ALL files. With OneLake roles, you can restrict access to specific tables — the marketing team sees customers and orders but NOT salaries.
OneLake security uses a deny-by-default model. When you enable OneLake security on a Lakehouse, ALL users start with NO access to any data. You must explicitly grant access by creating roles and assigning users to them. This is the opposite of the default behavior (where workspace Contributors, Members, and Admins see everything).
Lakehouse: sales_lakehouse (OneLake security ENABLED)
Default state: ALL users have NO access to any table or folder
Role: "engineering_full_access"
Tables: ALL (customers, orders, products, salaries, raw_events)
Files: ALL
Members: data_engineering_group@company.com
Permission: ReadWrite
Role: "marketing_read"
Tables: customers, orders, products (NOT salaries, NOT raw_events)
Files: NONE
Members: marketing_group@company.com
Permission: Read
Role: "hr_sensitive"
Tables: salaries, employees
Files: NONE
Members: hr_group@company.com
Permission: Read
Result:
Marketing analyst queries SQL endpoint → sees customers, orders, products
Marketing analyst tries to query salaries → ACCESS DENIED
HR analyst queries salaries → sees data
HR analyst tries to query orders → ACCESS DENIED (not in their role)
Engineer queries anything → full access
Creating Custom Data Roles
To create OneLake data access roles:
- Open the Lakehouse → click Manage OneLake security (preview)
- Review the confirmation dialog (this enables the preview and cannot be undone on this item)
- Click New role
- Name the role descriptively:
marketing_read,hr_sensitive_access,finance_readonly - Select the tables and/or folders this role can access
- Choose the permission: Read (read-only) or ReadWrite (read and write)
- Add members: individual users, security groups, or automatic assignment based on workspace role
- Save the role
Important notes:
- Only workspace Admin and Member roles can create and manage OneLake security roles. Contributors lost this ability in August 2025.
- OneLake security is per-item — you enable it on a specific Lakehouse, not the entire workspace. Other Lakehouses in the same workspace are unaffected.
- Once enabled, OneLake security cannot be turned off on that item.
- The security applies across all Fabric compute engines — SQL endpoint, Spark notebooks, OneLake APIs, Power BI Direct Lake. A user denied access to a table cannot see it from any engine.
DefaultReader Role
When you first enable OneLake security on a Lakehouse, Fabric automatically creates a DefaultReader role that grants Read access to all tables and files — maintaining the existing behavior. If you delete or modify this role, users lose their blanket access and must be explicitly granted access through custom roles. This is the recommended approach for production: delete DefaultReader and create specific roles for each team.
Row-Level Security (RLS)
Row-level security restricts which rows a user sees when querying a table. The table structure is the same for everyone — same columns, same schema — but different users see different subsets of rows based on their identity. This is essential for multi-tenant data, regional isolation, and compliance.
Real-life analogy: RLS is like a teacher’s gradebook. The gradebook has every student’s grades. When a parent logs in, they see only their child’s grades — not the entire class. The teacher sees everyone. The principal sees everyone. But each parent’s view is filtered to just their rows. The table is the same; the filter changes per user.
RLS in Warehouse (T-SQL)
In a Fabric Warehouse, RLS is implemented using T-SQL security policies and inline table-valued functions. The function checks the current user’s identity and returns rows they are allowed to see. The security policy binds the function to a table as a filter predicate.
-- Step 1: Create a filter function
-- This function returns rows WHERE the region column matches the logged-in user's name
-- OR the user is an admin (sees all rows)
CREATE FUNCTION dbo.fn_region_filter(@region VARCHAR(50))
RETURNS TABLE WITH SCHEMABINDING
AS RETURN SELECT 1 AS result
WHERE @region = USER_NAME()
OR USER_NAME() = 'admin@company.com';
-- Step 2: Create a security policy that binds the function to the table
-- The filter predicate runs automatically on every SELECT against this table
CREATE SECURITY POLICY dbo.RegionSecurity
ADD FILTER PREDICATE dbo.fn_region_filter(region) ON gold.fact_sales
WITH (STATE = ON);
-- What happens now:
-- east_manager@company.com runs: SELECT * FROM gold.fact_sales
-- → Sees ONLY rows where region = 'east_manager@company.com'
-- → The WHERE clause is automatically injected — the user does not see it
--
-- admin@company.com runs the same query:
-- → Sees ALL rows (the OR clause bypasses the filter for admins)
--
-- The user CANNOT bypass RLS — it applies to every query, every tool,
-- every connection to this warehouse. They cannot see, update, or delete
-- rows they are not authorized to access.
For a mapping-table approach (more scalable than hardcoding user names):
-- Create a mapping table: which user sees which region
CREATE TABLE dbo.user_region_mapping (
user_email VARCHAR(200),
region VARCHAR(50)
);
INSERT INTO dbo.user_region_mapping VALUES
('east_mgr@company.com', 'East'),
('west_mgr@company.com', 'West'),
('central_mgr@company.com', 'Central'),
('admin@company.com', 'East'),
('admin@company.com', 'West'),
('admin@company.com', 'Central');
-- Filter function using the mapping table
CREATE FUNCTION dbo.fn_region_filter_v2(@region VARCHAR(50))
RETURNS TABLE WITH SCHEMABINDING
AS RETURN SELECT 1 AS result
WHERE EXISTS (
SELECT 1 FROM dbo.user_region_mapping
WHERE user_email = USER_NAME()
AND region = @region
);
-- Now adding a new region manager is just an INSERT — no code changes
RLS in Lakehouse (SQL Endpoint)
The Lakehouse SQL analytics endpoint supports the same T-SQL security predicates as the Warehouse. The syntax is identical. However, there is a critical scope limitation:
- ✅ RLS applies to SQL endpoint queries (T-SQL)
- ✅ RLS applies to Power BI Direct Lake reports that use the SQL endpoint for authentication
- ❌ RLS does NOT apply to Spark notebooks — Spark reads Delta files directly from OneLake, bypassing the SQL endpoint entirely
For Spark notebook security, use OneLake data access roles (table-level restriction) or implement row filtering in notebook code.
RLS in Semantic Models (DAX)
For Power BI reports, RLS is defined in the semantic model using DAX filter expressions. This is the most common RLS implementation because it controls what report consumers see.
In Power BI Desktop or the Fabric web portal:
1. Open the Semantic Model → Manage roles
2. Create a role: "RegionalAccess"
3. Add a DAX filter on the fact_sales table:
[region] = USERPRINCIPALNAME()
4. Save and publish
5. In the Fabric portal → Semantic Model → Security → add users to the role:
east_manager@company.com → RegionalAccess
west_manager@company.com → RegionalAccess
Result:
east_manager opens the report → sees only East region data
west_manager opens the report → sees only West region data
The DAX filter is applied automatically to every visual in every report
connected to this semantic model
Testing RLS
Always test RLS before deploying to production. In Power BI, use “View as” → select a role → enter a user email to preview what that user sees. In the Warehouse, use EXECUTE AS USER = 'username@company.com' followed by your query, then REVERT to go back to your own identity.
-- Test RLS in Warehouse: impersonate a user
EXECUTE AS USER = 'east_mgr@company.com';
SELECT COUNT(*) FROM gold.fact_sales; -- Should return only East region rows
REVERT; -- Return to your own identity
EXECUTE AS USER = 'admin@company.com';
SELECT COUNT(*) FROM gold.fact_sales; -- Should return ALL rows
REVERT;
Column-Level Security (CLS)
Column-level security restricts which columns a user can see. Unlike RLS (which filters rows), CLS hides entire columns. This is used to protect sensitive fields — salary, SSN, credit card numbers, medical diagnosis — that should not be visible to users who query the same table.
-- Grant access to specific columns ONLY
-- The analyst can see customer_id, name, city, country
-- but CANNOT see email, phone, ssn, or salary
GRANT SELECT ON gold.dim_customer
(customer_id, name, city, country) TO [analyst@company.com];
-- Explicitly deny sensitive columns to a group
DENY SELECT ON gold.dim_customer (email, phone, ssn) TO [marketing_group];
-- If an analyst runs: SELECT * FROM gold.dim_customer
-- They get an error because * includes denied columns
-- They must explicitly list allowed columns:
-- SELECT customer_id, name, city, country FROM gold.dim_customer
When to Use CLS vs Separate Tables
CLS is simpler but has a limitation: users who run SELECT * get an error. For a better user experience with many restricted columns, consider creating views or separate tables — a gold.dim_customer_public view without sensitive columns that analysts query freely, and the full gold.dim_customer table that only HR accesses.
Dynamic Data Masking
Dynamic data masking shows partial or obfuscated values to users who should see the column but not the full value. Unlike CLS (which completely hides a column), masking lets the user see that a value exists — they just cannot read the full value.
Real-life analogy: CLS is like removing a page from a report — the reader does not know it exists. Dynamic masking is like redacting text with a black marker — the reader knows there is an email address, they just cannot read it. Masking is useful when the user needs to know a field is populated (for data quality checks) without seeing the actual value.
Masking Functions
-- Email masking: naveen@company.com → nXXX@XXXX.com
ALTER TABLE gold.dim_customer
ALTER COLUMN email ADD MASKED WITH (FUNCTION = 'email()');
-- Partial masking: 416-555-0123 → 416-XXX-XXXX
ALTER TABLE gold.dim_customer
ALTER COLUMN phone ADD MASKED WITH (FUNCTION = 'partial(3,"XXX-XXX-",4)');
-- partial(prefix_chars, padding, suffix_chars)
-- Default masking: shows type-appropriate default value
-- Numbers → 0, Strings → "XXXX", Dates → 1900-01-01
ALTER TABLE gold.dim_customer
ALTER COLUMN salary ADD MASKED WITH (FUNCTION = 'default()');
-- Random masking: shows a random number in a range
ALTER TABLE gold.dim_customer
ALTER COLUMN age ADD MASKED WITH (FUNCTION = 'random(1, 100)');
Who Sees Masked vs Unmasked Data
-- Grant UNMASK permission to users who need full values
GRANT UNMASK ON gold.dim_customer TO [hr_admin@company.com];
-- Or grant UNMASK on the entire database
GRANT UNMASK TO [security_team];
-- Users WITHOUT UNMASK see:
-- email: nXXX@XXXX.com phone: 416-XXX-XXXX salary: 0
-- Users WITH UNMASK see:
-- email: naveen@company.com phone: 416-555-0123 salary: 95000
-- IMPORTANT: Masking is NOT encryption — a determined user with raw
-- OneLake file access can bypass masking by reading the Delta files directly.
-- Masking protects against SQL queries only. For true data protection,
-- combine masking with OneLake data access roles that restrict file access.
Sensitivity Labels
Sensitivity labels classify data to control how it is handled, shared, and exported. Unlike the previous layers (which control who sees data inside Fabric), labels control what happens when data leaves Fabric — exports to Excel, PDF, email attachments, and external sharing.
Classifying Data (Confidential, Internal, Public)
| Label | Meaning | What Happens on Export | Example Data |
|---|---|---|---|
| Public | Non-sensitive, anyone can access | No restrictions | Published reports, public metrics |
| Internal | Company-internal only | Warning on external sharing | Internal KPIs, team dashboards |
| Confidential | Sensitive business data | Encrypted on export, restricted sharing | Revenue data, customer lists, contracts |
| Highly Confidential | PII, financial, regulated data | Encrypted, audit-logged, no external sharing | SSN, salary, medical records, credit cards |
How to apply labels: Open any Fabric item → Settings → Sensitivity label → select the appropriate label. Labels can be applied manually by item owners or automatically via Microsoft Purview auto-labeling policies.
How Labels Flow Downstream
Labels inherit downstream automatically — this is one of their most powerful features. You set the label once at the source, and every downstream artifact inherits the classification:
Lakehouse (labeled: Confidential)
→ Semantic Model built on it → automatically Confidential
→ Report built on that model → automatically Confidential
→ Excel export from report → file is encrypted, labeled Confidential
→ PDF export → watermarked "Confidential"
→ Email attachment → DLP policy can block external recipients
What this prevents:
Analyst exports Confidential data to Excel → file is encrypted
Analyst tries to email the Excel to a personal Gmail → DLP blocks it
Analyst screenshots the report → watermark identifies the source
Without labels → data walks out the door unprotected
Auto-Labeling Policies
Instead of manually labeling every item, configure Purview auto-labeling policies that scan Fabric items and apply labels automatically based on content. For example: any table containing a column named “SSN” or “social_security_number” automatically gets the “Highly Confidential” label. Any item containing credit card patterns (4 groups of 4 digits) gets “Confidential.” This scales governance across hundreds of items without manual intervention.
Microsoft Purview Integration
Microsoft Purview is the governance layer that sits above Fabric and provides organization-wide data management. While Fabric handles security within a workspace, Purview handles governance across ALL workspaces, ALL data sources (not just Fabric), and ALL compliance requirements.
Data Lineage
Purview automatically tracks the complete flow of data through Fabric — from source to destination, through every transformation:
Azure SQL (source) → Pipeline (Copy Activity) → Bronze Lakehouse → Notebook (PySpark)
→ Silver Lakehouse → Notebook (PySpark) → Gold Warehouse → Semantic Model → Report
In Purview's lineage view:
- Click any item to see its UPSTREAM sources (where did this data come from?)
- Click any item to see its DOWNSTREAM consumers (who uses this data?)
- See the complete chain from raw source to final report
- Identify impact: "If I change the schema of Bronze.customers, which reports break?"
Why lineage matters: When a source system changes a column name, lineage tells you which Silver tables, Gold views, semantic models, and reports are affected — before users report broken dashboards. When an auditor asks “where does the revenue number on this report come from?”, lineage traces it back through every transformation to the source system.
Data Catalog
Purview catalogs ALL Fabric items into a searchable directory. Analysts can discover datasets without asking engineers “where is the customer data?” — they search the catalog and find gold.dim_customer with its description, owner, classifications, lineage, and endorsement status. This eliminates the “shadow data” problem where teams build duplicate datasets because they do not know the official one exists.
Data Classification
Purview automatically scans Fabric items and classifies columns based on content patterns — it recognizes 200+ built-in classification types:
Auto-detected classifications:
dim_customer.email → "Email Address" (PII)
dim_customer.phone → "Phone Number" (PII)
dim_customer.ssn → "Social Security Number" (Sensitive PII)
fact_sales.credit_card → "Credit Card Number" (PCI)
dim_customer.ip_address → "IP Address" (PII)
What Purview does with these classifications:
1. Tags the column in the data catalog (searchable)
2. Recommends sensitivity labels (Confidential for PII columns)
3. Feeds into compliance reports (GDPR, HIPAA, PCI-DSS)
4. Powers auto-labeling policies (columns with SSN → Highly Confidential)
5. Surfaces in Data Estate Insights for governance dashboards
Endorsement (Promoted and Certified)
Endorsement is how organizations signal which datasets are trustworthy and recommended for use. This prevents analysts from building reports on staging tables or outdated copies.
| Status | Meaning | Who Can Set | Visual Indicator |
|---|---|---|---|
| None | Default — not validated | N/A | No badge |
| Promoted | “This is useful and recommended” | Any workspace Member | Blue badge |
| Certified | “This is officially validated by governance” | Designated Certifiers only (set by Fabric Admin) | Green badge with checkmark |
To set endorsement: Open the item → Settings → Endorsement → select Promoted or Certified. Certified items appear higher in search results and are flagged as trusted in the catalog. Only users designated as “Certifiers” by the Fabric Admin can certify items — this prevents self-certification.
Audit Logs
Every action in Fabric is logged — who accessed what, when, and what they did. Audit logs are essential for compliance (GDPR, HIPAA, SOX), incident investigation, and governance reporting.
Audit log captures:
✅ Who viewed a report (user, timestamp, report name)
✅ Who ran a pipeline (user, pipeline name, start/end, status)
✅ Who queried the SQL endpoint (user, query text, rows returned)
✅ Who shared an item (sharer, recipient, permissions granted)
✅ Who exported data (user, export format, sensitivity label)
✅ Who changed workspace roles (admin, who was added/removed, old/new role)
✅ Who modified a notebook (user, item name, action type)
✅ Who downloaded files from OneLake (user, file path, size)
Accessing audit logs:
| Method | How | Best For |
|---|---|---|
| Microsoft 365 Audit Log | compliance.microsoft.com → Audit | Manual investigation, compliance audits |
| PowerShell | Search-UnifiedAuditLog cmdlet | Automated extraction, scheduled reports |
| Microsoft Purview | Purview portal → Activity explorer | Governance dashboards, DLP reports |
| Admin Monitoring workspace | Fabric Admin portal → Monitoring | Capacity usage, per-item activity |
Retention: Microsoft 365 E5 license retains audit logs for 1 year by default. E3 retains 90 days. For longer retention (regulatory requirements), export logs regularly via PowerShell to Azure Storage or your own data lake and archive them.
Real-World Security Architecture
Scenario: Multi-Team Data Platform
A company has three teams using Fabric: Data Engineering builds and maintains the platform, Marketing analyzes customer behavior, and HR manages employee data. Here is how to architect security using all seven layers:
WORKSPACE: DataPlatform_Prod
Roles:
Admin: DE Lead (1 person — manages access and settings)
Member: Senior Engineers (5 people — create, edit, share everything)
Contributor: Junior Engineers (3 people — build but cannot share or delete others' work)
Viewer: Business Analysts, Marketing, HR (view reports, query SQL endpoint)
LAKEHOUSE: silver_lakehouse (OneLake security ENABLED)
OneLake Roles:
"engineering_all": ALL tables → data_engineering_group
"marketing_data": customers, orders, products → marketing_group
"hr_data": employees, salaries, benefits → hr_group
→ Marketing cannot see salaries. HR cannot see orders. Engineers see everything.
WAREHOUSE: gold_warehouse
Schema permissions:
staging schema → DENY to Viewers (engineers only)
gold schema → GRANT SELECT to all Viewers
RLS on gold.fact_sales:
Regional managers see only their region (mapping table approach)
CLS on gold.dim_customer:
DENY email, phone, ssn columns to marketing_group
Masking:
salary column → default() mask for non-HR users
email column → email() mask for non-privileged users
SEMANTIC MODEL: Sales Analytics
Connection: Direct Lake on gold_warehouse
RLS: RegionalAccess role (DAX filter on region)
Sensitivity Label: Confidential
Endorsement: Certified ✅
REPORT: Monthly Revenue Dashboard
Inherits Confidential label from semantic model
RLS enforced — each regional manager sees only their region
Export to Excel → encrypted file with Confidential label
External sharing → blocked by DLP policy
This architecture uses all seven layers: workspace roles (who enters), OneLake roles (which tables), schema permissions (which schemas), RLS (which rows), CLS (which columns), masking (obfuscated values), and labels (export controls). Each layer adds protection that the others do not provide.
Common Mistakes
- Giving everyone Admin role — Admin can delete the workspace, remove other members, and change capacity settings. Most engineers need Member, most analysts need Viewer. Limit Admin to 1-2 leads.
- Not implementing RLS — without RLS, every Viewer sees ALL rows in every table. Regional managers see other regions’ data. Department heads see other departments’ salaries. This is a compliance violation in most organizations.
- Forgetting sensitivity labels — a Confidential report exported to Excel without a label loses its protection. The file can be emailed externally, uploaded to personal drives, or shared on social media. Labels ensure protection travels with the data.
- Not using OneLake data access roles — without them, a workspace Viewer with ReadAll permission sees ALL tables in every Lakehouse. Use OneLake roles to restrict access to specific tables per team.
- Relying only on workspace roles — workspace roles are coarse (all-or-nothing per workspace). They cannot restrict specific tables, rows, columns, or items. Combine workspace roles with item permissions, OneLake roles, RLS, CLS, and masking for defense-in-depth.
- RLS in Warehouse but not in Semantic Model — a user querying via SQL sees filtered rows (RLS works). The same user viewing a Power BI report sees ALL rows (semantic model has no RLS). Implement RLS at BOTH layers for complete protection.
- Masking without OneLake role restriction — masking only applies to SQL queries. A user with OneLake file access can read the raw Delta/Parquet files and see unmasked values. Always pair masking with OneLake data access roles that restrict file-level access.
- Not testing RLS before production — use EXECUTE AS USER in Warehouse and “View as role” in Power BI to verify each role sees only what it should. Untested RLS is worse than no RLS — it gives a false sense of security.
Interview Questions
Q: Describe the security layers in Microsoft Fabric. A: Fabric uses seven security layers in a defense-in-depth model: (1) Workspace roles control who enters a workspace (Admin, Member, Contributor, Viewer). (2) Item permissions grant access to specific items without workspace membership (Read, ReadAll, ReadData, Reshare, Build). (3) OneLake data access roles control which tables/folders a user sees within a Lakehouse. (4) Row-level security filters which rows a user sees (T-SQL predicates or DAX filters). (5) Column-level security hides specific columns (GRANT/DENY SELECT). (6) Dynamic data masking shows obfuscated values (email, partial, default functions). (7) Sensitivity labels control how data is handled on export (encryption, DLP policies). Each layer narrows access further.
Q: What is the difference between Admin, Member, Contributor, and Viewer workspace roles? A: Admin manages workspace access, settings, and can delete the workspace. Member can create, edit, delete, and share all items but cannot manage access. Contributor can create and edit items but cannot share or delete others’ items. Viewer can only view and query (read-only). Additionally, Admin, Member, and Contributor always have full OneLake file access, while Viewer needs explicit OneLake data access roles.
Q: What is the difference between RLS in a Warehouse vs a Semantic Model? A: Warehouse RLS uses T-SQL security policies with filter predicates — it applies to all SQL queries against the warehouse. Semantic Model RLS uses DAX filter expressions — it applies to Power BI reports built on that model. They are independent: implementing RLS in the warehouse does NOT automatically apply to the semantic model, and vice versa. For complete protection, implement RLS at both layers.
Q: What are OneLake data access roles and when do you need them? A: OneLake data access roles control which tables and folders a user can read within a Lakehouse. They use a deny-by-default model — when enabled, all users start with no access and must be explicitly granted access through roles. You need them when different teams should see different tables (marketing sees customers but not salaries), when Viewers need access to specific tables only, or when you want to enforce consistent security across all compute engines (SQL, Spark, OneLake APIs).
Q: How do sensitivity labels work in Fabric? A: Labels classify data as Public, Internal, Confidential, or Highly Confidential. They are applied to Fabric items and inherit downstream automatically — a Confidential Lakehouse produces Confidential semantic models and reports. When data is exported (Excel, PDF, email), the label travels with it and enforces protection: encryption, watermarks, DLP policies that block external sharing. Labels are set manually or automatically via Purview auto-labeling policies.
Q: What is the difference between column-level security and dynamic data masking? A: CLS completely hides a column — the user does not know it exists and gets an error if they try to SELECT it. Masking shows the column with obfuscated values — the user sees “nXXX@XXXX.com” instead of the real email. Use CLS when a user should never see the column (SSN for marketing). Use masking when a user needs to know a value exists but should not read it (email for data quality checks).
Q: How would you implement security for a multi-team Fabric platform? A: Use all seven layers: workspace roles for coarse access (engineers = Member, analysts = Viewer), OneLake data access roles for table-level isolation (marketing sees customers, HR sees salaries), RLS in both Warehouse and Semantic Model for row-level filtering (regional managers see only their region), CLS for column restriction (deny SSN to non-HR), masking for obfuscation (email masking for marketing), and sensitivity labels for export control (Confidential data is encrypted on export). Test each layer with EXECUTE AS USER and “View as role” before deploying.
Wrapping Up
Security in Fabric is not a single setting — it is seven layers that work together. Workspace roles control who enters. Item permissions control what they access. OneLake data access roles control which tables they see. RLS controls which rows. CLS controls which columns. Masking obfuscates values. Sensitivity labels control what happens on export. Each layer addresses a different scope, and no single layer is sufficient alone.
For the DP-700 exam, know the difference between each layer, when to use each one, and how they interact. Know that RLS in the Warehouse does not automatically apply to the Semantic Model. Know that masking only protects SQL queries, not raw file access. Know that OneLake data access roles use a deny-by-default model. And know that sensitivity labels inherit downstream — set once at the source, enforced everywhere.
Related posts:
- Fabric Warehouse Practical Guide
- Fabric Foundations
- Administration & Cost Management
- Git Integration & CI/CD
Naveen Vuppula is a Senior Data Engineering Consultant and app developer based in Ontario, Canada. He writes about Python, SQL, AWS, Azure, and everything data engineering at DriveDataScience.com.