Summary
Add native support for connecting to Microsoft Dynamics 365 CRM (Customer Engagement / Sales) and Dataverse from DuckDB, enabling users to authenticate and query CRM data using SQL.
Relationship to Business Central Integration (#5)
This issue shares significant implementation overlap with #5 (Business Central Integration). Both use:
- Microsoft Entra ID OAuth2 authentication (identical token endpoint and flow)
- OData v4 API compliance (same query capabilities)
- Same scope pattern for tokens (
{resource_url}/.default)
Recommended approach: Implement a shared microsoft_entra or azure_ad authentication provider that both Business Central and CRM/Dataverse integrations can use. This avoids code duplication and ensures consistent authentication behavior.
Background
Microsoft Dynamics 365 CRM (also known as Customer Engagement, Sales, or Dataverse) is a cloud-based CRM platform widely used for sales, marketing, customer service, and field service operations. It exposes data through:
- Dataverse Web API (OData v4 compliant)
- Standard entities (accounts, contacts, leads, opportunities, etc.)
- Custom entities (user-defined tables)
User Stories
1. Service-to-Service Authentication (Primary)
As a data engineer, I want to configure automated access to Dynamics 365 CRM using client credentials, so that I can build ETL pipelines without user interaction.
Acceptance Criteria:
- Create a secret with
client_id, client_secret, tenant_id, and environment_url
- Authenticate using OAuth2 client credentials flow against Microsoft Entra ID
- Automatically obtain and refresh tokens as needed
2. Interactive User Authentication
As an analyst, I want to authenticate to Dynamics 365 CRM using my Microsoft account, so that I can query data with my user permissions.
3. Entity Discovery
As a user, I want to discover all available entities in my Dataverse environment, so that I can explore the data model.
4. Entity Schema Discovery
As a user, I want to describe the schema of a specific entity, so that I understand the available fields.
5. Data Reading with Pushdown
As an analyst, I want to query Dynamics 365 CRM data using SQL with filter pushdown, so that I can efficiently retrieve only the data I need.
Technical Context
Dataverse Web API Structure
Base URL Pattern:
https://{organization}.crm.dynamics.com/api/data/v9.2/
Authentication (Same as Business Central #5)
Microsoft Entra ID OAuth2:
- Token endpoint:
https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token
- Scope:
{environment_url}/.default
- Client credentials flow for S2S automation
Core CRM Entities
Sales: accounts, contacts, leads, opportunities, quotes, orders, invoices
Marketing: campaigns, lists, campaignresponses
Customer Service: incidents (cases), knowledgearticles, queues
Common: systemusers, teams, businessunits, annotations, activities
Query Capabilities (Same as Business Central)
$filter, $select, $expand, $top, $skip, $count, $orderby
Example Usage (Conceptual)
-- Create secret for S2S authentication
CREATE SECRET crm_secret (
TYPE dataverse,
PROVIDER client_credentials,
CLIENT_ID 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
CLIENT_SECRET 'your-client-secret',
TENANT_ID 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
ENVIRONMENT_URL 'https://myorg.crm.dynamics.com'
);
-- Discover all available entities
SELECT * FROM crm_show_entities(secret := 'crm_secret');
-- Describe entity schema
SELECT * FROM crm_describe('accounts', secret := 'crm_secret');
-- Query accounts with filter pushdown
SELECT name, emailaddress1, revenue
FROM crm_read('accounts', secret := 'crm_secret')
WHERE statecode = 0;
-- Query opportunities with expansion
SELECT * FROM crm_read('opportunities', secret := 'crm_secret', expand := 'customerid_account')
WHERE estimatedclosedate >= '2024-01-01';
Implementation Strategy
Shared Components with Business Central (#5)
| Component |
Reuse Strategy |
| Microsoft Entra ID OAuth2 |
Create shared MicrosoftEntraAuthProvider class |
| Token refresh logic |
Shared token storage and refresh mechanism |
| OData v4 query building |
Existing odata_client infrastructure |
| Predicate pushdown |
Existing odata_predicate_pushdown_helper |
CRM-Specific Components
| Component |
Description |
| URL builder |
CRM-specific URL patterns ({org}.crm.dynamics.com/api/data/v9.x/) |
| Entity discovery |
Query EntityDefinitions metadata endpoint |
| Secret type |
TYPE dataverse with ENVIRONMENT_URL parameter |
Out of Scope
- Write operations (POST, PATCH, DELETE)
- FetchXML query support
- On-premises deployments
References
Summary
Add native support for connecting to Microsoft Dynamics 365 CRM (Customer Engagement / Sales) and Dataverse from DuckDB, enabling users to authenticate and query CRM data using SQL.
Relationship to Business Central Integration (#5)
This issue shares significant implementation overlap with #5 (Business Central Integration). Both use:
{resource_url}/.default)Recommended approach: Implement a shared
microsoft_entraorazure_adauthentication provider that both Business Central and CRM/Dataverse integrations can use. This avoids code duplication and ensures consistent authentication behavior.Background
Microsoft Dynamics 365 CRM (also known as Customer Engagement, Sales, or Dataverse) is a cloud-based CRM platform widely used for sales, marketing, customer service, and field service operations. It exposes data through:
User Stories
1. Service-to-Service Authentication (Primary)
As a data engineer, I want to configure automated access to Dynamics 365 CRM using client credentials, so that I can build ETL pipelines without user interaction.
Acceptance Criteria:
client_id,client_secret,tenant_id, andenvironment_url2. Interactive User Authentication
As an analyst, I want to authenticate to Dynamics 365 CRM using my Microsoft account, so that I can query data with my user permissions.
3. Entity Discovery
As a user, I want to discover all available entities in my Dataverse environment, so that I can explore the data model.
4. Entity Schema Discovery
As a user, I want to describe the schema of a specific entity, so that I understand the available fields.
5. Data Reading with Pushdown
As an analyst, I want to query Dynamics 365 CRM data using SQL with filter pushdown, so that I can efficiently retrieve only the data I need.
Technical Context
Dataverse Web API Structure
Base URL Pattern:
Authentication (Same as Business Central #5)
Microsoft Entra ID OAuth2:
https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token{environment_url}/.defaultCore CRM Entities
Sales:
accounts,contacts,leads,opportunities,quotes,orders,invoicesMarketing:
campaigns,lists,campaignresponsesCustomer Service:
incidents(cases),knowledgearticles,queuesCommon:
systemusers,teams,businessunits,annotations,activitiesQuery Capabilities (Same as Business Central)
$filter,$select,$expand,$top,$skip,$count,$orderbyExample Usage (Conceptual)
Implementation Strategy
Shared Components with Business Central (#5)
MicrosoftEntraAuthProviderclassodata_clientinfrastructureodata_predicate_pushdown_helperCRM-Specific Components
{org}.crm.dynamics.com/api/data/v9.x/)EntityDefinitionsmetadata endpointTYPE dataversewithENVIRONMENT_URLparameterOut of Scope
References