Learn how to configure Power BI External Data Sharing to give external partners governed, live access to your semantic models — without exporting data, managing guest identities, or losing control of your security model. This deep-dive covers architecture, RLS design for cross-tenant identity, capacity planning, and the full operational lifecycle.

Your largest retail partner needs access to their sell-through data. Your logistics provider needs visibility into shipment performance metrics. Your joint-venture partner needs consolidated financial reporting. In each of these scenarios, someone outside your Azure Active Directory tenant needs access to live, governed data — and your first instinct might be to export a spreadsheet, schedule an email, or set up a separate reporting environment.
All of those instincts are wrong, at least from a governance and security standpoint. Every export is a snapshot that goes stale, a file that escapes your control, and a compliance risk waiting to materialize. The better solution is Power BI External Data Sharing — Microsoft's mechanism for distributing live, governed semantic models to external consumers without ever moving a byte of data outside your tenant. External partners connect to your model, query your data, and see results governed by your security rules, all through their own Power BI identity.
By the end of this lesson, you'll understand the full architecture of External Data Sharing, know how to configure it end-to-end in both the Power BI Service and Azure AD, design a security model that protects sensitive dimensions while exposing the right data to the right partners, and handle the operational edge cases that trip up even experienced Power BI administrators.
What you'll learn:
Before working through this lesson, you should have:
Before you configure anything, you need to understand what's happening under the hood. The distinction between different external access patterns in Power BI is genuinely confusing because Microsoft has layered multiple mechanisms on top of each other over several product generations.
Azure AD B2B Guest Access is the oldest pattern. You invite an external user into your Azure AD tenant as a guest. They get a guest account in your directory, subject to your conditional access policies, and they can be added to workspaces and given report access like any internal user. The friction here is organizational: your IT team has to manage guest identities, your Azure AD admin has to approve invitations, and the external partner's Power BI experience is awkward because they're effectively operating as a pseudo-employee of your organization.
Report Sharing via Public Links or Email is the simplest pattern but the least governed. You share a report link; anyone with the link can view it. You lose identity-based access control entirely. This is appropriate for genuinely public data; it's completely inappropriate for partner data.
External Data Sharing is the newest pattern and the subject of this lesson. Rather than adding a guest to your tenant, you share a semantic model with an external Power BI user in their own tenant. They connect to your model from their own workspace using their own identity. No guest accounts. No cross-tenant identity management. The external user accesses the model through a live connection, meaning all queries execute against your model on your capacity. Data never leaves your tenant. The external user can build their own reports in their own workspace, but the underlying data engine is yours.
Key insight: The "no data export" guarantee in External Data Sharing is structural, not policy-based. Because the external consumer connects via a live semantic model connection rather than copying data, the actual model data never transfers to their tenant. Their queries execute in your capacity and return results — just like an internal user's queries would. This is fundamentally different from telling someone "please don't copy the data."
When you share a semantic model externally, the recipient gets:
The recipient does not get:
This asymmetry is exactly what makes External Data Sharing appropriate for B2B scenarios: you maintain complete control over the data layer while giving partners genuine, governed self-service capability.
This is where many implementations stall, so let's be completely clear about the requirements.
The workspace containing the shared semantic model must reside on a Premium Per Capacity, Premium Per User, or Microsoft Fabric capacity. External Data Sharing does not work on shared capacity (Pro workspaces). The model owner or workspace admin must have a Power BI Pro or Premium Per User license to manage sharing.
This is the part that surprises most people: the external consumer does not need Premium capacity in their own tenant. They need a Power BI Pro license or Premium Per User license to connect to your shared model and build reports. Their workspace can be a standard Pro workspace.
However, there's an important nuance: all query processing happens on your capacity. If you share a large model with 50 external users who run complex queries, that load lands on your Premium capacity. You need to plan capacity accordingly, and we'll cover this in detail in the performance section.
Warning: If you're using Premium Per User (PPU) on the provider side, external consumers must also have PPU licenses. PPU-licensed semantic models can only be accessed by PPU-licensed users. This is a significant constraint for external sharing scenarios — your partner organization would need to purchase PPU licenses just to consume your model. For most B2B scenarios, a P1 or F64 capacity is more practical for the provider because it removes the PPU requirement from the consumer side.
External Data Sharing must be enabled at the tenant level before any sharing can occur. This is a deliberate governance checkpoint — Microsoft doesn't want this feature accidentally enabled in organizations that aren't ready for it.
Navigate to the Power BI Admin Portal (app.powerbi.com, then the gear icon, then Admin portal). Under Tenant settings, find the "External data sharing" section. You'll see a setting titled "Allow specific users to turn on external data sharing."
This setting has three configuration modes:
Disabled for the entire organization: No one can share models externally. This is the default for most tenants.
Enabled for the entire organization: Any user with the right workspace role can share models externally. This is appropriate only for organizations with strong workspace governance already in place.
Enabled for specific security groups: The recommended configuration for most enterprises. You define which Power BI users are permitted to share externally. Typically this is a group like "Power BI External Sharing Approved Publishers" containing your certified dataset owners and workspace administrators.
Tip: Even when the tenant setting is enabled, sharing can only be done by users with at least Admin, Member, or Contributor role in the workspace. Viewer-role users cannot share models externally regardless of the tenant setting. This two-layer control (tenant policy + workspace role) gives you defense in depth.
After enabling the tenant setting, navigate to the specific workspace containing your model. In workspace settings, under the "Advanced" tab, you'll find an "External sharing" toggle. This must be enabled at the workspace level in addition to the tenant setting. This workspace-level control means you can enable the feature tenant-wide but still have it disabled for specific workspaces that contain particularly sensitive models.
Let's walk through a realistic scenario. Contoso Manufacturing wants to share their Supply Chain Performance model with their logistics partner, FastFreight Logistics. The model lives in the "Supply Chain Operations" workspace on Contoso's Premium P2 capacity.
Before sharing, ensure your model is production-ready. This means:
In the Power BI Service, navigate to your workspace. Find the semantic model (formerly called "dataset") in the workspace content list. Click the ellipsis menu next to the model name and select "Manage permissions."
In the permissions panel, you'll see a tab or button for "External sharing." Click it. You'll see a field to enter an email address. This must be the email address of a user who:
Enter the FastFreight contact's email address (for example, analytics@fastfreight.com) and click Share.
When you click Share, several things happen simultaneously:
Power BI generates a unique external sharing invitation token tied to the specific model and the specific recipient email. This token is not reusable by other email addresses.
An email is sent to the recipient containing a link to accept the share. The link includes the token and directs them to a Power BI consent flow.
An audit log entry is written to your tenant's activity log recording: who shared the model, which model was shared, with which external email, and the timestamp.
The share appears in your model's "Manage permissions" panel under External sharing with a status of "Pending" until the recipient accepts.
Note: The external sharing invitation expires after a configurable period (typically 90 days by default). If the recipient doesn't accept before expiration, you'll need to re-share. Monitor pending shares regularly as part of your governance process.
When the FastFreight analyst receives the invitation email, they click the link and are redirected to Power BI. If they're not signed in, they authenticate with their own organizational credentials (their FastFreight identity, not a Contoso identity).
Once authenticated, they see a consent screen explaining that they're connecting to an external model from Contoso's tenant. They must explicitly consent to this connection. This consent is recorded in the audit log of both tenants.
After accepting, the model appears in their Power BI workspace list under a special "External data" category or they can find it in "Get data" when building a new report. The model shows as a live connection source from Contoso's tenant.
In their workspace, they can now create reports, dashboards, and even Power BI Apps using this model as the data source. All of this is contained within their tenant. Contoso's workspace, other models, and reports are never visible to them.
Sharing a semantic model externally without RLS means every external user sees all data in the model. In most B2B scenarios, this is completely unacceptable — FastFreight should only see shipment data for their routes, not for Contoso's relationship with competing carrier AceLogistics.
Here's where external sharing gets nuanced in a way that trips up most experienced Power BI developers.
In a normal internal RLS setup, you'd write a filter like:
[UserEmail] = USERNAME()
The USERNAME() function returns the identity of the currently authenticated user. For internal users on a capacity-backed workspace, this is their Azure AD UPN (e.g., jsmith@contoso.com).
For external users connected via External Data Sharing, USERNAME() returns their external identity in a cross-tenant format. Microsoft formats this as the user's actual email address from their home tenant. So for the FastFreight analyst analytics@fastfreight.com, USERNAME() would return analytics@fastfreight.com.
This is actually helpful — it means you can use email-based RLS directly against a user mapping table. But you need to design your RLS filter to handle both internal and external users cleanly.
Let's build a complete RLS solution for the FastFreight scenario. The Supply Chain Performance model has a Shipments fact table with a CarrierID column. We need FastFreight users to only see their own carrier's shipments.
Step 1: Create a User-to-Partner mapping table
In your model (or upstream in a dataflow), create a table that maps user email addresses to partner/carrier identifiers:
PartnerUserMapping
------------------
UserEmail | PartnerCode | AccessLevel
analytics@fastfreight.com | FSTFRT | Standard
director@fastfreight.com | FSTFRT | Premium
reporting@acelogistics.com | ACELG | Standard
Step 2: Define RLS roles
Create an RLS role called ExternalPartner with the following DAX filter on the Shipments table:
[CarrierID] IN
SELECTCOLUMNS(
FILTER(
PartnerUserMapping,
PartnerUserMapping[UserEmail] = USERNAME()
),
"PartnerCode", PartnerUserMapping[PartnerCode]
)
This filter says: "Show only shipment rows where the CarrierID appears in the PartnerCodes that are mapped to the currently authenticated user." If a user isn't in the mapping table at all, they get an empty result set — a safe default.
Step 3: Handle internal users gracefully
Your internal Contoso analysts also need to use this model, and they should see all data. Create a separate InternalAnalyst role with no filter (or a filter that always evaluates to TRUE()), and assign internal users to that role.
Alternatively, use a single role with a more sophisticated filter:
// Shipments table RLS filter
VAR CurrentUser = USERNAME()
VAR IsInternalUser =
CONTAINS(
InternalUsers, -- a separate table listing all Contoso email domains
InternalUsers[EmailDomain],
RIGHT(CurrentUser, LEN(CurrentUser) - FIND("@", CurrentUser))
)
RETURN
IF(
IsInternalUser,
TRUE(),
[CarrierID] IN
SELECTCOLUMNS(
FILTER(PartnerUserMapping, PartnerUserMapping[UserEmail] = CurrentUser),
"PartnerCode", PartnerUserMapping[PartnerCode]
)
)
Warning: Be very careful with the domain-based internal user check. If your partner happens to use a similar email domain, or if your organization acquires another company, this logic can fail in unexpected ways. For high-security scenarios, prefer an explicit allowlist of internal user email addresses or security group membership rather than a domain pattern match.
Step 4: Assign external users to the role
In the Manage Permissions panel for the semantic model, find the external users you've shared with and assign them to the ExternalPartner role. You cannot add external users to RLS roles through the workspace roles UI — you must use the semantic model's own permission management.
This is a critical operational step that's easy to miss. The share invitation and the RLS role assignment are separate actions. A user who has accepted the external share but hasn't been assigned to an RLS role will either see all data (if no RLS is defined) or get an error (if RLS is defined but they're not in any role).
Beyond row-level filtering, you can use Object-Level Security (OLS) to hide entire tables or columns from external users. If your Supply Chain model contains a ContractMargin column that shows Contoso's profitability per carrier — information you absolutely cannot expose to FastFreight — you can restrict column visibility entirely.
Configure OLS through the XMLA endpoint using Tabular Model Scripting Language (TMSL) or Tabular Editor. The following TMSL script applies OLS to the ContractMargin column for the ExternalPartner role:
{
"createOrReplace": {
"object": {
"database": "Supply Chain Performance",
"role": "ExternalPartner"
},
"role": {
"name": "ExternalPartner",
"modelPermission": "read",
"tablePermissions": [
{
"name": "Shipments",
"columnPermissions": [
{
"name": "ContractMargin",
"metadataPermission": "none"
}
]
}
]
}
}
}
With this configuration, the ContractMargin column doesn't appear in the field list when an ExternalPartner user builds a report. It's not filtered to empty — it simply doesn't exist from their perspective. Implementing Power BI XMLA Endpoint for Advanced Dataset Management and Third-Party Tool Integration covers the XMLA workflow in detail if you need to get comfortable with that interface.
Design your roles so that it's structurally impossible for a user to be in both an internal and external role simultaneously. Use Azure AD security groups for internal role assignments and manual individual assignments for external roles. This creates a natural audit trail: internal role members are managed by your IAM process; external role members are managed explicitly by the model owner.
External sharing relationships must be tracked as part of your data governance program. Use the Power BI Activity Log to query sharing events. Here's a REST API call to retrieve external sharing activities:
GET https://api.powerbi.com/v1.0/myorg/admin/activityevents
?startDateTime='2024-01-01T00:00:00'
&endDateTime='2024-01-31T23:59:59'
&$filter=Activity eq 'ExternalDataShareEnabled'
The relevant activity event types for external sharing are:
| Activity Event | Meaning |
|---|---|
ExternalDataShareEnabled |
A model was shared externally |
ExternalDataShareDisabled |
A share was revoked |
ExternalDataShareAccepted |
The recipient accepted the invitation |
ExternalDataShareDeclined |
The recipient declined |
ExternalDataShareExpired |
The invitation expired before acceptance |
For ongoing monitoring, build a Power BI report on top of your Activity Log data to show: currently active external shares, pending invitations, last query activity per external user, and shares that haven't been used in 90+ days (candidates for revocation). The Power BI REST API: Automate Administration and Deployments article covers how to pull activity log data programmatically.
Revoking external data sharing access is immediate and structural. When you revoke access in the Power BI Service:
To revoke: navigate to the model's Manage Permissions panel, find the External Sharing section, locate the user, and click Remove. You can also do this programmatically via the Power BI REST API, which is useful for bulk revocations when a business relationship ends.
Tip: Build revocation into your offboarding process for business partnerships. When a contract ends, there should be a checklist item to audit and revoke Power BI external shares. This is analogous to revoking VPN access when an employee leaves — it's just as important and just as often forgotten.
When you update your semantic model — adding new measures, renaming tables, changing RLS logic — the changes propagate to all external consumers automatically. This is one of the major advantages of live connection sharing over data exports.
However, schema-breaking changes require care. If an external user has built a report with a measure called Total Shipment Weight and you rename it to Gross Shipment Weight, their report will break. Unlike internal users who might email you directly, external users may not have a natural escalation path.
Establish a versioning communication protocol with external partners before making breaking changes. Consider using Power BI Deployment Pipelines to maintain a stable production model that external users connect to while you iterate in development and test stages.
Because all external queries execute against your capacity, external sharing is not free from an infrastructure perspective. Here's how to think about the capacity impact.
For each external organization you share with, estimate:
A reasonable planning assumption for a lightly used B2B share is 0.25 to 0.5 CU (capacity units) per active external user per hour. A heavily used analytical sharing relationship with complex queries can hit 2-4 CU per active user. Monitor this using the Power BI Premium Metrics app and adjust capacity sizing accordingly.
External queries compete with internal queries for the same capacity resources. If you share a large model with a partner organization and they schedule automated report exports during business hours, your internal users may see query slowdowns.
Mitigate this with Power BI's query timeout settings and by educating external partners about appropriate usage patterns. For high-volume external sharing at scale, consider Query Scale-Out with read-only replicas, which allows you to route external user queries to replica nodes while keeping primary processing for internal refresh and high-priority queries.
External Data Sharing works with both Import mode and DirectQuery models, but the performance implications differ significantly.
Import mode models compress data into the in-memory engine. External queries benefit from this compression and caching. Query performance is generally excellent, but the model must be refreshed to reflect new data.
DirectQuery and Composite models push queries through to the source system. External users' queries trigger real-time source queries, which adds latency and can strain your source systems if external usage is heavy. If you're sharing a composite model with DirectQuery partitions, be especially attentive to query folding efficiency and source system capacity.
Key insight: For models that external users will query heavily, Import mode is generally preferable because it insulates your source systems from external query load. Use incremental refresh to keep large Import models fresh without full reloads. DirectQuery shared externally is appropriate for scenarios where data currency is critical and source system load is manageable.
This is the core use case — the external partner gets the model and builds their own reports. They're Power BI users. This works cleanly with External Data Sharing as described.
For this pattern, provide your external partners with:
If your external partner has a custom web application and wants to embed Power BI reports using your data, this requires a combination of External Data Sharing and Power BI Embedded. The partner would use their own Power BI Embedded capacity with a service principal that has been granted external share access to your model.
This is an advanced scenario. The service principal in the partner's tenant must be explicitly granted access to the external share — you'd add the service principal's email identifier to the external sharing permissions on your model. The partner then generates embed tokens from their own capacity against your model. Power BI Embedded: Integrate Reports into Custom Applications covers the embedding architecture if this is your scenario.
If your partner doesn't need self-service — they just need a weekly scorecard — you can use report subscriptions rather than full External Data Sharing. However, subscriptions export snapshots. If true live access and self-service are requirements, External Data Sharing is the right pattern and subscriptions are just a complementary mechanism on top.
When you have a dozen logistics partners who all need similar views of carrier performance, manage this with a single model and partner-specific RLS rather than a separate model per partner. A single ExternalPartner RLS role with the user-mapping table approach described earlier scales cleanly to dozens of partners.
You manage new partner access through:
PartnerUserMapping table (requires a model refresh)ExternalPartner roleThis is operationally manageable and keeps your Premium capacity usage predictable — one model with N external users rather than N models each with their own overhead.
Note: If different partners need access to structurally different subsets of the model (not just different rows, but different measures or tables), consider whether Object-Level Security can handle the variation within a single model, or whether separate certified models are warranted. The Dataset Certification and Endorsement workflow becomes important here to track which models are cleared for external sharing.
Let's implement a complete External Data Sharing scenario from scratch. You'll need a Power BI Premium workspace and access to a second Power BI account in a different tenant (a personal Microsoft account with a PPU trial works for testing).
Scenario: You work for Northwind Foods. You want to share a Supplier Performance semantic model with your key supplier, Alpine Provisions. Alpine's analytics contact has a Power BI Pro license at analyst@alpineprovisions.com.
Step 1: Build a simple model
In Power BI Desktop, create a simple model with two tables:
A Suppliers table:
SupplierID | SupplierName | Region
S001 | Alpine Provisions | Northwest
S002 | Valley Fresh | Central
S003 | Coast Organics | Pacific
A DeliveryPerformance table:
DeliveryID | SupplierID | OnTimeFlag | DeliveryDate | OrderValue
D001 | S001 | 1 | 2024-01-15 | 4200
D002 | S001 | 1 | 2024-01-22 | 3800
D003 | S002 | 0 | 2024-01-18 | 6100
D004 | S003 | 1 | 2024-01-20 | 2900
A SupplierUserMapping table:
UserEmail | SupplierID
analyst@alpineprovisions.com | S001
Create a relationship between Suppliers[SupplierID] and DeliveryPerformance[SupplierID].
Create a measure: On-Time Delivery Rate = DIVIDE(COUNTROWS(FILTER(DeliveryPerformance, DeliveryPerformance[OnTimeFlag] = 1)), COUNTROWS(DeliveryPerformance))
Step 2: Configure RLS
In Power BI Desktop, go to Modeling > Manage roles. Create a role called SupplierPartner.
Add this filter expression to the Suppliers table:
[SupplierID] IN
SELECTCOLUMNS(
FILTER(
SupplierUserMapping,
SupplierUserMapping[UserEmail] = USERNAME()
),
"SupplierID", SupplierUserMapping[SupplierID]
)
Test the role using "View as" and entering analyst@alpineprovisions.com as the username. Verify you only see Alpine Provisions data.
Step 3: Publish and configure
Publish to your Premium workspace. In the Power BI Service:
Step 4: Share the model
Navigate to the model's Manage Permissions. Under External Sharing, enter analyst@alpineprovisions.com and click Share. Note the confirmation email text that gets sent.
In the Manage Permissions panel, assign analyst@alpineprovisions.com to the SupplierPartner RLS role.
Step 5: Accept and verify (from the partner side)
Log in as analyst@alpineprovisions.com in a private browser window. Accept the invitation. Create a new report using the external model as a data source. Verify that the report only shows Alpine Provisions data.
Step 6: Audit the activity
Return to your provider tenant. Use the Power BI Admin Portal's Activity Log or the REST API to verify the sharing and acceptance events were recorded. Review what information is captured.
Bonus: Test revocation
Revoke the share from the Manage Permissions panel. Return to the external account and attempt to query the model. Observe the error behavior.
Cause: The workspace is on shared (Pro) capacity, not Premium or Fabric capacity. Fix: Move the model to a Premium-backed workspace. There's no workaround — this is an architectural requirement.
Cause 1: The recipient's email domain has strict spam filtering that's blocking the Microsoft invitation email.
Fix: Have the recipient whitelist the sender domain @powerbi.com or check their spam folder. You can also manually send them the acceptance link, which you can copy from the Manage Permissions panel.
Cause 2: The email address is already a guest in your Azure AD tenant. Fix: Remove the guest account from your Azure AD, or use the B2B guest access pattern instead. External Data Sharing does not work with existing guest accounts.
Cause: The tenant setting is enabled, but external sharing is disabled at the workspace level. Fix: Go to workspace Settings > Advanced and toggle on external sharing.
Cause 2: The external user's tenant has disabled users from accepting external shares. Some organizations configure their Power BI tenant settings to block external sharing acceptance. Fix: The external partner's Power BI admin needs to enable "Allow users to accept external data shares" in their own tenant settings.
Cause: The user is correctly connected but isn't assigned to any RLS role, and you have RLS defined. Since they don't match any role, Power BI applies the implicit "deny all" behavior for unassigned users. Fix: Assign the external user to the appropriate RLS role in the model's Manage Permissions panel.
Cause: You've created RLS roles but haven't assigned the external user to any role. RLS only applies to users who are in a role. Users not in any role see all data if they have read permissions at the model level. Fix: Always assign external users to an RLS role explicitly. Never rely on "they'll be added later" — make role assignment part of the sharing checklist.
Cause: External user queries are consuming capacity that internal users depend on. Diagnosis: Open the Premium Metrics app and review capacity utilization over time, segmenting by report ID or workspace. Identify when external user patterns correlate with internal user slowdowns. Fix: Consider Query Scale-Out to route external queries to replicas, implement query timeout limits for external users, or increase capacity size.
Cause: A measure, column, or table was renamed or removed in the provider's model. Fix: Communicate schema changes in advance to external partners. Use model versioning via deployment pipelines to maintain a stable production model while iterating in development.
Warning: Deleting a semantic model that has active external shares does not automatically notify external users. Their reports will simply fail to load with a generic data source error. Before decommissioning any externally shared model, audit active external shares using the Manage Permissions panel and notify all affected external users with at least 30 days' notice. This is an operational hygiene requirement, not an automated safeguard.
External Data Sharing represents a genuine architectural advance in how Power BI handles B2B data distribution. By connecting external partners directly to live governed semantic models — rather than pushing exports, building shadow systems, or managing guest identities — you get the best of all worlds: partners have real-time, self-service access; you maintain complete control over the data layer, refresh schedule, and security model; and your compliance team has an audit trail of every share, acceptance, and query session.
The key principles to carry forward:
Security is layered, not singular. The External Data Sharing tenant setting, workspace-level enable, RLS role assignment, and OLS column restrictions each address a different threat vector. All layers should be configured together.
RLS design for external sharing requires intentional handling of USERNAME(). Test your RLS expressions explicitly with external user identities, not just internal ones.
Capacity planning must account for external query load. External users query your capacity. Size it accordingly and monitor it actively.
The sharing lifecycle requires governance. Shares must be audited, unused shares should be revoked, and there must be a process for revoking shares when business relationships end.
From here, explore these related capabilities:
If you're building toward a full enterprise semantic layer strategy where external sharing is just one distribution channel, Implementing Power BI Dataset Sharing and Cross-Workspace Live Connections to Build a Reusable Enterprise Semantic Layer provides the foundational architecture.
For models that need to scale to high concurrent external user loads, Implementing Power BI Query Scale-Out with Read-Only Replicas is your next stop.
If your external sharing scenario involves regulatory requirements around where data keys are stored, Implementing Power BI Bring Your Own Key (BYOK) Encryption adds the encryption sovereignty layer on top of your sharing architecture.
External Data Sharing is how enterprise Power BI should do B2B analytics. Get it right once and you'll never send a spreadsheet to a partner again.