Dynamics 365
Reads accounts, opportunities and cases from a Dynamics 365 (Dataverse) environment, so commercial and service agents can answer from the account and case history. It reads in place, in your deployment; only ids, hashes and counts reach LightHouse.
At a glance
Section titled “At a glance”| Collector | Dynamics 365, version 1.0.0 |
|---|---|
| Reads | Microsoft: Dynamics 365 (Dataverse Web API) (the vendor's documentation) |
| Family | CRM |
| Kind | CRM |
| Ways to connect | OAuth approval |
| Scopes |
|
| Read only | Yes, except: [object Object] |
| Vendor's API can move money | No |
| Personal data | Contact, Content |
| Hosts it may contact | {org}.crm{region}.dynamics.com, login.microsoftonline.com |
| Vendor API versions | Dataverse Web API v9.2 |
| Lowest engine version | 0.46.0 |
What it reads
Section titled “What it reads”- Accounts: name, account number, industry, website, city, country, description, primary contact (as its formatted name).
- Opportunities: name, customer, state, sales stage, estimated value, estimated close date, close probability, description.
- Cases (the
incidenttable): title, ticket number, customer, state, priority, case type, description. - Only the tables you name in
objects(accounts,opportunities,cases), and only the columns above ($select), with lookups as their formatted names. - Changes only: each table is read by
modifiedon(UTC), oldest first, 500 a page, following@odata.nextLink, which must stay on the environment’s host.
How to connect
Section titled “How to connect”- In Microsoft Entra, make an app registration with a certificate, as for SharePoint, and note the directory (tenant) id and application (client) id.
- In your Dynamics 365 environment, add the app as an application user with a security role that is a read-only copy over the three tables.
- In LightHouse, open Setup and admin, Connectors, choose
Dynamics 365, and give
environment_url(https://<org>.crm.dynamics.com, orcrm2,crm4and so on for your region) andobjects. - Paste the certificate’s private key. Your browser seals it to your deployment; LightHouse never sees it.
The credential is JSON in the variable the source names
(DYNAMICS_CREDENTIAL by default): tenant_id, client_id, certificate
and environment_url.
Permissions
Section titled “Permissions”- Scope requested:
<environment_url>/.default: a token for that environment alone, minted from a certificate assertion signed in your own account (client-credentials grant). No client secret exists. - Dataverse states no permissions in the token, so read-only is the security role you give the application user: a copy of a read-only role over accounts, opportunities and cases. The connection check says so.
- What the collector does:
GETrequests to/api/data/v9.2/<table>, plus onePOSTto Microsoft’s token endpoint (login.microsoftonline.com/<tenant>/oauth2/v2.0/token) for the access token. Its read-only test proves that on every change. - Hosts: your environment and Microsoft’s login host. A next-page link to any other host is refused.
Limits
Section titled “Limits”- Dataverse Web API v9.2.
environment_urlmust look likehttps://<org>.crm.dynamics.com(with an optional region number aftercrm).- Pages of 1 to 5,000 rows (
page_size, default 500). - Deletions are found by listing primary keys every six hours; a deleted record is removed from the corpus then, not at once.
- A table the role cannot list (403 or 404) skips the deletion check for it rather than failing the read.
Data handling
Section titled “Data handling”- Accounts, contacts’ names and cases hold personal data. Documents carry the
labelyou give the source. - Content is read in place, in your deployment. LightHouse receives ids, hashes and counts, never the records, and never opens the credential.
- The raw bytes of each response are cached in your deployment, named by their SHA-256, so any passage can be traced to what was served.
- The private key is used only to sign the assertion; it is never put in a request, a log line or an error message.
Troubleshooting
Section titled “Troubleshooting”| What you see | What it means | What to do |
|---|---|---|
credential variable 'DYNAMICS_CREDENTIAL' is not set |
The deployment holds no credential for this source | Connect Dynamics 365 again in LightHouse |
the dynamics credential has no environment_url |
A field (named in the message) is missing | Re-enter all four fields |
environment_url is https://<org>.crm.dynamics.com |
The URL is not a Dataverse environment | Use the environment’s own address |
tenant_id is the directory's id, a GUID |
tenant_id is not a GUID |
Copy the directory id from Entra |
HTTP 401 or HTTP 403 |
The app is not an application user, or its role lacks a table | Add the application user and give it read on the table |
HostNotAllowed (... is not an allowed host) |
A next-page link named another host | Report it; nothing was sent there |
Certification
Section titled “Certification”Each entry is a run by Atlantic Agentic Labs, newest first. Only a run against the vendor’s sandbox or a client environment certifies a collector; a certification lasts six months, or less if the vendor publishes an API version the collector does not list. See How collectors are certified.
| Date | Collector | Engine | Vendor API | Method | Expires |
|---|---|---|---|---|---|
| 10 November 2026 | 1.0.0 | 0.46.0 | Dataverse Web API v9.2 | Fixtures only: built, not certified | Not applicable |
Security posture
Section titled “Security posture”From the collector’s last scan on the default branch. What each line means, and what blocks a release: Security posture.
| Last scanned | 10 November 2026 |
|---|---|
| Critical findings | 0 |
| High findings | 0 |
| Medium findings | 0 |
| Low findings | 0 |
| Info findings | 0 |
| Release blocked | No |
| Network allow-list check | Pass |
| Read-only behavioural test | Pass |
| SBOM (CycloneDX) | Produced |
| Dependency licences | Pass |
| Scanners | bandit 1.9.4, semgrep 1.181.1, pip-audit 2.10.1, osv-scanner 2.7.0, cyclonedx-py 7.5.0, pip-licenses 5.5.5, gitleaks repository job aal-secrets, hosts_check tools/hosts_check.py, read-only test pytest -m read_only |