Connecting Dynamics 365
Connecting Dynamics 365 takes four values you copy out of Azure and two things you set up inside Dynamics itself. The values are the easy half. The part that trips almost everyone is that pasting correct credentials is not enough — until an Application User exists in your Dynamics environment for that same app, and that user has a security role, Dynamics will refuse a sign-in that Azure happily approved.
Work through the steps in order. Each one produces something the next one needs.
Before you start: who has to be involved
This is the single most common reason a connection takes days rather than twenty minutes — the two halves usually belong to two different people.
| Step | Where | Permission needed |
|---|---|---|
| 1–2: app registration and secret | Azure portal (Microsoft Entra ID) | Rights to create app registrations — Application Developer or Cloud Application Administrator |
| 3–4: Application User and security role | Power Platform admin center | System Administrator on the target environment |
| 5: connect | This app | Workspace admin |
If you only administer one side, get the other person lined up before you start. Steps 3 and 4 cannot be done from Azure, and the Application User in step 3 needs the Client ID that step 1 produces.
The app registration and the Dynamics environment must live in the same Microsoft tenant. An app registered in one directory cannot be given an Application User in an environment owned by another.
The four values you will paste
Keep a scratch file open and collect these as you go.
| Field in the Connect dialog | Where it comes from | The usual mistake |
|---|---|---|
| Organization URL | Your environment's URL, e.g. https://yourorg.crm.dynamics.com | Including a path. Paste the origin only — no /main.aspx, no trailing path |
| Azure tenant ID | App registration → Overview → Directory (tenant) ID | Using a subscription ID, or the tenant of a different directory |
| Client ID | App registration → Overview → Application (client) ID | Using the Object ID, which sits directly beneath it and looks identical |
| Client secret | Certificates & secrets → the secret's Value | Copying the Secret ID instead of the Value. Both are shown in the same row and only one works |
Step 1 — Register the application in Azure
- In the Azure portal, go to Microsoft Entra ID → App registrations → New registration.
- Give it a name you will recognise later — the name is cosmetic, but it is
what you will search for in step 3. Something like
Marketing platform – Dynamics syncworks. - Under Supported account types, choose Accounts in this organizational directory only (single tenant).
- Leave Redirect URI empty. This connection signs in as itself, not as a person, so there is no browser redirect.
- Click Register.
On the Overview page that appears, copy two values into your scratch file:
- Application (client) ID → the Client ID field
- Directory (tenant) ID → the Azure tenant ID field
You do not need to add API permissions. Dynamics access is granted by the security role in step 4, not by anything on the API permissions page. Adding the Dynamics CRM permission does no harm, but it is not what makes the connection work — and adding it will not rescue a connection that is missing its Application User.
Step 2 — Create a client secret
- In the same app registration, open Certificates & secrets → Client secrets → New client secret.
- Add a description and choose an expiry. Azure allows at most 24 months.
- Click Add.
Copy the Value column now. Azure shows the secret's value exactly
once; after you navigate away it is permanently masked and you will have to
create another one. The adjacent Secret ID column is not the secret —
it is a reference to it, it is a GUID, and pasting it produces the single
most common connection error we see.
Put a reminder in your calendar a few weeks before the expiry date you chose. When a secret expires, the sync stops and the error says so, but nothing warns you in advance.
Step 3 — Add the Application User in Dynamics
This is the step people miss, and missing it produces a failure that looks like bad credentials even though the credentials are perfect.
- Go to the Power Platform admin center → Environments and select the environment you want to connect.
- Open Settings → Users + permissions → Application users.
- Click New app user.
- Click Add an app, then find your app registration — search by the name from step 1, or paste the Client ID. Select it and confirm.
- Pick a Business unit. The root business unit is the normal choice unless your organisation deliberately segments data by unit.
- Do not save yet — assign the security role first, in the next step. The form asks for it here.
An Application User is not a licensed human user and does not consume a user licence. It is how Dataverse recognises your app registration as a caller.
Step 4 — Assign a security role
In the same New app user panel, under Security roles, choose the role this connection will run as, then Create.
What the connection can see and change is governed entirely by this role. Azure's token grants access to the organisation as a whole; the role decides what happens inside it. Too thin a role fails silently — no error, just empty pickers and a sync that imports nothing.
The privileges we actually use are listed in full in the CRM permissions reference. In short, the role needs:
- Contact — Read, Write
- Lead — Read, Write
- Opportunity — Read (we mirror deals, we never write them)
- List and List Member — Read (for marketing-list sync scope)
- Account, Connection, Transaction Currency — Read (these only enrich the deal mirror; without them one field degrades rather than the sync failing)
The cleanest approach is a custom security role containing exactly those privileges. If you want the connection live quickly and will tighten it later, assigning a broad built-in role gets you connected — but treat that as a temporary state, not the finished configuration.
If you also plan to push engagement data back into Dynamics, that needs customisation rights once, at provisioning time only, plus one further grant so your own team can see the resulting rows. Both are covered in Pushing engagement data into Dynamics 365 — set up the sync first and come back to it.
Step 5 — Connect in the app
- Open Settings → the Integrations tab.
- Choose the CRM category, then the Dynamics 365 for Sales card.
- Pick the Online (Azure AD) sign-in method.
- Paste all four values from your scratch file. Each box carries a note naming the exact Azure screen its value comes from, and a Setup guide link back to this page.
- Click Connect.
Two of the mistakes in the table above are caught before anything is sent: a Secret ID in the client-secret box, and an Organization URL with a path on the end. If you see a red note under a box, nothing has left your browser yet — correct that value and the note clears as you type.
Once the values pass that check the app does two things, in this order: it asks Azure for a token, and then it calls your Dynamics environment to confirm the token is accepted. The connection is only saved if both succeed — so a card that appears is a card that genuinely works.
If something fails, the message appears at the top of the dialog, usually prefixed with "Could not verify Dynamics 365 for Sales:". The table below decodes it.
If the connection fails
Read the message carefully: it tells you which of the two halves failed, and that determines where to go looking.
Azure would not issue a token
Nothing reached Dynamics. One of the four pasted values is wrong, and the
message names which. Each carries an AADSTS… code your Azure
administrator can look up directly.
| Message | Code | Fix |
|---|---|---|
| Azure rejected the client secret — check you copied the secret's Value, not its Secret ID | AADSTS7000215 | Re-copy the Value column in Certificates & secrets. If it is masked, create a new secret (step 2) |
| The client secret has expired | AADSTS7000222 | Create a new secret and reconnect |
| Azure could not find an application with that Client ID | AADSTS700016 | Use Application (client) ID, not the Object ID. Also confirm the app is registered in the same tenant as the environment |
| Azure could not find that tenant | AADSTS90002 | Use Directory (tenant) ID from the app registration's Overview page |
| Azure did not recognise the Organization URL as a Dataverse environment | AADSTS500011 | Use https://yourorg.crm.dynamics.com with no path |
Dynamics rejected the sign-in
"Dynamics rejected the sign-in. The Azure credentials are valid, so this is usually a missing Application User: in the Power Platform admin centre, add an application user for this Client ID and give it a security role."
This is good news, and it is the most common failure of all. All four Azure values are correct — Azure issued a token, and only Dataverse refused it. You have almost certainly skipped step 3 or step 4, or done them in a different environment from the one your Organization URL points at.
Check, in this order:
- Does an Application User exist for this Client ID, in this environment? Compare the Organization URL you pasted against the environment you were editing in the admin center — a tenant with sandbox and production environments makes this easy to get wrong.
- Does that Application User have a security role? An Application User with no role is created successfully and then refuses every call.
- Is the Application User enabled?
Other messages
| Message | Meaning |
|---|---|
| Missing required field: … | One of the four boxes is empty. Nothing was sent |
| It connects, but pickers are empty and nothing syncs | The security role is too thin. See CRM permissions reference |
A wrong Organization URL does not reliably fail at the Azure step —
Azure issues tokens for the whole *.crm*.dynamics.com family, so a typo in
the region or organisation name surfaces as a failure to reach the
environment rather than a rejected credential. Note that your region
determines the exact hostname: crm.dynamics.com, crm4.dynamics.com,
crm11.dynamics.com and others are all normal. Use exactly what the admin
center shows you.
Checklist
Before you press Connect, all six of these should be true:
- App registration created, single-tenant, in the same directory as the Dynamics environment
- Application (client) ID and Directory (tenant) ID copied from its Overview page
- A client secret created, and its Value copied (not the Secret ID)
- An Application User added in the target environment for that Client ID
- A security role assigned to that Application User
- Organization URL is the environment's origin with no path
Related
- CRM permissions reference — every privilege we call, and why
- CRM sync scope — choosing which records sync
- Pushing engagement data into Dynamics 365 — the optional write-back