Microsoft Dynamics 365 Business Central – OAuth Setup - Celigo Connection Tutorial

Since there were no in-depth tutorials available on the Celigo Community, I decided to share a complete and practical guide. OAuth setup for Microsoft 365 Business Central can be tricky, so I’ve documented the full process to help you connect M365 to Celigo more easily:

:page_facing_up: Provided by Teknuro.com
For questions or implementation support, contact: nuri@teknuro.com

:red_exclamation_mark:Background

Microsoft has deprecated the use of Web Service Access Keys for Business Central Online. Integrations must now use OAuth2.0.

This guide walks you through creating an OAuth App Registration in Azure Portal for use with Celigo integrator.io or other integration platforms.

:white_check_mark: Step-by-Step: Set up OAuth in Azure

1. Go to Azure Portal

Navigate to: https://portal.azure.com

2. Register a new application

  • Search for App registrations

  • Click New registration

  • Fill in:
    • Name: (e.g., Celigo Demo)
    • Supported account types: Choose as per your organization
  • Click Register

3. Configure Authentication

  • For redirect URI, enter:
    https://integrator.io/connection/oauth2callback
  • Click Configure

4. Set API Permissions

  • Go to API permissions
  • Click Add a permission

  • Choose Dynamics 365 Business Central****First:
    • Select Delegated permissions


  • Add required scopes (e.g., Financials.ReadWrite.All, etc.)

5. Create Client Secret

  • Go to Certificates & secrets
  • Click New client secret
  • Add description and expiry (e.g., 6 or 12 months)
  • Click Add


:paperclip: Example Output (For Reference Only)

Save the Client ID and Secret Value.

:warning: Store the Client Secret securely. You cannot retrieve it again later.
:warning: Creating a Business Central connection via OAuth still uses the Azure App Registration, which may grant higher privileges than intended if the app has broad permissions — bypassing user-level scope limitations.

Create Connection in Celigo

  • Go to Connections
  • Create Connection
  • Select Microsoft Dynamics 365 Business Central application and select for example API:

  • Enter your Microsoft Dynamics 365 Business Central environment.
    How to retrieve the environment name:
  1. Sign in to the Microsoft Dynamics 365 Business Central admin center.
  2. Click Environment .
  3. Copy the Environment Name

Name here is Production, so we fill in Production:

:white_check_mark:Now the connection should work and you will see a online connection:

If it is not working, you can also switch to the HTTP tab in the connection to be created:

As a base uri fill in: https://api.businesscentral.dynamics.com/v2.0/Production/api

(Production is your environment name here)

Then scroll down and select OAuth 2.0 as the Auth:

