When building Power Platform solutions, there are times when a flow, integration, pipeline, script, or external service needs to connect to Dataverse without relying on a named user account. That is where service principals come in. A service principal gives an application or automation its own identity. Instead of tying access to a person, you create an identity for the workload itself, then grant that identity only the Dataverse permissions it needs.
Why Use a Service Principal?
A common mistake in Power Platform projects is using a regular user account for automation or integrations. That may work at first, but it creates long-term problems.
User-based accounts can break when:
- The user leaves the organization
- The password changes
- MFA requirements change
- Licensing changes
- Ownership of flows or apps becomes unclear
- Admins need to audit who or what is accessing Dataverse
A service principal gives you a cleaner model. Microsoft describes a service principal as a non-human security identity that can own and manage resources across Azure and Power Platform. In Power Platform, that service principal is represented in the environment as an application user.
The Big Picture
At a high level, the setup looks like this:
- Create an app registration in Microsoft Entra ID.
- Create a client secret or certificate for that app.
- Add the app as an application user in the Dataverse environment.
- Assign the application user the correct security role.
- Use the client ID, tenant ID, and secret/certificate in your automation or integration.
The important part is that creating the app registration alone does not give it Dataverse access. You still need to add it to the specific Dataverse environment as an application user and assign security roles. Microsoft’s Dataverse OAuth guidance calls out that after creating the application user, you associate it with the custom security role you created.
Service Principal vs Application User
This is one of the areas that can confuse people.
The service principal lives in Microsoft Entra ID. It represents the application identity.
The application user lives in Dataverse. It represents that same application inside a specific Dataverse environment.
Think of it this way:
| Concept | Where It Lives | Purpose |
|---|---|---|
| App registration | Microsoft Entra ID | Defines the application |
| Service principal | Microsoft Entra ID | Represents the app identity in the tenant |
| Application user | Dataverse environment | Allows the app identity to access Dataverse |
| Security role | Dataverse environment | Controls what the app can do |
Step 1: Create the App Registration
Start in Microsoft Entra ID and create a new app registration.

Suggested name:
spn-dv-[environment]-[purpose]

Capture the following values when creating the SPN:
Application client ID:
Directory tenant ID:
Microsoft’s Dataverse developer documentation still points to registering an application in Microsoft Entra ID before it can authenticate with Dataverse web services.
I like naming service principals based on the environment and purpose because six months later “PowerAppTest123” tells nobody what it does.
Step 2: Create a Client Secret
- Select Certificates & Secrets
- Select New Client Secret
- Give the secret a Description
- Set the expire for the secret

Capture the client secret now, as it will not be able to be captured after this window is closed
Do not store the client secret in plain text inside documentation, source control, or unmanaged environment variables. Use Key Vault, secure pipeline variables, or another approved secret store.
Step 3: Add API Permission
- Select API permissions
- Select Add a permission
- Select Dynamics CRM (yes this is the right one)
- In the new window select user_impersonation, then select add permissions
- Select Grant admin consent
If you do not have the role to grant admin consent work with your admin team to grant it, it is a scary sounding term, but it simply allows the app to run. It doesn't actually do anything at this point



For GCC and GCCH
The setup is the same for GCC/GCCH users except for one part the Dynamics 365 API is not listed on the API list; to get it you have to select API my organization uses and search for Dataverse

Step 4: Add the Application User in Power Platform Admin Center
Navigate to the Power Platform Admin Center and follow the tree
Power Platform Admin Center
→ Environments
→ Select environment
→ Settings
→ Users + permissions
→ Application users
→ New app user
From there:
- Select the Microsoft Entra app.
- Select the business unit.
- Assign one or more security roles.
- Save.
Step 5: Assign the Right Security Role
This is where you should slow down.
Do not automatically assign System Administrator unless you are testing or have a specific administrative reason. Instead, create a role that gives the service principal only what it needs.For example:
| Scenario | Suggested Role Approach |
|---|---|
| Deployment automation | Role with solution import/customization rights |
| Data integration | Table-specific read/write privileges |
| Reporting extract | Read-only role for required tables |
| Admin automation | Elevated role, but documented and approved |
Security roles control access to Dataverse data through privileges and access levels, and users can have multiple roles with cumulative privileges.
This is where a lot of teams get lazy. Giving every service principal System Administrator works, but it also destroys the security model. If the workload only needs to read three tables, give it read access to those three tables.
Step 6: Create the Connection
Once the application user is created and assigned a role, create a connection to be used
- In the environment that the SPN was added into create a new connection using a SPN and fill in the Client ID, Client Secret and tenant accordingly.

Common Mistakes
Mistake 1: Creating the App Registration but Not the Application User
The app registration only creates the identity. It does not automatically grant Dataverse access. You still need to add that identity as an application user in the target environment.
Mistake 2: Assigning Too Much Access
System Administrator is easy, but it is usually not the right answer. Start with the minimum required permissions and expand only when needed.
Mistake 3: Using One Service Principal for Everything
One service principal for all environments and all purposes becomes hard to audit. A cleaner pattern is:
spn-dv-dev-deployment
spn-dv-test-deployment
spn-dv-prod-deployment
spn-dv-prod-integration-name
This makes ownership, access reviews, and troubleshooting much easier.
Mistake 4: Forgetting Secret Expiration
Client secrets expire.
If no one tracks the expiration date, your automation will eventually fail. Add the expiration date to your operational documentation, backlog, or monitoring process.