Setting up Entra ID
Entra ID does two separate jobs for ReportMesh, and they are two separate registrations in the Entra admin centre:
| Registration | Job |
|---|---|
| Sign in | Signs internal staff in, and syncs people from your directory into the portal |
| Content | Reads Power BI reports and SharePoint workbooks, with no user involved |
Who this is for: Whoever is standing the portal up. Several steps grant admin consent, so you need Application Administrator or Global Administrator.
Everything here happens at entra.microsoft.com, under Identity → Applications → App registrations.
The sign-in registration
Create it
- New registration.
- Name it
ReportMesh, adding an environment suffix if you keep environments separate. - Supported account types: Accounts in this organisational directory only (single tenant). ReportMesh checks the tenant on every token and rejects multi-tenant ones, so this is required rather than a preference.
- Leave the redirect URI blank for now, and Register.
From the Overview page, record the Application (client) ID and the Directory (tenant) ID. You need both when configuring the application.
Add the redirect URI
-
Authentication → Add a platform → Web.
Web, not SPA. ReportMesh completes sign in from the backend using a client secret. A SPA registration forces a different flow and the exchange fails.
-
Add
https://<your-portal-hostname>/entra-callback— the portal's hostname, because that is where the browser lands. -
Under Implicit grant and hybrid flows, leave ID tokens and Access tokens unticked.
-
Save.
This has to match the application's configured redirect URI exactly: scheme, host, port, and the
absence of a trailing slash. A mismatch shows at sign in as AADSTS50011.
Create a client secret
- Certificates & secrets → Client secrets → New client secret.
- Describe it, choose an expiry in line with your rotation policy, and Add.
- Copy the Value immediately, not the Secret ID. It is shown once.
When this secret expires, both sign in and directory sync stop. Put the date in a calendar.
Grant permissions
Delegated permissions, for sign in — API permissions → Add a permission → Microsoft Graph →
Delegated permissions → add openid, profile and email.
Application permissions, for the directory sync — add User.Read.All.
Then select Grant admin consent and confirm. Application permissions do nothing until the Status column shows a green tick. A directory sync that returns a permissions error nearly always means this was skipped.
User.Read.All is sufficient. The sync reads names, addresses and account status, and never
writes to your directory, so do not grant write permissions.
Add the token claims
Token configuration → Add optional claim → ID → tick email and upn → Add.
Accept the prompt about the profile permission if it appears. ReportMesh reads both when
identifying who has signed in.
Decide the first administrator
There is no built-in administrator account, and the first person to sign in is not promoted automatically. One named email address is configured as the bootstrap administrator, and that person becomes an administrator on first sign in, but only while the portal has no administrator yet.
Decide that address now. Left unset, nobody is promoted, the first person to sign in arrives as an ordinary user, and there is no way for them to grant themselves anything.
First-one-in-wins is an escalation path. Where external sign in is enabled, a stranger who signed themselves up into a portal with no administrator would become its administrator. Naming the address closes that off. External guests are never promoted by anything, whatever the configuration says.
The content registration
A second registration, with no user attached, that reads report and workbook content.
- New registration, named
reportmesh-service-principal, single tenant, redirect URI left blank. It never receives a browser redirect. - Record its Application (client) ID and Directory (tenant) ID.
- Certificates & secrets → New client secret, and record the Value immediately.
When this secret expires, every embedded report stops rendering at once.
Power BI: add no Power BI permissions
Counter-intuitively, this registration needs no Power BI API permissions at all. Power BI grants access through workspace membership and tenant settings, not through consented API permissions.
-
Create an Entra security group, for example
ReportMesh-ServicePrincipals, and add the content registration to it. This lets your Fabric administrator scope the next settings to the group rather than the whole organisation. -
In the Fabric admin portal → Tenant settings → Developer settings, enable "Service principals can call Fabric public APIs" and confirm "Embed content in apps" is enabled, both scoped to that group.
-
Add the group as a Member of every Power BI workspace whose reports will be registered.
Member, not Viewer. Viewer is not enough to embed a report.
Tenant setting changes can take up to 15 minutes to apply. If a test fails immediately after a change, wait before investigating further.
Granting Power BI workspace access covers all three in full, with the verification calls that prove each one took. Hand it to your Fabric administrator.
It can read every report and workbook in scope, and it does so with no user attached. Which reports a given person sees is decided by ReportMesh, not by Power BI. Treat its secret accordingly.
SharePoint: Sites.Selected
For Excel workbooks, add the Sites.Selected Microsoft Graph application permission and
grant admin consent. If the consent button is greyed out, you need a higher directory role.
Sites.Selected grants access to nothingIt only makes the identity eligible to be granted individual sites. Each site is then granted separately, against that one site, by a SharePoint or Global administrator. Until that happens, ReportMesh cannot read anything in that site and Excel reports cannot be registered from it.
ReportMesh cannot perform the grant itself, and there is no consent prompt that shortcuts it. Microsoft requires a signed-in administrator holding full control of the site.
Granting SharePoint site access has the commands and who runs them. Hand it to your SharePoint administrator.
Checklist
- The sign-in registration is single tenant.
- Its platform is Web, not SPA.
- Its redirect URI is exactly
https://<your-portal-hostname>/entra-callback. -
openid,profileandemailare present as delegated permissions. -
User.Read.Allis present as an application permission and shows Granted. -
emailandupnappear under Token configuration. - The bootstrap administrator address is decided.
- The content registration exists, with a secret and no Power BI API permissions.
- The security group exists, contains the content registration, and both Fabric developer settings are scoped to it.
- The content registration is a Member of each Power BI workspace.
-
Sites.Selectedshows Granted, if Excel workbooks are in scope. - Both client secrets are in a password manager, with their expiry dates in a calendar.
Common problems
| What you see | What it usually means |
|---|---|
AADSTS50011, redirect URI mismatch | The registered URI and the configured one differ. They must match byte for byte, trailing slash included. |
AADSTS9002326, cross-origin token redemption | The registration was created as a SPA. Delete that platform and add a Web one. |
| Directory sync returns a permissions error | Admin consent for User.Read.All was not granted. |
| Sign in works, but nobody can administer anything | The bootstrap administrator address is unset, or does not match the address on the token. |
| "Entra ID is not configured" at sign in | One of the four Entra values is missing. The application starts without them and fails at sign in by design. |
| Reports do not render, immediately after a tenant setting change | Fabric tenant settings take up to 15 minutes. Wait, then retry. |
Next
Setting up Duo, for the second factor on internal sign in.
For the content identity, Granting Power BI workspace access and Granting SharePoint site access are what actually give it reach over your content. Neither can be done from Entra, and both need someone other than the Entra administrator.