Solution Architecture  /  Analytics  /  Powerhouse · EXO

Who is
asking?

One question decides how a governed dashboard is licensed, secured and paid for: when the query reaches Power BI, whose name is on it? Answer "the person" and cost grows with every colleague you add. Answer "the application" and cost stops growing — but you take on a secret, and row-level security stops being automatic.

Staff member Entra ID sign-in EXO · React ECharts dashboards RELAY · BFF picks the identity it presents downstream PATH A · as the person — their licence, their RLS PATH B · as the app — one identity + effective identity POWER BI semantic model · DAX POWER BI via a capacity EVERYTHING UPSTREAM OF THE RELAY IS IDENTICAL · THE DECISION IS ONE LINE

The bug report was the useful kind: "I can log in, but the dashboard is blank." Not an error. Not a permission dialog. Sign-on worked exactly as designed — single sign-on, Entra ID, the person's real identity — and then nothing rendered. Several staff, same story.

The instinct is to go looking for a bug in the app. There wasn't one. The app was doing precisely what we built it to do: take the signed-in person's own token, hand it to Power BI, and ask for data as them. Power BI looked at who was asking, checked whether that person held a Power BI Pro licence and Build permission on the dataset, found they didn't, and returned nothing.


01 · THE SYMPTOMSigning in is not the same as being entitled

That blank dashboard is not a defect. It is the licensing model working, and it exposed a strategic question hiding underneath an architectural one. We had quietly assumed that anyone who could authenticate could see a dashboard — and the two are governed by completely different systems: ours, and Microsoft's. Authenticating proves who you are. Whether you are entitled to the data is a separate question, and Power BI answers it against the real human on the request.

Signing in is not the same as being entitled. The moment we saw that, the real question surfaced: who should be asking Power BI for the data?

02 · PATH AThe person asks

The relay forwards each viewer's own delegated token, verbatim. Power BI sees Alice, applies Alice's licence, Alice's dataset permissions, Alice's row-level security. Nothing is impersonated; the platform is simply looking at the real person.

ALICE'S BROWSER holds Alice's token delegated token RELAY owns NO data secret same token, unchanged POWER BI · checks Alice's licence? Alice's Build permission? Alice's row-level security THE RELAY VERIFIES A SIGNATURE AND PASSES THE MESSAGE ALONG — IT HOLDS NOTHING
Path A · the person asks. The relay's security posture is not "we guarded the secret well" — it is "there is no secret here." Every question of what a person may see is answered by Power BI against the real human, so our rules cannot drift from the platform's: there is only one set.

The virtue is severe and easy to underrate: the relay holds no data credential. Compromise it and you have stolen nothing, because it owns nothing. The price is a slope. Every additional viewer is another Pro licence (~AUD $20/month) and another Build grant. Twenty viewers, ~$400 a month. Two hundred viewers, ~$4,000 a month — and an administrator adding people to security groups forever.

03 · PATH BThe application asks

The relay authenticates as one service principal — a non-human identity for EXO itself — and queries as itself. Viewers need no Power BI licence at all. Where per-person filtering matters, the relay tells Power BI "apply this person's row-level security" by passing their verified identity as an effective identity.

ALICE'S BROWSER no Power BI licence Entra token · proves who she is RELAY holds the SP secret stamps effective identity SP credential + "act for Alice" POWER BI · capacity checks the app's permission applies Alice's RLS — from the stamp, not from her THE PATH NOT TAKEN — FOR NOW · ONE SECRET, AND RLS BECOMES OURS TO ENFORCE
Path B · the application asks. The price is a step, not a slope: one Power BI Embedded (A1) capacity, pausable outside business hours, costing the same whether five people look or five hundred. But the platform now sees only the app — so the effective-identity stamp, and the row-level security that rides on it, become ours to get right.

04 · THE ARGUMENTCost is where this starts — and the least interesting part

The shapes are obvious once drawn. A slope beats a step until it doesn't. Below roughly thirty viewers, Path A is cheaper and simpler. Above it, Path A becomes a tax on curiosity — every colleague who might benefit from looking at the data costs money to let look, which is exactly the wrong incentive for an organisation trying to become data-literate.

 
Path A · per-user Pro
Path B · SP + Embedded
20 viewers
~AUD $400 / mo
capacity only
200 viewers
~AUD $4,000 / mo
the same capacity
Shape
a slope
a step
Break-even
roughly 30–50 viewers

But the cost curve is not the argument. The argument is what you give up. Path A's relay is a remarkable thing: a component that sits in the middle of a data path and owns nothing. Path B ends that. You now hold one credential that can read every dataset the app can reach, and the blast radius of losing it is the whole semantic layer.

The part that gets underestimated

Under Path A, row-level security applies because Power BI is looking at a real person — there is nothing to implement and nothing to get wrong. Under Path B, the platform sees only the application, so we become responsible for telling it whose rows to return. That effective-identity stamp must be derived from the cryptographically verified sign-in token and nothing else. Derive it from a request header, a query parameter, or anything the client can influence, and you have built a system where any authenticated user can read any other user's rows by asking nicely.

That is not a reason to avoid Path B. It is a reason to be honest that Path B moves a security guarantee from Microsoft's side of the line to ours.


05 · TWO LAYERSThe distinction people keep collapsing

Almost every confused conversation about dashboard access comes from conflating two separate questions. Both paths need this distinction, and neither path changes the first layer — only the second.

Which dashboards may I open? OURS

Our decision, always. An AD group maps to an Entra app role, the role appears in the sign-in token, and config/models.json tags each dashboard with the roles that may see it. Add a colleague to the Finance AD group and they see the finance dashboards — no config change, no deploy.

identical under Path A and Path B

Which rows do I see inside one? RLS

The semantic model's business, via row-level security. Automatic under Path A, because Power BI is looking at a real person. Explicit under Path B, because we must stamp the effective identity ourselves.

the only layer the decision actually touches

06 · WHAT DOESN'T CHANGEAlmost none of the system moves either way

"We're changing how Power BI auth works" tends to make people brace for a rebuild. It isn't one. The choice is confined to a single line of code — which token the relay presents — which is exactly why it can be made reversibly. Everything else stands untouched.


07 · THE DECISIONStay on Path A. Move when the number says so.

For an audience in the tens, per-user Pro is cheaper, simpler, and the stronger security posture. The blank-dashboard problem that started all this is not an argument for re-architecting — it is an operational fix: grant the affected staff Pro + Build via a security group, and move the one dataset still sitting in a personal workspace into the shared one. The trigger to revisit is written down, so nobody has to relitigate it from intuition.

Viewers approaching 30–50? OR licensing every person becoming an admin burden? no STAY ON PATH A simplest · cheapest no secret to guard yes BUILD PATH B · BEHIND A FLAG SP + Embedded A1 · paused off-hours RLS modelled explicitly VERIFY · unlicensed test account: right dashboards, right rows CUT OVER · remove Pro · rollback = one flag
The trigger, written down. Build Path B feature-flagged and reversible when the number arrives — not because we expect to roll back, but because a decision you can undo is one you are allowed to make on incomplete information. And the information here is genuinely incomplete.

08 · HONEST UNCERTAINTYThree things to confirm before anyone buys anything

I would not let enthusiasm for the elegant answer paper over these — the indicative pricing above must be confirmed, and Microsoft moves the rules on service-principal executeQueries and on what a capacity is required for.

← All writing rummanahmed.com Share on LinkedIn