For service-to-service (S2S) client credentials flow against D365 F&SCM supply planning APIs, the scope configuration sits at the intersection of Azure AD app registration and D365 application user setup — both sides must align.
Azure AD / Entra ID App Registration
The effective OAuth2 scope for D365 F&SCM is always https://<your-environment>.operations.dynamics.com/.default in client credentials flow. You don’t define granular OAuth2 scopes at the token level the way you would with delegated permissions — the token grants access to the environment, and authorization granularity is enforced inside D365 via security roles and duties, not at the token scope level. This is a common architectural misunderstanding that causes over-provisioned application users.
Token request (client_credentials):
POST https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token
grant_type=client_credentials
&client_id={app_registration_client_id}
&client_secret={secret}
&scope=https://{d365-environment}.operations.dynamics.com/.default
D365 Application User & Role Scoping
Create a dedicated application user per integration workload (demand forecasting vs. inventory optimization), not a single shared user. Map each to the minimum required security roles:
- Demand forecasting:
Demand forecasting clerk duty or a custom role restricted to ReqDemandPlanningAPI-prefixed privileges (verify in your version)
- Inventory optimization: scope to relevant
InventSite/InventWarehouse entity access within a custom security role
This gives you the operational granularity you’re looking for at the duty/privilege level rather than at the OAuth scope level.
Token Lifetime & Refresh Strategy
Client credentials tokens have no refresh token — you re-request on expiry. Default access token lifetime in Entra ID is 60–75 minutes (verify in your version for any CAA/CAE policy overrides). Recommended pattern:
# Proactive refresh: re-acquire when < 5 minutes remaining
if token_expiry - datetime.utcnow() < timedelta(minutes=5):
token = acquire_new_token()
Cache tokens in a thread-safe store (Azure Key Vault + in-memory cache). Don’t re-request on every API call — you’ll hit Entra ID throttling under load.
Permission Auditing for Compliance
D365 System administration → Security → Audit log captures entity-level access. For API-specific tracing, enable Database logging on the entities your integrations touch (e.g., ForecastImpact, ReqTransPo). Correlate with Entra ID sign-in logs using the appId claim — this gives you end-to-end traceability from token issuance to data operation.
For structured compliance reporting, route D365 database logs + Entra ID sign-in logs into Microsoft Sentinel or your SIEM via the Diagnostics Settings connector.
Version Compatibility Note
D365 10.0.42 ships with updated OData and custom service endpoint behaviors — verify that any $batch requests to planning endpoints handle the Authorization header propagation correctly across batch changesets, as behavior has shifted in recent PU releases. Test against your sandbox before production rollout.
This draft is based on general Microsoft Dynamics 365 knowledge. It has not been verified against your specific version and environment. Practitioners: verify the steps and share your experience below.