December 7, 2020
Table of Contents #
- Application Models
- Service Principal in Azure
- Service Principal in PowerBI Service
- Application Authorization
- RLS Folding
- Setup an Azure Application and a “Service Principal” mapping for it
- Assign and configure that service principal for PowerBI Service
- Authenticate against that Application and proxy the Service Principal access from said application.
Application Models #
So you’re trying to embed PowerBI as a report into your customer facing application?
Great! You have to make some decisions first:
- Pick an Application Access model
- Master Service User (Application maps to specific user and inherits that user’s accesses or restrictions)
- Service Principal (Application maps to a security group and inherits that group’s accesses or restrictions)
- Pick an Application Data Model
- User owns Data (effectively “Active Directory User to Data”)
- App owns Data (usually non-AD model such as a database with a multi-tenant DB where you have your own user hierarchy established)
When we set out to build this application, we unknowingly fell into some tradeoffs that were not very apparent in the Microsoft Documentation.
|Model||Feature 1||Feature 2|
|Master Service User||Authenticate as licensed AD User (must be setup with O365, PowerBI Pro, etc.)||Inherits mapping to that User’s security rules and policies (MFA, Password Rotations, etc.)|
|Service Principal||Authenticates as Azure App Registration mapped to Security Group in Azure||Inherits mapping of that Group’s security rules and policies|
|User owns Data||Designed for AD Authentication (Ex. SQL Server with AD auth model) where every user must be in AD (Can be guest to domain, not licensed etc.)||RLS support for PowerBI “Apps” and “Dashboards” (the ones created in PowerBI.com with pinned visuals etc.) and full page “Reports”|
|App owns Data||Designed for custom hierarchy or user model||RLS support for full page “Report” Objects only|
That said - let’s convert our embedded Report object to the combination of Service Principal with App owns Data so that we can stop performing password rotations every 90 days! It’s an application for goodness sake! Certificate, Client Id, and Client Secret should be enough!
Let’s get started.
Service Principal in Azure #
First steps - you need an App Registration in Azure.
PowerBI App registration tool here if you are creating a new one (does not edit existing): https://app.powerbi.com/embedsetup
Basically, these are just paths to create a record like here in your Azure Portal: https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade
Where the post important things are:
- Under “Authentication”, setup a “Platform”, Web Method with self provided redirect uris.
- Under “Certificates & Secrets”, create a new secret key for the application.
- Under “API Permissions”, enable any and all relevant scopes which will be needed by this application.
In our case, because we are scoping building this application to interact with PowerBI related APIs and Services, nearly all enabled scopes will related to that except for a few which will connect Graph API.
Now all this so far is the application itself - next is the security group and the assignment of that security group as the service principal for this application.
Service Principal in PowerBI Service #
Application Authorization #
Next, when having a front-end application connect to the PowerBI Service APIs to retrieve reports such as for embedding - you have to make a decision about how to handle “authentication” via Oauth2. Now, while that is well documented here ( https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow) the implications that this will have on your ability to retrieve data from PowerBI is not well communicated.
I’m just going to shortcut straight to the point- for now, I think that the
client_credential method is the best supported authentication type for Embedding PowerBI Reports.
Why? It allows you to assume the Service Principal for the application without an additional step of the User Oauth flow.
Is there some security implications to this? Yes, but you should probably being using Conditional Access (Location / IP whitelisting) and a VPN to reduce your app’s total surface area anyway.