Luise Freese

Why your Power Platform service principal doesn't need a Dynamics user_impersonation scope

Auth is hard, for most developers. This is also true when building Power Platform solutions. As I see some blog posts explaining how to use a service principal in Power Platform that contain some inaccuracies/wrong information, I’d like to clarify some auth myths :-)

Usually, Power Automate flows run in the context of a signed-in user. If we for example want to create a row in Dataverse table with a Power Automate flow, we would use the connection of this signed-in user, which can potentially lead to lots of issues. To tackle this, we can create a service principal that will connect our flow action with Dataverse. To do so, we will

  • Register an application in Azure Active Directory
  • Create an application user in the Power Platform Admin Center and assign a security role to it
  • Create a new connection in our flow

Let’s first tackle some auth basics

We need both the App registration and the security role as we need to cover

Authentication

Authentication refers to the identity of a user or an app, it’s the answer to the question Who is this?. You can think of it like your identity card or passport.

Authorization

Authorization refers to privileges of a user or an app, it’s answer to the question What are they allowed to do? You can think of it like a boarding pass for a flight.

In the end, you will need both documents to board/fly, as you will first need to prove your identity with your ID card/passport and then show your permissions to board a certain flight with your boarding pass (that also has your name/identity on it).

Register an application in Azure Active Directory

To handle authentication of our service principal, we need to register an application in Azure Active Directory. We will give this application a name and let Azure AD generate a username (App/Client Id) and password (Client secret) for it. If later a user or an application tries to log in, AAD will lookup Client Id and Client Secret and validate the identity. You can think of it like showing your passport with your picture to prove your identity.

To register an application in Active Directory, follow these steps:

  • Open portal.azure.com
  • Select Azure Active Directory
  • Select Add, then App registration
  • Enter a name for your app
  • Select Accounts in this organizational directory only
  • Select Register
  • Select Overview and copy Directory (tenant) ID and Application (client) ID - we will need these later
  • Select Certificates & secrets
  • Select New client secret
  • Select Add
  • Save the value of this secret somewhere - we will need this later
  • NO (and I repeat: NO API PERMISSIONS)

(Let’s revisit my last point a little bit later)

Create an application user in the Power Platform Admin Center and assign a security role to it

Now that we created our passport, we need to tell Dataverse about this app and relate this to a security role that will ultimately grant the connection access to the tables we want it to have access.

  • Head over to aka.ms/ppac to access the Power Platform Admin center
  • Select an environment of your choice
  • Select Settings
  • Select Users + permissions
  • Select Application users
  • Select New app user
  • Select Add an app
  • Select the app that you registered in the step before
  • Select Add
  • Select the appropriate Business unit
  • Select the pen icon next to Security roles
  • Add a security role, for example System Administrator (God mode)
  • Select Save
  • Select Create

What we now did is, we print our boarding pass with name and flight number on it. The System Administrator role may access every table and we assigned this role to an app that we registered in Active Directory.

Create a new connection in our flow

Now let’s create a flow and test this in action:

  • Open flow.microsoft.com
  • Make sure that you are in the same environment as your created your application user in
  • Create a new flow, it can be as simple as

flow showing a manual trigger with a textinput, and an add a row in Dataverse action mapping the textinput to a Name colummn

  • On the ellipsis menue ... of the Dataverse action, select Add new connection
  • Select Connect with service principal
  • Give the connection a name
  • Fill in Tenant Id, Client Id, and Client secret
  • Select Create
  • Save your flow

By this we created a new connection that uses the Dataverse application user, to which we assigned the security role System Administrator.

Little discussion of API permissions

Next up: Run your flow - you will see, that it runs without any error - especially without any 403 error, which would mean Forbidden/missing privileges.

I saw in some blog posts (and I stumbled over that myself as well 🙄), that authors instruct to assign API permissions to the app registration, specifically Dynamics CRM –> user_impersonation.

This is relatable, if you do not realize, that security roles are the only way to control access (permissions) in Dataverse. Especially if you are familiar with app registrations that will enable apps to call Microsoft Graph API for example, you know the concept of an app registration with then one or multiple permissions that need to be assigned to it in order to make things work. It is therefore easy to fall into this trap when its about Dataverse/Dynamics CRM. But, unlike in Microsoft 365, we have security roles in Dataverse, which means that we do not need to take care of authorization (boarding pass) in the app registration but can use pre-defined or custom-tailored roles to give privileges.

The only permission scope for Dynamics CRM that we can find in the App registration is user_impersonation (Delegated), and it doesn’t make sense to select this, as our service principal in fact does application-only auth. Still I have been guilty of doing the same thing, as I was not really aware of this and didn’t fully understand security roles.

Feedback and what’s next?

Let me know, were you aware of how security roles of an application user and a service principal connection in a Power Automate flow interact with each other? Or did you also use user_impersonation scope? Let’s talk on twitter :-) If you found this blog post useful, please also subscribe to my newsletter - news coming about every 2 months, I promise to not spam you!

You May Also Like

How to build a Power Apps Likert component

tl;dr Power Apps components allow makers to reuse fragments and patterns of their work to ensure design consistency and developer productivity. This Likert component showcases also custom properties …

Want to work with me?