Stop copying data between Fabric workspaces. This expert-level lesson shows you how to use OneLake shortcuts to expose lakehouse and warehouse tables to downstream workspaces, covering permissions, performance, warehouse security caveats, and a hands-on multi-workspace exercise. Learn the hub-and-spoke shortcut pattern used by mature Fabric platform teams.

Picture this: your platform engineering team has spent months building a clean, well-governed gold layer in a central Fabric lakehouse. Sales analytics, finance reporting, and customer success all want access to the same fact_sales, dim_customer, and dim_product tables. The old-world answer would be to set up scheduled copy jobs into each team's workspace, maintain data contracts between three different extract jobs, and then spend every other Monday morning debugging why Finance's copy is two hours behind Sales's copy. That's the data mesh nightmare that OneLake shortcuts were built to end.
In this lesson, you'll learn how to expose tables from a source lakehouse or warehouse to one or more downstream workspaces without moving a single byte. Instead of copying data, downstream workspaces create OneLake shortcuts that point directly at the source Delta tables or warehouse data in OneLake's underlying storage. Queries in the downstream workspace read the same physical Parquet files the source workspace reads, governed by the same Delta transaction log, always showing the freshest committed data. This is the architectural pattern that makes Microsoft Fabric genuinely different from "just another cloud data platform."
By the end of this lesson, you will have built a working multi-workspace sharing architecture and understand every nuance that could trip you up in production.
What you'll learn:
You should be comfortable with Fabric workspaces and capacity before starting. If you need a refresher on how workspaces relate to Fabric SKUs and capacity units, review Fabric Capacities and Workspaces: F SKUs, Trials, and Setting Up Your First Workspace. You should also have a working understanding of what OneLake is and why the single-data-lake architecture matters — the article OneLake Explained: One Copy of Data, Delta Tables, and Shortcuts covers that foundation thoroughly. Finally, you'll need at least one lakehouse with Delta tables already created, and optionally a Fabric warehouse. If you haven't built either of those yet, Building Your First Lakehouse in Microsoft Fabric: Files, Tables, and the SQL Analytics Endpoint will get you there.
Minimum access requirements:
Before you create your first shortcut, you need to understand what's actually happening in storage, because that understanding will inform every decision you make about permissions, performance, and governance.
Every Fabric item that stores data — lakehouses, warehouses, KQL databases — has a dedicated folder inside OneLake. OneLake itself is a hierarchical namespace layered over Azure Data Lake Storage Gen2. The path structure looks like this:
onelake://<tenant-name>/
└── <workspace-guid>/
└── <item-name>.<item-type>/
└── Tables/
└── <table-name>/
├── _delta_log/
└── part-00000-xxxx.parquet
For a lakehouse, Delta tables live under Tables/. For a Fabric warehouse, things are slightly more nuanced — warehouse data is also stored in Delta format inside OneLake, but the warehouse's SQL engine manages the transaction log and schema metadata independently of the Delta open standard's transaction log. The files are there, the Delta log is there, but the warehouse engine has its own catalog layer on top.
When you create a cross-workspace shortcut in a downstream lakehouse, you're creating a logical pointer at a specific path in this hierarchy. The shortcut has no data of its own. When a query hits the shortcut, the Fabric compute engine (whether Spark or the SQL Analytics Endpoint) resolves the pointer, goes directly to the source path in OneLake storage, reads the Delta log, and fetches the Parquet files. If a new row was committed to the source table thirty seconds ago, your shortcut query sees it immediately — no refresh cycle, no copy lag.
Key insight
Shortcuts are not snapshots and they are not cached copies. They are live references to a path in OneLake. Every query is fresh. This is fundamentally different from the Import mode datasets many Power BI practitioners are used to, and it changes how you think about data freshness SLAs entirely.
Here's where most teams get confused, and it's worth spending time on this before you touch the UI.
When a user in a downstream workspace queries a shortcut table, two distinct permission checks occur:
Workspace-level check: Does the user have permission to access the downstream workspace item (the lakehouse containing the shortcut)? This is governed by standard Fabric workspace roles.
OneLake data access check: Does the user — or more precisely, does the compute identity used to execute the query — have permission to read from the source path?
For Fabric-to-Fabric shortcuts (i.e., shortcuts from one Fabric workspace to another Fabric workspace, as opposed to shortcuts to external ADLS or S3), the second check works through a mechanism called delegated access. When you create the shortcut, Fabric stores the identity of the user who created it. At query time, the compute engine uses that stored identity to authorize the read from the source path.
This means the shortcut creator needs to have, at minimum, read access to the source lakehouse or warehouse at the time of shortcut creation. Specifically, they need the ReadAll permission on the source item, which is granted through workspace roles (Viewer and above in the source workspace) or through explicit item-level sharing.
Warning
If the user who created the shortcut later loses access to the source workspace, the shortcut can break for all downstream consumers — even users who still have access in the source workspace. This is a critical operational risk to manage. Many teams address this by creating shortcuts using a service principal or a dedicated "platform" service account that retains permanent access.
There's an additional wrinkle specifically for warehouse shortcuts: querying warehouse data through a shortcut from a downstream lakehouse happens at the Parquet file level, bypassing the warehouse's SQL-layer row-level security policies and object-level permissions. Column masking rules defined in the warehouse don't apply when the data is read through a Delta shortcut. If your warehouse has RLS or column masking configured for compliance reasons, you cannot rely on those controls to protect data accessed via an OneLake shortcut. You'll need to apply equivalent controls at the OneLake level or restrict shortcut creation entirely for those tables. The article on Securing and Governing Microsoft Fabric: Workspace Roles, Item Permissions, and OneLake Data Access goes deep on this.
Let's work through a realistic scenario. We'll call our architecture a hub-and-spoke model:
fabric-platform-prod — owned by the platform team, contains the gold-layer lakehouse called gold_lakehouse with curated tables: fact_sales, dim_customer, dim_product, dim_date.sales-analytics — owned by the Sales BI team.finance-reporting — owned by the Finance team.Both spoke workspaces will create shortcuts into gold_lakehouse tables. Neither spoke workspace copies any data. Both read directly from the hub.
Log in to the Fabric portal at app.powerbi.com and navigate to fabric-platform-prod. Open gold_lakehouse. In the Lakehouse Explorer on the left, expand the Tables section. You should see your Delta tables listed there. If you've been following the Implementing the Medallion Architecture in Microsoft Fabric: Bronze, Silver, and Gold Layers pattern, these gold tables are the output of your silver-to-gold transformations.
Click on fact_sales. Fabric shows you a preview of the table's data and its schema. Make a note of the table names — you'll need them when configuring shortcuts.
Navigate to workspace settings for fabric-platform-prod. Go to the Members/Access section. You have two choices for giving spoke workspace teams access to source tables:
Option 1: Add teams as Viewer in the source workspace. This grants read access to all items in the workspace. It's simple but coarse-grained — the Finance team can see everything, including development lakehouses and staging items you might not want exposed.
Option 2: Share the specific lakehouse item with item-level permissions. From the gold_lakehouse item in the workspace view, click the three-dot menu and select Share. You can share the lakehouse with specific people or groups and grant them ReadAll access without giving them any workspace-level visibility.
For production architectures with strict governance requirements, Option 2 is almost always the right choice. You share only the item(s) you intend to expose, to the specific groups or service principals that need access.
Tip
If you're managing many spoke workspaces, use Azure AD security groups rather than individual user assignments. Create a group like fabric-gold-lakehouse-readers and add it to the item sharing. When a new team onboards, add them to the group — no changes to Fabric permissions needed.
Now navigate to sales-analytics workspace. If there's no lakehouse here yet, create one — call it sales_analytics_lakehouse. This will be the container for your shortcuts.
Open sales_analytics_lakehouse. In the Lakehouse Explorer on the left side, right-click on the Tables folder (not the Files folder). You'll see an option called New shortcut. Click it.
A dialog opens with three source type options:
Select Microsoft OneLake. This is the option for Fabric-to-Fabric shortcuts across workspaces.
The next screen shows a picker for OneLake items. You'll see a hierarchy: your tenant name at the top, then workspaces below it. Expand fabric-platform-prod. You'll see gold_lakehouse (type: Lakehouse) listed there. Expand it. You'll see two subfolders: Tables and Files.
Expand Tables. You can now see every Delta table inside the source lakehouse. Select fact_sales. The path shown at the bottom of the dialog will look something like:
onelake://fabric-platform-prod.dfs.fabric.microsoft.com/<workspace-guid>/gold_lakehouse.Lakehouse/Tables/fact_sales
Note
You're creating a shortcut at the table level, not the entire Tables folder. You should do this deliberately — if you shortcutted the entire Tables folder, every new table added to the source lakehouse would automatically appear in the downstream workspace, which can be a security and governance problem. Table-level shortcuts give you explicit control over what's exposed.
Click Next. On the following screen, Fabric asks you to name the shortcut. By default it uses the source table name (fact_sales). Keep it the same name unless you have a specific reason to rename it — consistency between source and consumer makes lineage easier to track.
Click Create. After a few seconds, fact_sales appears under the Tables section in sales_analytics_lakehouse, but with a small arrow icon overlaid on it — that's the visual indicator that this is a shortcut, not a locally materialized table.
Repeat this process for dim_customer, dim_product, and dim_date.
Click on fact_sales in the lakehouse explorer. A preview pane loads the first rows of the table. If you see data, your shortcut is working and your permissions are correctly configured. If you see an error like "Access denied" or "Failed to resolve shortcut," jump to the troubleshooting section at the end of this article.
Now switch to the SQL Analytics Endpoint view (the dropdown at the top right of the lakehouse view switches between "Lakehouse" and "SQL Analytics Endpoint"). In the SQL query editor, run:
SELECT
fs.order_date,
SUM(fs.sale_amount) AS total_sales,
COUNT(DISTINCT fs.customer_id) AS unique_customers
FROM fact_sales fs
WHERE fs.order_date >= '2024-01-01'
GROUP BY fs.order_date
ORDER BY fs.order_date DESC;
This query runs through the SQL Analytics Endpoint against the shortcut. The endpoint translates your T-SQL into a Parquet read against the source path in fabric-platform-prod's OneLake storage. The Finance and Sales teams write their T-SQL exactly as they would against a locally materialized table — they don't need to know (or care) that the data lives in another workspace.
The warehouse case has important nuances. The Fabric warehouse engine stores data as Delta Parquet files in OneLake, but unlike a lakehouse where each Delta table is a simple folder you can target directly, the warehouse organizes its tables under a schema structure and manages metadata through its own catalog.
When you navigate to fabric-platform-prod in the OneLake shortcut picker and expand a warehouse item, you'll see the internal folder structure. Warehouse tables appear under Tables/<schema-name>/<table-name>/. So a dbo.fact_revenue table would be at:
onelake://<workspace-guid>/platform_warehouse.Warehouse/Tables/dbo/fact_revenue
Select the specific table path and create the shortcut as you did for lakehouse tables. The shortcut appears in your downstream lakehouse's Tables folder.
Warning
Querying warehouse tables through a shortcut from a downstream lakehouse bypasses the warehouse's SQL-layer security entirely. If dbo.fact_revenue has row-level security defined in the warehouse that restricts certain users to their own region's data, those restrictions do NOT apply when the table is read through an OneLake shortcut. You are reading the raw Parquet files. Design your security model accordingly — either apply OneLake data access control policies at the file level, or don't expose sensitive warehouse tables through shortcuts at all.
One important constraint: shortcuts to warehouse tables are read-only from the downstream side, which is expected behavior, but also note that the warehouse's transactional guarantees don't carry through to the shortcut. If a multi-statement warehouse transaction is mid-commit when your shortcut query starts reading, you may read a partially committed state. For most analytical workloads this is not a practical problem, but it's worth knowing.
If your downstream consumers are other Fabric warehouses (not lakehouses), you should know that Fabric warehouses support cross-database T-SQL queries natively using three-part naming syntax (workspace.database.schema.table). For warehouse-to-warehouse sharing, cross-database queries are often simpler to set up than shortcuts because they stay entirely within the SQL layer and inherit SQL security models.
Shortcuts are the better pattern when the consumer is a lakehouse (or a Spark notebook) because Spark can read shortcut tables as Delta tables natively. If your downstream team does PySpark transformations on top of the data, shortcuts are the natural integration point.
Your Spark users in the downstream workspace can read shortcut tables exactly like any other Delta table in the attached lakehouse. No special configuration needed.
Open a Spark notebook in sales-analytics. Attach it to sales_analytics_lakehouse. Run:
# Read the shortcutted fact_sales table
df_sales = spark.read.format("delta").load("Tables/fact_sales")
# Or use the lakehouse table API directly
df_sales = spark.table("fact_sales")
# Check the record count and schema
print(f"Row count: {df_sales.count():,}")
df_sales.printSchema()
The spark.table("fact_sales") call resolves through the attached lakehouse's table catalog, which sees the shortcut as a registered table. Under the hood, Spark reads from the same OneLake path. You can run complex transformations on this DataFrame, join it with locally materialized tables, write output back to the lakehouse's own Delta tables — all without touching the source workspace.
from pyspark.sql import functions as F
# Join shortcutted tables to build a sales summary
df_customers = spark.table("dim_customer")
df_products = spark.table("dim_product")
df_enriched = (
df_sales
.join(df_customers, on="customer_id", how="left")
.join(df_products, on="product_id", how="left")
.select(
"order_date",
"region",
"product_category",
F.col("sale_amount"),
F.col("customer_segment")
)
.filter(F.col("order_date") >= "2024-01-01")
)
# Write the enriched result to a LOCAL table in the downstream lakehouse
# (This creates a real Delta table, not another shortcut)
(
df_enriched
.write
.format("delta")
.mode("overwrite")
.option("overwriteSchema", "true")
.saveAsTable("sales_enriched_2024")
)
Notice that the write target (sales_enriched_2024) is a local table in sales_analytics_lakehouse. You're reading from shared shortcut tables and materializing an aggregated or enriched derivative locally. This is a very common and appropriate pattern: share raw or lightly curated data via shortcuts, let downstream teams build their domain-specific aggregations locally.
Tip
When reading multiple shortcut tables in the same Spark job, Spark can push predicate filters down to the Parquet reader and exploit Delta file statistics just like it does for local tables. Add explicit filter conditions early in your query to limit the number of Parquet files read from the source. If your source Delta table has Z-Order on order_date, a filter on order_date will benefit from data skipping automatically — even across the workspace boundary.
One of the most powerful use cases for cross-workspace shortcuts is building a Direct Lake semantic model in a downstream workspace that reads from source tables in a platform workspace. This lets Power BI reports query source data at near-native speed without any import cycle.
From sales-analytics workspace, create a new semantic model. Add sales_analytics_lakehouse as the data source. When you select tables to include, the shortcut tables (fact_sales, dim_customer, etc.) appear alongside any locally materialized tables. Add them to the model.
Fabric creates a Direct Lake semantic model. When a Power BI report queries this model, the engine performs a "framing" step — reading the current Delta transaction log to identify the set of Parquet files that represent the committed state of the table — and then reads those files directly from OneLake. For shortcut tables, framing reads the Delta log from the source path in fabric-platform-prod. The query latency for this cross-workspace framing is minimal in practice (typically tens of milliseconds) because it's just a metadata read.
Key insight
A Direct Lake model built on shortcut tables in a downstream workspace always shows the current committed state of the source tables. If the platform team runs a nightly Spark transformation that overwrites fact_sales at 2:00 AM, the Power BI model in sales-analytics automatically reflects those changes at query time — no model refresh required, no dataset scheduled refresh window to configure. This is the zero-copy freshness guarantee that makes the pattern compelling. For more on how Direct Lake works mechanically, see Direct Lake Mode in Power BI: How It Works and When to Use It over Import and DirectQuery.
When a Direct Lake query runs against shortcut tables, the Fabric capacity being charged for the compute is the capacity of the workspace containing the semantic model (i.e., the downstream workspace capacity), not the source workspace capacity. The storage I/O reads happen against the source workspace's OneLake storage, but the compute cost for DAX evaluation, column dictionary loading, and aggregation runs on the downstream capacity.
This has planning implications: if your Sales BI workspace is on an F8 and they're running heavy Direct Lake queries against a very large fact_sales table, they're consuming F8 CU/s for those queries. The platform team's workspace capacity is not burdened by downstream query load. This is usually the intended behavior — each team is responsible for their own compute consumption.
Now that you understand the mechanics, let's talk about what a well-designed hub-and-spoke shortcut architecture actually looks like at scale, because there are several pitfalls that bite teams who don't think this through in advance.
Treat your hub workspace's gold lakehouse as a published API. Just like an API contract, you need to be explicit about:
pub_ prefix for published tables.fact_sales, every downstream shortcut immediately reflects that change — and every downstream query that referenced that column breaks instantly. You need a schema evolution policy. Adding columns is safe (Delta's schema evolution handles it). Dropping or renaming columns is breaking. If you're running the medallion architecture and need to read more about managing schema changes safely, the article on Handling Schema Evolution in Fabric Lakehouse Delta Tables covers this in depth.When you have 15 spoke workspaces each creating shortcuts into the platform lakehouse, the platform team needs a way to track who is consuming what. Fabric doesn't yet provide a native "show me all workspaces that have shortcuts pointing at my lakehouse" view (as of mid-2025). The practical approach is to require spoke teams to register their shortcut usage in a governance catalog — Microsoft Purview can discover and track OneLake shortcuts automatically if your organization has Purview scanning configured.
At minimum, document shortcut usage in a shared wiki or data catalog entry. When you need to change the schema of a shared table, you know who to notify.
Earlier I mentioned the risk of user-created shortcuts breaking when that user loses access. In production, here's how to handle this properly:
Create a service principal in Azure Entra ID — something like svc-fabric-platform-reader. Grant this service principal item-level ReadAll access to gold_lakehouse in fabric-platform-prod. When you need to create shortcuts in downstream workspaces, do so through the Fabric REST API authenticated as this service principal, or have a workspace admin who delegates through this principal.
The Fabric REST API shortcut creation endpoint looks like this:
POST https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}/items/{itemId}/shortcuts
With a request body like:
{
"path": "Tables",
"name": "fact_sales",
"target": {
"oneLake": {
"workspaceId": "<source-workspace-guid>",
"itemId": "<gold-lakehouse-item-guid>",
"path": "Tables/fact_sales"
}
}
}
This API call creates the shortcut programmatically. If you're managing many spoke workspaces, you can script the entire shortcut provisioning process — add a new workspace, run the script, all required shortcuts are created immediately. This approach also makes shortcut management part of your infrastructure-as-code workflow.
Tip
Pair the REST API shortcut provisioning with Fabric Git integration and deployment pipelines if you're managing workspace configurations as code. The Fabric Git Integration and Deployment Pipelines article explains how workspace state — including shortcut definitions — can be version-controlled and promoted across environments.
Shortcuts are not always the right answer. Here's an honest assessment of when they work well and when you should consider materializing data into the downstream workspace instead.
fact_sales has 5 billion rows but your downstream query reads only 60 days of data using a WHERE order_date >= ... filter, data skipping means you might only read 2% of the files. The cross-workspace hop adds negligible overhead compared to the file I/O savings.Note
There is currently no built-in row count or file-level caching for shortcut tables in the downstream workspace. Every query resolves the shortcut and reads from the source storage. If you have extremely latency-sensitive queries (sub-100ms response requirement), and your source table isn't small, consider whether a materialized copy with optimized V-Order might serve your SLA better. V-Order optimization at the source benefits shortcut readers too — it's applied at the file level, and downstream readers benefit automatically.
This exercise builds a working two-workspace shortcut architecture. Allow 45–60 minutes.
platform-hub and analytics-spoke. Both must be on Fabric capacity.platform-hub, create a lakehouse called gold_lh.platform-hub and run the following to create sample gold tables:from pyspark.sql import SparkSession
from pyspark.sql import functions as F
import random
from datetime import datetime, timedelta
spark = SparkSession.builder.getOrCreate()
# Generate dim_customer
customers = [(i, f"Customer_{i}", random.choice(["Enterprise", "SMB", "Consumer"]),
random.choice(["North", "South", "East", "West"]))
for i in range(1, 1001)]
df_customers = spark.createDataFrame(customers, ["customer_id", "customer_name", "segment", "region"])
df_customers.write.format("delta").mode("overwrite").saveAsTable("dim_customer")
# Generate dim_product
products = [(i, f"Product_{i}", random.choice(["Hardware", "Software", "Services"]),
round(random.uniform(10, 5000), 2))
for i in range(1, 201)]
df_products = spark.createDataFrame(products, ["product_id", "product_name", "category", "list_price"])
df_products.write.format("delta").mode("overwrite").saveAsTable("dim_product")
# Generate fact_sales
import random
from datetime import date
base_date = date(2024, 1, 1)
sales = []
for i in range(1, 100001):
order_date = base_date + timedelta(days=random.randint(0, 364))
sales.append((
i,
random.randint(1, 1000),
random.randint(1, 200),
str(order_date),
round(random.uniform(50, 10000), 2),
random.randint(1, 10)
))
df_sales = spark.createDataFrame(sales,
["order_id", "customer_id", "product_id", "order_date", "sale_amount", "quantity"])
df_sales.write.format("delta").mode("overwrite") \
.partitionBy("order_date") \
.saveAsTable("fact_sales")
print("Gold tables created successfully.")
gold_lh.In platform-hub workspace settings, navigate to Manage access. Add the user account you'll be using in analytics-spoke as a Viewer, or alternatively share gold_lh directly with them granting ReadAll permission.
Switch to analytics-spoke. Create a lakehouse called spoke_lh. Open it, right-click Tables, and select New shortcut. Choose Microsoft OneLake as the source. Navigate to platform-hub > gold_lh > Tables. Select fact_sales. Name the shortcut fact_sales. Repeat for dim_customer and dim_product.
Switch to the SQL Analytics Endpoint view of spoke_lh. Run the following query:
SELECT
dp.category,
dc.region,
COUNT(DISTINCT fs.order_id) AS order_count,
SUM(fs.sale_amount) AS total_revenue,
AVG(fs.sale_amount) AS avg_order_value
FROM fact_sales fs
INNER JOIN dim_customer dc ON fs.customer_id = dc.customer_id
INNER JOIN dim_product dp ON fs.product_id = dp.product_id
WHERE fs.order_date BETWEEN '2024-06-01' AND '2024-09-30'
GROUP BY dp.category, dc.region
ORDER BY total_revenue DESC;
You should get revenue by product category and region for Q3 2024, read entirely from platform-hub's storage, executed in analytics-spoke.
Open a Spark notebook in analytics-spoke attached to spoke_lh. Run:
from pyspark.sql import functions as F
df_sales = spark.table("fact_sales")
df_customers = spark.table("dim_customer")
df_products = spark.table("dim_product")
# Build quarterly summary — this will be a LOCAL table in spoke_lh
df_quarterly = (
df_sales
.join(df_customers, "customer_id")
.join(df_products, "product_id")
.withColumn("quarter", F.quarter(F.to_date("order_date")))
.withColumn("year", F.year(F.to_date("order_date")))
.groupBy("year", "quarter", "category", "segment", "region")
.agg(
F.count("order_id").alias("order_count"),
F.sum("sale_amount").alias("total_revenue"),
F.countDistinct("customer_id").alias("unique_customers")
)
)
df_quarterly.write.format("delta").mode("overwrite").saveAsTable("quarterly_revenue_summary")
print(f"Materialized {df_quarterly.count()} rows into quarterly_revenue_summary")
Check the lakehouse explorer — you should see quarterly_revenue_summary as a standard (non-shortcut) Delta table alongside your three shortcut tables.
Go back to platform-hub. Open a notebook and append new rows to fact_sales:
from datetime import date
from pyspark.sql import Row
new_rows = [
Row(order_id=100001, customer_id=5, product_id=12, order_date="2024-12-15",
sale_amount=9999.99, quantity=1),
Row(order_id=100002, customer_id=7, product_id=45, order_date="2024-12-16",
sale_amount=1234.56, quantity=3),
]
df_new = spark.createDataFrame(new_rows)
df_new.write.format("delta").mode("append").partitionBy("order_date").saveAsTable("fact_sales")
print("New rows committed to source fact_sales.")
Now switch back to analytics-spoke and re-run the SQL query filtering for December 2024:
SELECT order_id, sale_amount, order_date
FROM fact_sales
WHERE order_date >= '2024-12-01'
ORDER BY order_id;
The two new rows appear immediately. No shortcut refresh was triggered. No copy job ran. The shortcut resolved the updated Delta transaction log and read the new partition files directly.
Symptom: When you navigate to the source workspace in the shortcut picker, the lakehouse item appears grayed out or unavailable. Cause: The current user doesn't have at least Viewer-level access to the source workspace, or doesn't have ReadAll on the specific lakehouse item. Fix: In the source workspace, share the specific lakehouse with the user's account or group. Ensure the share includes the ReadAll permission (not just "Allow recipients to share this item").
Symptom: You created shortcuts and can see them in the Lakehouse Explorer under Tables, but when you switch to the SQL Analytics Endpoint view, the tables aren't listed in the schema browser.
Cause: The SQL Analytics Endpoint's metadata sync can lag a few minutes behind the lakehouse. Also, shortcuts must point to valid Delta table paths — if you accidentally pointed at the Files section instead of Tables, the endpoint won't recognize it as a Delta table.
Fix: Wait 2–5 minutes and refresh. If tables still don't appear, verify the shortcut target path ends in a folder that contains a _delta_log directory.
Symptom: spark.table("fact_sales") works fine, but a Direct Lake semantic model built on the same table fails to frame or returns a "Transient error" during query.
Cause: Most commonly, this is a permission issue with the identity used by the Power BI service to access OneLake. The semantic model's refresh identity needs ReadAll on the source lakehouse, separate from the notebook user's permissions.
Fix: In the source workspace, ensure that either the semantic model's owner's identity or the workspace's service principal has ReadAll on gold_lh. If using a semantic model with scheduled refresh or direct lake mode, the model's data source credentials configuration may need to be updated.
Symptom: Downstream SQL queries suddenly start failing with "column not found" or "type mismatch" errors after a platform team deployment. Cause: A column was dropped, renamed, or its data type changed in the source table. Fix: This is a process failure, not a technical one. Establish a schema compatibility policy in your hub workspace. Use Delta's schema evolution features for additive changes only, and treat destructive changes as breaking API changes that require downstream team notification and migration windows.
Symptom: Queries against a shortcut that itself points to a shortcutted table (chain of shortcuts) are slower than expected. Cause: Each shortcut resolution hop adds a metadata lookup cost. With two or three hops in a chain, latency accumulates. Fix: Flatten the chain where possible. If Workspace C needs data from Workspace A and Workspace B has a shortcut, have Workspace C create a direct shortcut to Workspace A rather than chaining through B.
Symptom: A shortcut that previously worked now returns "Path not found" or "Table does not exist." Cause: The source Delta table was deleted or moved in the hub workspace. Fix: Delete the dangling shortcut in the downstream workspace. If the table needs to be recreated, re-create the shortcut after the source is restored. Implement a monitoring check (a simple pipeline activity that tests shortcut tables) to proactively detect dangling shortcuts before users do.
You've built a working cross-workspace data sharing architecture using OneLake shortcuts. Let's recap what you've learned and why each piece matters.
The core pattern is a hub-and-spoke model where a central platform workspace owns and governs curated gold-layer tables, and downstream consumer workspaces access those tables through live shortcuts. No data is copied. No refresh cycle introduces staleness. Compute in downstream workspaces reads directly from the hub's OneLake storage paths.
The permission model has two distinct layers: workspace-level access in the downstream workspace (for item access) and ReadAll permission on the source item (for OneLake storage access). The identity used to create the shortcut needs ReadAll at creation time, and that identity's access must be maintained for the shortcut to continue working. Use service principals for production shortcut creation to avoid user-lifecycle dependency.
Warehouse shortcuts bypass SQL-layer security. If you expose warehouse tables through shortcuts, row-level security and column masking defined in the warehouse SQL layer don't apply. Design your security model to account for this, either by applying OneLake-level access controls or by not exposing sensitive warehouse tables through shortcuts.
Know when to materialize. Shortcuts are the right tool for high-freshness reads with selective queries. For full-table aggregation pipelines or for teams that need to maintain their own derived data, local materialized tables are appropriate — often sourced by reading shortcut tables and writing derivatives locally.
From here, consider these next directions depending on your goals:
Cross-workspace shortcuts are one of the highest-leverage patterns in Fabric. Once you've set up the hub correctly and established access conventions, adding a new consumer workspace is a five-minute task. That's the kind of infrastructure that pays dividends every time a new team wants to get their hands on good data.