Click on the plus and create the iClient.
Here you will fill in a name and the client id and secret (which we generated in azure in the previous steps

Now click on Save & Authorize and it should work now:


:blue_book: Notes

  • This OAuth setup is required for all new integrations with Microsoft Dynamics 365 Business Central Online.
  • Use these credentials to authenticate in Celigo’s HTTP connector or prebuilt Business Central connector using OAuth 2.0.
7 Likes

@nuriensing You've been such a great part of the Celigo Connective community from its inception and this post is another great example of your awesome partnership. Thank you for taking the time to share your knowledge in such a detailed and thoughtful way! :clap:

1 Like

Thank you so much for the kind words, I truly appreciate it!

1 Like

Separately, I've sent this to @stephenbrandt and his docs team to improve our docs around this! As you can imagine, doing this for all 800 connections is a challenge so we appreciate the help!

1 Like

I just need to highlight one more part.

When creating a connection via Celigo > Microsoft 365 Business Central using OAuth 2.0, the process still opens a Microsoft consent screen — a pop-up that asks the user to grant permissions to the app.

Even if the OAuth app in Azure is configured with limited scopes (e.g., Financials.ReadWrite), the connection still results in full read/write access within Business Central. This behavior suggests that the actual access granted may exceed the scope requested, which is concerning.

Feel free to add insights about this.

Super helpful!! Thank you for doing this!

This is weird, do you think it’s a Microsoft bug or our bug? If you setup the same thing in Postman do you get the same outcome?

Nuri,
I am not 100% sure, as I have not tested this myself, but this could have to do with the permissions type that you set on the app.
Microsoft has the ability for you to define Delegated or Application.

Depending on how the app was configured, if you are using delegated and then logging in with an Admin user it could be inheriting permissions from the user.
As per the comparison below delegate permission is "Limited to what the user could do (plus any extra scopes granted). Can be further constrained by Conditional Access or RBAC targeted at the user."

I would suggest trying to setup a specific user in Azure, such as app_login@mycompany.com, with only the specific access you want to grant and use that to login in Integrator.IO when setting up the connection.

===============================================================================
In Azure AD (and therefore Microsoft Entra ID and Microsoft Graph), “Delegated” and “Application” designate the two fundamental permission types an app can ask for. They differ in whose identity is used, how tokens are issued, what appears inside the token, and who can grant consent.

Aspect Delegated permissions (“scope”) Application permissions (“app-only / app role”)
Identity in the access token The signed-in user + the app (the app is acting on behalf of that user). The app itself (service principal) only; no user context.
Typical OAuth 2.0 flow Authorization-code / hybrid / device-code, etc.—interactive, because a user must sign in. Client-credentials (daemon/daemonless), certificate or secret—non-interactive.
Claim that carries privileges scp claim lists the scopes (e.g., user.read, mail.send). roles claim lists the app roles (e.g., User.Read.All).
Consent required User can self-consent to low-impact scopes; higher-impact scopes need tenant-admin consent. Always needs admin consent because it allows the app to act without a user present.
Granularity of access Limited to what the user could do (plus any extra scopes granted). Can be further constrained by Conditional Access or RBAC targeted at the user. Often broader: the app can reach every object the permission covers across the tenant. You must constrain it with its own RBAC assignments or resource-specific permissions.
Typical scenarios Single-page or mobile apps, web apps where users read/write their own mail, calendars, files, etc. Daemons and background jobs, sync engines, export tools, unattended automation, APIs that must run 24×7.

Key points explained

  1. User context vs. app context

    • With delegated permissions the access token represents both the user and the application, so every call happens “through” the user. If that user loses access (e.g., disabled account), the call fails because the user can no longer sign in. (Microsoft Learn)
    • With application permissions the token represents only the application. The user factor is irrelevant; the app still works even when no one is logged in. (Microsoft Learn)
  2. Consent and security posture

    • Delegated scopes can be granted by individual users for low-impact data (for example, an Outlook add-in requesting Mail.Read). More sensitive scopes, or scopes in tenants where user consent is disabled, require an administrator. (Microsoft Learn)
    • Application permissions bypass user-level checks, so Azure always requires an administrator to approve them. Apply the least-privilege principle: request only the narrowest app role your service really needs. (Microsoft Learn, Microsoft Learn)
  3. Token differences

    • Delegated token → scp claim lists granted scopes.
    • Application token → roles claim lists granted app roles. These claims tell Microsoft Graph (or any API that trusts Entra ID) which operations are allowed. (Microsoft Learn)
  4. Example
    Suppose you have a nightly export service that copies every user’s OneDrive content to an archive bucket:

    • You’d register an app with Files.Read.All application permission and run it with the client-credentials flow—no user ever signs in.
      Conversely, if you’re building a Teams add-in that shows the signed-in person’s recent files, you’d request Files.Read delegated scope. Each user consents the first time the add-in runs, and the token only lets the add-in see that user’s files.

Choosing the right type

  • Need a signed-in user? → Delegated.
  • Run headless / server-to-server? → Application.
  • Want to limit access to exactly what the user can already do? → Delegated.
  • Need tenant-wide or cross-user access? → Application, plus extra guardrails (e.g., restrict the service principal via Azure RBAC or resource-specific consents in SharePoint/Teams).

Understanding the distinction is crucial for designing secure solutions and passing Azure’s consent review.