Wicked Smart Data
LearnInsightsAboutContact
Sign InLet's Build
LearnInsightsAboutContact
Sign InLet's Build
Wicked Smart Data

Intelligence, automation, and expert execution — plus an elite library of free knowledge. We turn complexity into competitive advantage.

Start a conversation

Platform

  • Learning Paths
  • Insights
  • RSS Feed

Company

  • About
  • Contact
  • Work With Us

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Wicked Smart Data. All rights reserved.

Intelligence · Automation · Advantage

All Insights
Microsoft Fabric

Securing and Governing Microsoft Fabric: Workspace Roles, Item Permissions, and OneLake Data Access

Fabric's security model has four distinct permission layers — and most teams only know about one of them. This deep-dive lesson teaches you how workspace roles, item permissions, and OneLake data access policies interact so you can design and audit a governance model that actually holds up in production.

🔥 Expert29 min readSep 22, 2026Updated Sep 22, 2026
Securing and Governing Microsoft Fabric: Workspace Roles, Item Permissions, and OneLake Data Access
On this page
  • Introduction
  • Prerequisites
  • Understanding the Four Permission Layers
  • Workspace Roles in Depth
  • Admin
  • Member
  • Contributor
  • Viewer
  • The Role You Don't Have: No Workspace Role
  • Item-Level Permissions
  • Sharing Items
  • Lakehouse Item Permissions
  • Warehouse Item Permissions
  • Semantic Model Permissions
  • OneLake Data Access Policies
  • What Problem Do They Solve?
  • How to Configure OneLake Data Access Policies
  • OneLake Policies vs. SQL Object Permissions
  • Designing a Multi-Team Governance Model
  • Workspace Role Assignments
  • OneLake Policies for the Gold Lakehouse
  • Semantic Model RLS for the Risk Dataset
  • Auditing and Monitoring Access
  • The Fabric Activity Log
  • The Fabric Admin APIs
  • Cross-Workspace Data Access and Shortcuts Security
  • Internal Shortcuts
  • External Shortcuts (ADLS Gen2, S3)
  • Service Principals and Managed Identities
  • Registering a Service Principal for Fabric Access
  • Managed Identities for Fabric Items
  • Hands-On Exercise
  • Common Mistakes and Troubleshooting
  • Mistake 1: Giving Everyone Contributor "Just in Case"
  • Mistake 2: Conflating Item Sharing with Data Access
  • Mistake 3: Not Accounting for the Default Semantic Model
  • Mistake 4: Trusting SQL Security to Protect Notebook Access
  • Mistake 5: Shortcut Permission Confusion After Workspace Migration
  • Troubleshooting: "User can see item but cannot query data"
  • Troubleshooting: "Direct Lake model returns errors in production"
  • Summary and Next Steps
  • Securing and Governing Microsoft Fabric: Workspace Roles, Item Permissions, and OneLake Data Access

    Introduction

    Imagine you've spent three months building a medallion architecture in Microsoft Fabric — bronze tables landing from pipelines, silver layers cleaned by Spark notebooks, gold semantic models powering executive dashboards. The project is a success. Then your CISO asks a single question: "Who has access to what, and how do you know?" You open the Fabric portal, click around for a few minutes, and realize you actually can't answer that question clearly. You granted a few workspace roles early on, shared a couple of items ad-hoc, and now the access picture is a tangled web of overlapping permissions that nobody fully understands.

    This is the most common governance failure in Fabric deployments. It's not malice — it's the natural result of moving fast and treating security as an afterthought. Fabric's permission model is genuinely sophisticated, but that sophistication cuts both ways: it gives you fine-grained control, but it also gives you plenty of rope to tangle yourself with. The system has at least four distinct permission layers — capacity, workspace, item, and OneLake — and they interact in ways that aren't always obvious.

    By the end of this lesson, you'll be able to design and implement a complete access control strategy for a real Fabric deployment. That means knowing which permission layer to use for which scenario, understanding how permissions propagate through OneLake, and knowing where the sharp edges are before you hit them in production.

    What you'll learn:

    • How Fabric's layered permission model works, from capacity admin down to individual OneLake paths
    • What each workspace role can and cannot do — including the non-obvious gaps in Contributor
    • How item-level permissions interact with (and override) workspace roles
    • How OneLake data access policies work and how they differ from everything above them
    • How to design a governance model for a multi-team, multi-environment deployment that you can actually audit

    Prerequisites

    You should be comfortable working in the Fabric portal and understand the basic building blocks: workspaces, lakehouses, warehouses, and semantic models. If you need a foundation, read What Is Microsoft Fabric? Workloads, OneLake, and How It Fits with Power BI first. You should also understand how Fabric capacities and workspaces are structured, since capacity-level admin permissions sit above everything else we'll discuss. Basic familiarity with OneLake and Delta tables is assumed.


    Understanding the Four Permission Layers

    Before you can govern Fabric intelligently, you need a mental model of how its permission system is actually layered. Most tutorials talk only about workspace roles. That leaves out three other distinct permission systems that interact — sometimes in surprising ways.

    Layer 1: Capacity-level permissions sit at the very top. Capacity admins can access any workspace assigned to that capacity, pause and resume the capacity, and override workspace-level settings. This role is typically held by platform engineers or central IT, not data teams.

    Layer 2: Workspace roles control who can see and interact with a workspace and its contents. There are four roles: Admin, Member, Contributor, and Viewer. These are coarse-grained and apply uniformly to everything inside the workspace.

    Layer 3: Item-level permissions are granted on individual Fabric items — a specific lakehouse, warehouse, semantic model, or report. These can be granted to users who have no workspace role at all, enabling read-only or compute-only access to a single asset without exposing the rest of the workspace.

    Layer 4: OneLake data access policies are a newer addition that operate beneath all of the above. They control access to specific paths inside OneLake — folders, tables, and files — independently of whether someone has a workspace role or item permission.

    These layers are additive in the sense that they all apply simultaneously, but restrictive in the sense that a lower layer can restrict what a higher layer grants. A workspace Viewer can be blocked from reading a specific Delta table by an OneLake policy that doesn't include them. A user with no workspace role can be granted read access to a single lakehouse via an item permission. Understanding these interactions is the entire game.

    Key insight

    There's no single "permissions report" in Fabric that shows you the union of all four layers for a given user. You need to understand the model well enough to reason through it manually — or build your own audit tooling via the Fabric Admin APIs.


    Workspace Roles in Depth

    Workspace roles are the backbone of access control for most teams. Let's be precise about what each role actually means, because the marketing-level descriptions ("Contributor can create content!") hide important nuances.

    Admin

    Workspace Admins have full control: they can add and remove members, change the workspace's capacity assignment, publish apps, delete the workspace, and access every item inside it. From a governance perspective, the key risk with Admin is that it's impossible to audit what an Admin did after the fact at the workspace level without digging into activity logs. Every Fabric deployment should maintain a short, documented list of workspace Admins.

    One subtle behavior: Workspace Admins can grant themselves access to items even if item-level permissions were deliberately configured to exclude them. The Admin role effectively bypasses item-level permission restrictions. This is a critical point we'll return to when discussing the separation of duties.

    Member

    Members can do almost everything Admins can except manage membership and delete the workspace. They can create, read, update, and delete items; they can publish and update apps; they can share items with other users. The "share" capability is where governance breaks down in many organizations — any Member can grant external users access to individual items, creating permission grants that aren't visible from the workspace role list.

    Contributor

    Contributor is the role most engineers end up in, and it has a subtle limitation that catches teams off guard: Contributors cannot share items or publish apps. They can create and modify items, run notebooks and pipelines, and read everything in the workspace — but they can't extend access to others. This makes Contributor appropriate for data engineers and analysts who are building content but shouldn't be making governance decisions.

    Warning

    Contributors have full read access to all data in all items in the workspace by default. A data engineer with Contributor access to your gold workspace can query your entire customer dataset from a Spark notebook. If that's a problem, you need item-level permissions or OneLake policies to further restrict data access — not just workspace roles.

    Viewer

    Viewers can read items but cannot create or modify them. However, "read" means different things for different item types. A Viewer on a workspace can:

    • View and interact with Power BI reports
    • See item metadata (name, description, lineage information)
    • Query a semantic model via Analyze in Excel or third-party tools

    But a Viewer cannot:

    • Query a lakehouse SQL analytics endpoint directly via a SQL client
    • Browse OneLake file paths in the lakehouse Explorer
    • Run a notebook or pipeline

    This asymmetry is important. Viewer is appropriate for business consumers who access data through published Power BI reports. It's not appropriate as a substitute for granular data access on lakehouses or warehouses — those require item-level permissions on top of, or instead of, a workspace role.

    The Role You Don't Have: No Workspace Role

    It's completely valid to grant a user access to a specific Fabric item without giving them any workspace role at all. A user with no workspace role who has been granted item-level Read access to a warehouse can connect via the SQL analytics endpoint and run queries — they just can't see the workspace in their workspace list or access any other items. This pattern is important for data consumers who should see exactly one dataset, not the entire engineering workspace.


    Item-Level Permissions

    Item permissions let you carve out access to individual Fabric items with more precision than workspace roles allow. Each item type exposes a slightly different permission model.

    Sharing Items

    To share an item, navigate to it in the Fabric portal, open the "..." context menu, and select "Manage permissions." From there, you can grant users or groups direct access. The "Share" button also exists in the item toolbar for supported item types.

    When you share an item, you can optionally include:

    • Reshare — allows the recipient to share the item with others (dangerous; default to off)
    • Build — for semantic models, allows the recipient to create new reports on top of the model

    These checkboxes look innocuous but have significant governance implications. Granting Reshare to a consultant or partner creates a permission chain that's essentially invisible from your workspace management view.

    Lakehouse Item Permissions

    For lakehouses, item-level sharing grants access to the lakehouse's SQL analytics endpoint and to the default semantic model. You can share a lakehouse with Read, ReadData, or ReadAll permissions:

    • Read — the user can view the lakehouse in the portal, see table names and schemas, and execute queries against the SQL analytics endpoint
    • ReadData — allows querying data but not viewing the item metadata
    • ReadAll — provides access to the underlying OneLake files for the entire lakehouse, not just the SQL surface

    Warning

    ReadAll on a lakehouse item is powerful. It gives the recipient programmatic access to every file in the lakehouse, including raw files in the /Files section and all Delta tables in /Tables. If you need table-level granularity, don't use ReadAll — use OneLake data access policies or SQL-level grants instead.

    Warehouse Item Permissions

    Warehouses expose a more SQL-centric permission model. At the item level, you can grant workspace users or external recipients the SQL permissions they need — but for fine-grained column or row-level security, you implement that with T-SQL directly inside the warehouse using GRANT, DENY, and CREATE ROW SECURITY POLICY statements, just as you would in Azure SQL Database. Item-level sharing gets users connected to the warehouse endpoint; T-SQL security controls what data they can actually see.

    This approach is explored further in Building a Fabric Data Warehouse with T-SQL: Tables, Views, and Cross-Database Queries, where the security model for warehouse objects is covered in detail.

    Semantic Model Permissions

    Semantic models support the most nuanced item-level permission model because Power BI's own permission system is embedded here. The key permissions are:

    • Read — can view reports built on the model, but not connect with external tools
    • Build — can create new reports in Power BI Desktop or the service using the model as a source
    • Reshare — can grant other users access to the model
    • Write — can edit the model definition itself (reserved for model owners/admins)

    For organizations implementing Direct Lake mode, there's an additional wrinkle: the semantic model must have access to the underlying OneLake data. This is typically handled by granting the semantic model's service principal Read access to the lakehouse. If the underlying OneLake permissions change in a way that breaks this service principal's access, your Direct Lake model will fail silently — it will fall back to DirectQuery mode or throw errors depending on configuration.

    Tip

    When you share a semantic model in Direct Lake mode, think carefully about the data access path. Users querying the model are getting data through the model's identity, not their own. Row-level security (RLS) defined in the model is your primary data governance tool for controlling what different users see in reports.


    OneLake Data Access Policies

    OneLake data access policies are the newest and most granular layer of the permission stack. They allow you to define access controls at the level of individual folders and tables within OneLake, independently of workspace or item permissions.

    What Problem Do They Solve?

    Consider a lakehouse that contains tables for twelve different business domains — HR, Finance, Supply Chain, Customer, and so on. The data engineering team needs full access to the entire lakehouse to run transformations. The Finance analytics team should only see Finance tables. The Customer team should only see Customer tables. The HR data is sensitive and should be restricted to a very small group.

    Without OneLake policies, your options are ugly:

    1. Create a separate lakehouse per domain (12 lakehouses, 12× the operational overhead)
    2. Grant warehouse column/row security on top of the SQL analytics endpoint (doesn't cover notebook or direct file access)
    3. Hope that workspace roles are restrictive enough (they're not)

    OneLake data access policies solve this directly. You define a policy that grants a security group read access to only the Tables/finance path in the lakehouse. Contributors and Viewers in the workspace who are not in that group cannot read those tables from notebooks, the SQL endpoint, or direct OneLake file access.

    How to Configure OneLake Data Access Policies

    OneLake data access policies are managed through the Fabric Admin portal, not the workspace UI — a fact that surprises most people when they first look for them.

    Navigate to: Admin Portal → OneLake data access settings (or in some tenants, through the lakehouse settings directly via the "..." menu → "Manage OneLake security").

    Note

    As of mid-2024, OneLake data access policies are in general availability for lakehouses but are still rolling out for other item types. Always verify current support in the Microsoft documentation for your specific Fabric version.

    A policy definition looks like this in its logical form:

    Resource: onelake://<workspace-id>/<lakehouse-id>/Tables/finance
    Principal: finance_analytics_group@contoso.com
    Permission: Read
    

    You can define multiple policies for different paths and different principals. The key behaviors are:

    1. Policies are additive. If a user is granted access to /Tables/finance and /Tables/supply_chain, they can read both path subtrees.
    2. Policies do not grant workspace access. A user who has only an OneLake policy and no workspace role or item permission cannot even see the workspace. You still need to share the item with them or give them a workspace role to get them connected.
    3. Policies apply across all access methods. Whether a user accesses data via the SQL analytics endpoint, a Spark notebook, the OneLake file browser, or the OneLake APIs, the OneLake policy applies. This is the critical advantage over SQL-only security.

    OneLake Policies vs. SQL Object Permissions

    A common source of confusion is the relationship between OneLake policies and the SQL object permissions you can set on the lakehouse's SQL analytics endpoint. These are separate systems:

    • SQL object permissions (GRANT SELECT on SCHEMA::finance) apply only when data is accessed via the SQL analytics endpoint
    • OneLake data access policies apply regardless of how the data is accessed

    If you implement SQL-level grants but not OneLake policies, a data engineer with a Spark notebook can bypass your SQL security entirely by reading the Delta table files directly from OneLake. This is a real attack vector — not hypothetical.

    The right architecture for truly secure data domains within a single lakehouse is to implement both: SQL object permissions for fine-grained column/row security on the SQL surface, and OneLake policies for restricting which paths are accessible at all. Think of SQL permissions as the "what can you do once you're in the room" control, and OneLake policies as "can you enter the room at all."

    Key insight

    For workloads where all data access happens through Power BI reports using a semantic model with RLS, OneLake policies may be overkill. But the moment users can access data directly — via Spark notebooks, the SQL endpoint with external tools, or OneLake APIs — you need OneLake policies to close the perimeter.


    Designing a Multi-Team Governance Model

    Let's translate all of this into a practical design. We'll use a realistic scenario: a mid-size financial services company building a Fabric platform for three teams.

    The teams:

    • Data Platform Team (6 engineers): owns all ingestion, transformation, and lakehouse/warehouse infrastructure
    • Finance Analytics Team (12 analysts): builds and consumes Finance reports; should not see HR or Customer data
    • Risk Management Team (4 analysts): needs read access to a curated Risk dataset that is derived from Finance and Customer data, but should not see either source directly

    The Fabric items:

    • Three workspaces: platform-dev, platform-prod, and analytics-prod
    • A bronze-silver-gold lakehouse in platform-prod
    • A Finance warehouse in analytics-prod
    • A Risk semantic model in analytics-prod

    Workspace Role Assignments

    platform-dev:
      Admin: data-platform-leads@contoso.com (2 people)
      Member: data-platform-team@contoso.com (6 people)
      Contributor: (none — avoid giving Contributor to non-engineers)
      Viewer: (none)
    
    platform-prod:
      Admin: data-platform-leads@contoso.com
      Member: data-platform-team@contoso.com
      Contributor: (none)
      Viewer: (none — no business users in the platform workspace)
    
    analytics-prod:
      Admin: data-platform-leads@contoso.com
      Member: data-analytics-leads@contoso.com (2 people)
      Contributor: finance-analytics-team@contoso.com
      Viewer: risk-management-team@contoso.com
    

    Notice that the Risk Management team is Viewer in analytics-prod — they can see reports, but we still need to control their data access at the semantic model level via RLS.

    OneLake Policies for the Gold Lakehouse

    The gold lakehouse in platform-prod contains Tables/finance, Tables/customer, Tables/hr, and Tables/risk. Here's the OneLake policy design:

    Policy 1:
      Resource: platform-prod/gold-lakehouse/Tables/finance
      Principal: finance-analytics-team@contoso.com
      Permission: Read
    
    Policy 2:
      Resource: platform-prod/gold-lakehouse/Tables/risk
      Principal: risk-management-team@contoso.com
      Permission: Read
    
    Policy 3:
      Resource: platform-prod/gold-lakehouse/Tables/*
      Principal: data-platform-team@contoso.com
      Permission: ReadWrite
    

    But wait — neither the Finance Analytics team nor the Risk Management team is in platform-prod. They're in analytics-prod. Do they need workspace access to platform-prod too?

    No — and this is where OneLake shortcuts come in. The Finance warehouse in analytics-prod uses a shortcut to point at Tables/finance in the gold lakehouse. When a Finance analyst queries the warehouse, they're reading the gold lakehouse data through the shortcut — but their access is governed by the OneLake policy on the source lakehouse path. They never need to be in the platform-prod workspace at all. The shortcut acts as a read-through, and OneLake policies on the source still apply.

    Tip

    Shortcuts preserve the access control of the source. When you create a shortcut in a lakehouse or warehouse pointing to another OneLake path, users accessing data through the shortcut must have permission on the source path, not just the destination item. This is by design and is a critical security property — it prevents "shortcut laundering" of permissions.

    Semantic Model RLS for the Risk Dataset

    The Risk semantic model aggregates from Finance and Customer data into a single Risk summary. Risk Management team members are workspace Viewers, so they can see the model and interact with reports. But within the model, we need RLS to ensure that different Risk analysts only see data for their assigned portfolios.

    In Power BI Desktop (or the web model editor), you define RLS roles:

    // Role: Portfolio_Restricted
    [PortfolioManagerEmail] = USERPRINCIPALNAME()
    

    This DAX filter ensures each analyst only sees rows where their email matches the portfolio manager field. You assign the risk-management-team@contoso.com security group to this role in the semantic model's security settings.

    Warning

    RLS in semantic models only applies when users are accessing data through the semantic model. If a Risk analyst has direct read access to the underlying lakehouse tables (via a workspace role, item permission, or OneLake policy), they can bypass RLS entirely. Ensure that your OneLake policies are configured so Risk analysts can only reach the Risk table — not the Finance or Customer source tables.


    Auditing and Monitoring Access

    Building an access model is half the job. Knowing whether it's working as designed over time is the other half — and most teams skip this part.

    The Fabric Activity Log

    Fabric writes activity events to the Microsoft 365 Unified Audit Log. You can query this via PowerShell or the Microsoft Purview portal. Key event categories include:

    • CreateItem, DeleteItem, UpdateItem — item lifecycle events
    • ShareItem, UpdateItemPermissions — permission change events
    • ViewItem, ReadItem — data access events (not all item types generate these)

    To pull these logs programmatically:

    # Requires Microsoft.Graph or ExchangeOnlineManagement module
    Search-UnifiedAuditLog `
      -StartDate (Get-Date).AddDays(-7) `
      -EndDate (Get-Date) `
      -RecordType FabricData `
      -Operations "ShareItem","UpdateItemPermissions" `
      -ResultSize 1000 |
      Select-Object CreationDate, UserIds, Operations, AuditData |
      Export-Csv ./fabric_permission_changes.csv -NoTypeInformation
    

    This gives you a log of who changed permissions on what items over the past week. In a governed environment, this should be reviewed weekly and any unexpected permission grants should trigger an incident.

    The Fabric Admin APIs

    The Fabric REST APIs expose workspace membership and item permission information programmatically. To get all workspace role assignments:

    GET https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/roleAssignments
    Authorization: Bearer {token}
    

    Response:

    {
      "value": [
        {
          "id": "8f3a9c12-...",
          "role": "Member",
          "principal": {
            "id": "a1b2c3d4-...",
            "displayName": "Finance Analytics Team",
            "type": "Group"
          }
        }
      ]
    }
    

    You can combine this with the activity log data to build a permissions inventory: who has what role in which workspace, and when was it last modified. In a regulated environment, you'd run this weekly and compare against an approved baseline configuration stored in source control.

    Speaking of source control — if you're using Fabric Git integration, workspace settings and item metadata are versioned, but workspace role assignments are not included in the Git sync. You'll need to manage role assignments separately, ideally through a deployment script that runs as part of your CI/CD pipeline.

    import requests
    import json
    
    def set_workspace_roles(workspace_id, token, role_config):
        """
        role_config: list of {"principalId": "...", "principalType": "Group", "role": "Contributor"}
        """
        headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
        
        # First, get current assignments
        current = requests.get(
            f"https://api.fabric.microsoft.com/v1/workspaces/{workspace_id}/roleAssignments",
            headers=headers
        ).json()["value"]
        
        current_ids = {r["principal"]["id"] for r in current}
        desired_ids = {r["principalId"] for r in role_config}
        
        # Remove unexpected assignments
        for assignment in current:
            if assignment["principal"]["id"] not in desired_ids:
                requests.delete(
                    f"https://api.fabric.microsoft.com/v1/workspaces/{workspace_id}/roleAssignments/{assignment['id']}",
                    headers=headers
                )
        
        # Add missing assignments
        for desired in role_config:
            if desired["principalId"] not in current_ids:
                requests.post(
                    f"https://api.fabric.microsoft.com/v1/workspaces/{workspace_id}/roleAssignments",
                    headers=headers,
                    json=desired
                )
    

    This pattern — define desired state in a config file, compare against actual state, reconcile — is how mature platform teams manage permissions at scale. It's infrastructure-as-code applied to access control.


    Cross-Workspace Data Access and Shortcuts Security

    One of the most powerful — and most commonly misunderstood — features of Fabric is how OneLake shortcuts interact with security across workspaces and external sources.

    Internal Shortcuts

    When you create a shortcut from Lakehouse B pointing to a path in Lakehouse A, users accessing data through the shortcut in Lakehouse B are validated against the source permissions in Lakehouse A. This is a critical security property.

    What this means in practice:

    1. User "Ana" is a Contributor in Workspace B (where Lakehouse B lives).
    2. Lakehouse B has a shortcut to /Tables/hr_salary in Lakehouse A.
    3. Ana does not have access to /Tables/hr_salary in Lakehouse A via OneLake policies or workspace roles.
    4. Ana queries the shortcut path in Lakehouse B from a Spark notebook.
    5. Result: Access denied. The OneLake policy on Lakehouse A is enforced at the source, regardless of Ana's role in Workspace B.

    This is the correct behavior — but it requires you to explicitly grant source access to anyone who needs it. In the previous multi-team design, we granted finance-analytics-team an OneLake policy on the source gold lakehouse tables. That's what makes the shortcut usable for them.

    External Shortcuts (ADLS Gen2, S3)

    When you create a shortcut to an external source like Azure Data Lake Storage Gen2, the security model changes. The shortcut uses a credential (either a service principal or a managed identity) to authenticate to the external source. Users querying data through the shortcut are not authenticated against the external source with their own identity — they inherit the credential attached to the shortcut.

    This has a significant implication: anyone who can read the shortcut in Fabric can access the external data, subject only to their Fabric permissions. The external source's RBAC (e.g., Azure RBAC on the ADLS Gen2 account) controls what the shortcut credential can do — but individual users querying through the shortcut don't need their own Azure RBAC grants.

    Warning

    This "pass-through credential" behavior for external shortcuts means that your OneLake access policies and workspace roles become the sole access control layer for external data accessed via shortcuts. If you have sensitive data in ADLS Gen2, ensure you don't create shortcuts to it in workspaces with permissive workspace roles. The external source's RBAC grants are on the credential, not the individual user.


    Service Principals and Managed Identities

    Production Fabric deployments almost always involve automated processes: pipelines, notebooks running on schedule, external applications calling the Fabric APIs. These need identities too — and service principals are how you handle that.

    Registering a Service Principal for Fabric Access

    1. Register an app in Azure Active Directory (Entra ID) and create a client secret or certificate.
    2. In the Fabric Admin Portal, enable "Service principals can use Fabric APIs" under Developer settings.
    3. Add the service principal to a workspace role or grant it item-level permissions as you would any user.

    Service principals follow the same four-layer permission model as users. A pipeline running as a service principal that is a workspace Contributor can read all items in that workspace unless OneLake policies further restrict it.

    Tip

    Follow the principle of least privilege for service principals ruthlessly. A data pipeline that only needs to write to one lakehouse should be a Contributor in exactly one workspace and have an OneLake write policy on exactly that lakehouse path — nothing more. Service principals don't get tired of arguing about access; they'll use every permission they have, and so will anyone who obtains their credentials.

    For automated deployments and data pipeline orchestration, use separate service principals for dev, test, and production environments. Never share credentials across environments — the ability to deploy to production should be explicitly gated, not inherited from dev.

    Managed Identities for Fabric Items

    Some Fabric items can use managed identities rather than service principals — particularly when connecting to Azure services. A Dataflow Gen2, for example, can use a managed identity to connect to Azure Key Vault for secrets, eliminating hardcoded credentials. The governance implication is that managed identity permissions must be tracked in your Azure RBAC inventory, not just your Fabric permissions inventory.


    Hands-On Exercise

    This exercise walks you through configuring a realistic multi-team permission structure from scratch.

    Setup: You'll need a Fabric workspace with at least one lakehouse containing a few Delta tables. If you've completed the lakehouse fundamentals lesson, use that workspace and lakehouse.

    Step 1: Establish baseline workspace roles

    1. Open your workspace in the Fabric portal. Click "Manage access" (top right of the workspace).
    2. Note the current role assignments. If it's just you as Admin, that's fine.
    3. Create a test scenario: add a test user (or your own secondary account if you have one) as a Viewer.
    4. Confirm the Viewer account can see the workspace and its item list, but cannot open a notebook or query the SQL endpoint directly.

    Step 2: Grant item-level access to the lakehouse

    1. In the workspace, find your lakehouse item. Click "..." → "Manage permissions."
    2. Share the lakehouse with your Viewer test account using ReadData permission only (not ReadAll).
    3. In a new browser session as the Viewer account, navigate to the lakehouse SQL analytics endpoint connection string (found in the lakehouse settings).
    4. Connect with Azure Data Studio or a SQL client. Confirm you can run SELECT * FROM <table_name> LIMIT 10.
    5. Now try to browse to the raw OneLake file path for that table. Confirm it is not accessible — ReadData grants SQL access, not direct file access.

    Step 3: Configure an OneLake data access policy

    1. Navigate to your workspace settings (or the Fabric Admin portal, depending on your tenant configuration) and find "OneLake data access policies" for your lakehouse.
    2. Create a policy granting your Viewer test account Read access to a specific table path: Tables/<your_table_name>.
    3. Explicitly do not create a policy for another table in the same lakehouse.
    4. In a Spark notebook (logged in as yourself, not the Viewer), confirm both tables are readable.
    5. If you have the ability to run a notebook as the Viewer account (this may require workspace access for the Viewer), test that only the explicitly granted table path is readable.

    Step 4: Audit your permissions via the API

    Using the Fabric REST API or PowerShell with the MicrosoftFabric PowerShell module, retrieve the full list of workspace role assignments:

    # Install the module if needed
    Install-Module -Name MicrosoftFabric -Scope CurrentUser
    
    # Connect
    Connect-FabricAccount
    
    # List workspace role assignments
    $workspaceId = "<your-workspace-id>"
    Invoke-FabricRestMethod `
      -Method GET `
      -RelativeUrl "workspaces/$workspaceId/roleAssignments" |
      Select-Object -ExpandProperty value |
      ForEach-Object {
        [PSCustomObject]@{
          Principal = $_.principal.displayName
          Type = $_.principal.type
          Role = $_.role
        }
      } | Format-Table
    

    Compare the output against what you configured. Verify the Viewer is listed correctly and no unexpected principals appear.


    Common Mistakes and Troubleshooting

    Mistake 1: Giving Everyone Contributor "Just in Case"

    This is the most common governance failure. Contributor sounds modest, but it grants read access to all data in the workspace. In a gold workspace with financial or PII data, Contributor effectively means "can read everything." Reserve Contributor for people who are actively building content, and use Viewer plus item-level permissions for data consumers.

    Mistake 2: Conflating Item Sharing with Data Access

    Sharing a lakehouse gives access to the SQL analytics endpoint. It doesn't necessarily grant direct OneLake file access (unless you use ReadAll). Many teams discover this when an analyst tries to load a Delta table into a Spark session from a shared lakehouse and gets a 403. The fix is either ReadAll permission (with appropriate OneLake policies to compensate) or a workspace role that includes OneLake access.

    Mistake 3: Not Accounting for the Default Semantic Model

    Every lakehouse automatically creates a default semantic model. When you share a lakehouse, this model is also implicitly shared. If users should not have access to the semantic model (because it exposes all tables), you need to check the semantic model's permissions separately. The semantic model has its own "Manage permissions" panel.

    Mistake 4: Trusting SQL Security to Protect Notebook Access

    SQL-level grants on the SQL analytics endpoint do nothing for users accessing data via Spark notebooks. If a Contributor runs spark.read.format("delta").load("abfss://...") pointing at a table path directly, SQL-level DENY statements have no effect. Only OneLake data access policies can enforce access control across all access methods.

    Mistake 5: Shortcut Permission Confusion After Workspace Migration

    When you move a shortcut from one workspace to another (via deployment pipelines), the shortcut destination path is preserved but the source-side OneLake policies may not be correctly configured for the new workspace context. After any deployment pipeline promotion, verify that shortcut access is working correctly for end users, and check that the OneLake policies on the source items still cover the identities that need access.

    Note

    Deployment pipelines clone item definitions — including shortcut definitions — but they do not clone permission assignments. After promotion from dev to production, you need a separate step (manual or automated) to apply the correct production permission configuration.

    Troubleshooting: "User can see item but cannot query data"

    This usually means workspace role is set (so item is visible) but item-level or OneLake permissions are missing. Check:

    1. Does the user have item-level sharing with at least ReadData?
    2. If the data is in a specific OneLake path, is there an OneLake policy granting them access to that path?
    3. For warehouses, check SQL object-level permissions with sys.database_permissions.

    Troubleshooting: "Direct Lake model returns errors in production"

    The most common cause is that the semantic model's service principal or managed identity does not have Read access to the OneLake table paths it needs. Check the semantic model's connection settings and verify the identity has an explicit OneLake policy or item-level ReadData permission on the source lakehouse. If the model is falling back to DirectQuery silently, the symptom is much slower query performance than expected.


    Summary and Next Steps

    Fabric's security model is genuinely powerful, but it requires you to think in layers. Workspace roles are the starting point, not the destination. Item permissions let you grant scoped access without exposing an entire workspace. OneLake data access policies are the enforcement layer that applies regardless of access method — and the only reliable way to secure data within a shared lakehouse against direct Spark or API access.

    The key design principles to take away:

    1. Design workspace structure to minimize permission sprawl. Separate platform workspaces from analytics workspaces. Keep raw data away from business users by design.
    2. Never rely on workspace roles alone for data access control. Contributor is "read everything." That's rarely what you want for business users.
    3. Use OneLake policies for any data that can be accessed outside of a semantic model. If users can run notebooks, use SQL clients, or call the OneLake API, SQL-only security is insufficient.
    4. Shortcut security is source-side. The source lakehouse's policies govern access, not the destination workspace's roles.
    5. Automate permission configuration and audit it regularly. Permissions drift. Build a known-good baseline in code and compare against it on a schedule.

    For your next steps, consider how this governance model applies to a complete data architecture. If you're building a medallion architecture in Fabric, the workspace and permission structure you design for bronze/silver/gold layers will directly determine how much of this governance complexity you can manage. And if your platform involves database mirroring from external sources like Azure SQL or Snowflake, the OneLake policies you define on those mirrored tables control who can access them — making the mirroring security story consistent with everything we've covered here.

    Fabric's governance capabilities are still maturing rapidly. OneLake policies, in particular, are receiving significant investment. Build your governance model with the assumption that new capabilities will arrive — design it to be extensible rather than fully relying on workarounds. The teams that get this right early will spend their time building data products, not untangling permission disasters.

    Work With Us

    From insight to implementation

    Reading is the start. When you're ready to build the data, automation, or AI systems behind it, our team turns strategy into shipped results.

    Let's Build

    Microsoft Fabric Fundamentals

    Previous

    Fabric Git Integration and Deployment Pipelines: Version Control and Promotion Across Environments

    Next

    Loading Data into a Fabric Lakehouse with the Pipeline Copy Activity: Connecting to REST APIs, Blob Storage, and SQL Sources

    Related Insights

    Microsoft FabricFoundation

    Calling the Fabric Lakehouse SQL Analytics Endpoint from Power BI Desktop: Connecting, Writing Measures, and Publishing a Report Without Direct Lake

    21 min
    Microsoft FabricFoundation

    Writing Data from a Spark Notebook to a Fabric Lakehouse Delta Table: Append, Overwrite, and Merge Patterns with PySpark

    16 min
    Microsoft FabricExpert

    Implementing Row-Level Security in a Fabric Warehouse and Lakehouse SQL Analytics Endpoint: Dynamic Policies, Workspace Roles, and Testing Access as a Business User

    31 min

    On this page

    • Introduction
    • Prerequisites
    • Understanding the Four Permission Layers
    • Workspace Roles in Depth
    • Admin
    • Member
    • Contributor
    • Viewer
    • The Role You Don't Have: No Workspace Role
    • Item-Level Permissions
    • Sharing Items
    • Lakehouse Item Permissions
    • Warehouse Item Permissions
    • Semantic Model Permissions
    • OneLake Data Access Policies
    • What Problem Do They Solve?
    • How to Configure OneLake Data Access Policies
    • OneLake Policies vs. SQL Object Permissions
    • Designing a Multi-Team Governance Model
    • Workspace Role Assignments
    • OneLake Policies for the Gold Lakehouse
    • Semantic Model RLS for the Risk Dataset
    • Auditing and Monitoring Access
    • The Fabric Activity Log
    • The Fabric Admin APIs
    • Cross-Workspace Data Access and Shortcuts Security
    • Internal Shortcuts
    • External Shortcuts (ADLS Gen2, S3)
    • Service Principals and Managed Identities
    • Registering a Service Principal for Fabric Access
    • Managed Identities for Fabric Items
    • Hands-On Exercise
    • Common Mistakes and Troubleshooting
    • Mistake 1: Giving Everyone Contributor "Just in Case"
    • Mistake 2: Conflating Item Sharing with Data Access
    • Mistake 3: Not Accounting for the Default Semantic Model
    • Mistake 4: Trusting SQL Security to Protect Notebook Access
    • Mistake 5: Shortcut Permission Confusion After Workspace Migration
    • Troubleshooting: "User can see item but cannot query data"
    • Troubleshooting: "Direct Lake model returns errors in production"
    • Summary and Next Steps