Semantic Model & Power BI Reports¶
This folder contains the Direct Lake semantic model TMDL and the configuration plan for the three Power BI reports that demonstrate progressively stricter security on the same model.
Files¶
| File | Purpose |
|---|---|
model.tmdl | Full semantic model: 6 tables, relationships, measures, 3 RLS roles. Direct Lake on lh_btfabric_gold. |
The three reports (build by hand in Power BI Desktop)¶
All three reports point at the same semantic model and use the same measures (Revenue, Gross Profit, Net Revenue, AOV, etc.). The difference is which role users land in via app audience assignment.
| Report | Audience | Role | What they see |
|---|---|---|---|
| 01 — Regional Sales | grp-sales-mgr-* | RegionalManager | Only their region's customers / orders / returns. Customer table is visible (they own those relationships). |
| 02 — Finance Performance | grp-finance | FinanceAnalyst | All regions, but the customer_id column is hidden by OLS. Reports use the Customers measure (distinct count) — no row-level PII. |
| 03 — Executive Scorecard | grp-exec | Executive | All regions, all columns, all measures. |
Best practice: separate refresh identity¶
Direct Lake on a lakehouse refreshes on-demand at query time, but the companion Direct Lake on SQL model (if you build one) does need a scheduled refresh credential. Do not use a personal account for this — and note: service principals cannot be RLS/OLS members (service-premium-service-principal).
✅ Canonical 2026 pattern: configure a Fixed Identity on the semantic model and grant only that identity Read on the lakehouse.
flowchart LR
SP["SPN<br/>sp-better-together-refresh"] -->|Scheduled refresh| SM[Semantic Model]
FX["Fixed Identity<br/>(model property)"] -->|Reads| LH[(Lakehouse lh_btfabric_gold)]
SM -->|Uses| FX
classDef good fill:#1B5E20,stroke:#fff,color:#fff
class SP,FX,SM,LH good How to publish¶
- In Power BI Desktop (March 2026+), open this folder via "Open report" → browse to a
.pbipproject. Save the project; it will create thedefinition/folder that pairs with the TMDL. - Publish to your
Better Togetherworkspace. - In the workspace, set the fixed identity on the semantic model to the SPN
sp-better-together-refresh(the security automation notebook creates this principal). - Configure 3 app audiences matching the table above, and assign the Entra security groups created by the persona generator.
Why dynamic RLS over static roles?¶
We use one RegionalManager role + a _RLS Mapping Delta table joined on USERPRINCIPALNAME(), rather than 4 separate RegionalManagerEMEA, RegionalManagerUSEast etc. roles. Why:
- The mapping is data, not metadata — it lives in the lakehouse and is curated by the security automation notebook. No model redeploy needed when org changes hit.
- One role to test, one role to audit.
- Survives a Fabric workspace clone — TMDL doesn't reference Entra group object IDs, so the model is portable.