---
title: "Microsoft 365 Exchange Reports collector"
canonical: "https://docs.devo.com/space/latest/622559292/Microsoft%20365%20Exchange%20Reports%20collector"
format: markdown
---
> Macro (excerpt-include)



> Macro (toc)

## Purpose

An analyst wants to detect data exfiltration in [Microsoft 365 Exchange Online](https://www.microsoft.com/en-us/microsoft-365/exchange/exchange-online). Using the Microsoft 365 Exchange Reports collector to send email traffic and security logs to Devo, the analyst will find suspicious message patterns and compliance violations. As a result, the analyst will block unauthorized sharing of sensitive information, preventing data loss through email channels.

## Example tables

| **Table** | **Description** |
| --- | --- |
| `cloud.office365.reporting.mailtraffic` | Summary information about mail traffic to and from the organization |
| `cloud.office365.reporting.dlpdetail` | Details about Data Loss Prevention rule matches across Exchange, SharePoint, and OneDrive |
| `cloud.office365.reporting.spoofmail` | Information about mail traffic from spoofed senders |
| `cloud.office365.reporting.atptraffic` | Results of Exchange Online Protection and Microsoft Defender detections |
| `cloud.office365.reporting.dlp` | Summary of Data Loss Prevention rule matches across services |
| `cloud.office365.reporting.maildetailatp` | Details about Exchange Online Protection and Microsoft Defender detections |
| `cloud.office365.reporting.safelinksdetail` | Detailed information about Safe Links results |
| `cloud.office365.reporting.messagetrace` | Reports for every email sent and received through Exchange Online |

## Authorize it

1 . Go to **Entra ID** portal and log in with your account.

2. Navigate to the **“App registration”** blade. Click on the **“+ New Registration”** button.
3. Give the application a name. Click the **“Register”** button.
4. On the **Overview** page, copy the **Application (client) ID** and **Directory (tenant) ID** values.
5. On the left side menu, navigate to the **“Certificates & secrets”** page and click on **“+ New client secret” **button. Set a description and an expiration for the secret. Click on the **“Add”** button.
6. Copy the **Value** field of the secret (it will only be shown once).
7. On the left side panel of your application, navigate to the **“API permissions”** page. Click the **“+ Add”** a permission button.
8. Navigate to the **"APIs my organization uses"** tab and select *Microsoft 365 Exchange Online* entry from the list. Click the **Application permissions** button.
9. Under the **ReportingWebService **section, select *ReportingWebService.Read.All* permission and click the **“Add permissions”** button.
10. Click **Grant admin consent **for your domain and confirm by clicking **“Yes”**.

## Run it

In the Cloud Collector App, [create](https://devodocs.atlassian.net/wiki/spaces/latest/pages/409305131) an **Office 365 Exchange Reports** collector instance.  Insert this parameters template, replacing the values enclosed in `< >`.  The `id` must be a unique [five digit number](https://www.random.org/integers/?num=1&min=10000&max=99999&col=5&base=10&format=html&rnd=new).

```

  "inputs": {
    "office365": {
      "id": "<FIVE_UNIQUE_DIGITS>",
      "services": {
        "office365_reporting_MailTraffic_service": {
          "creds_username": "<USER_EMAIL>",
          "creds_password": "<CREDS_PASSWORD_VALUE>"
      },
      "credentials": {
        "client_id": "<CLIENT_ID_VALUE>",
        "tenant_id": "<TENANT_ID_VALUE>",
        "client_secret": "<SECRET_VALUE>"
      }
    }
  }
}
```

## Secure it

Devo Exchange provides these resources:

**Alert Pack**

- [Account Manipulation (MITRE Att&ck Technique: T1098)](https://docs.devo.com/space/latest/325222844/Mitre+alert+packs+T1000-1099#Account-Manipulation)
- [Brute Force (MITRE Att&ck Technique: T1110)](https://docs.devo.com/space/latest/326172673/Mitre+alert+packs+T1100-1199#Brute-Froce)

## Monitor it

Create an [inactivity alert](https://devodocs.atlassian.net/wiki/spaces/latest/pages/95126785) to detect interruptions of transfer of data from the source  using the query

```
from cloud.office365.reporting.mailtraffic 
where toktains(hostchain,"collector-") 
select split(hostchain,"-",1) as collector_id
```

Set the inactivity alert to keep track of the `collector_id`.

## Parameters

### Example

```
{
  "global_overrides": {
    "debug": false
  },
  "inputs": {
    "office365_reporting_message": {
      "id": "<short_unique_id>",
      "enabled": true,
      "requests_per_second": 5,
      "max_historic_date_cutoff_days_back": "<max_historic_date_cutoff_days_back_value>",
      "max_historic_date_margin_seconds": "<max_historic_date_margin_seconds_value>",
      "credentials": {
        "tenant_id": "<tenant_id_value>",
        "client_id": "<client_id_value>",
        "client_secret": "<client_secret_value>"
      },
      "services": {
        "office365_reporting_MailTraffic_service": {
          "request_period_in_seconds": "<request_period_in_seconds_value>",
          "reset_persistence_auth": "<reset_persistence_auth_value>",
          "override_time_delay_in_seconds": 3600
        },
        "office365_reporting_DlpDetail_service": {
          "request_period_in_seconds": "<request_period_in_seconds_value>",
          "reset_persistence_auth": "<reset_persistence_auth_value>",
          "override_time_delay_in_seconds": 3600
        },
        "office365_reporting_SpoofMail_service": {
          "request_period_in_seconds": "<request_period_in_seconds_value>",
          "reset_persistence_auth": "<reset_persistence_auth_value>",
          "override_time_delay_in_seconds": 3600
        },
        "office365_reporting_AdvancedThreatProtectionTraffic_service": {
          "request_period_in_seconds": "<request_period_in_seconds_value>",
          "reset_persistence_auth": "<reset_persistence_auth_value>",
          "override_time_delay_in_seconds": 3600
        },
        "office365_reporting_Dlp_service": {
          "request_period_in_seconds": "<request_period_in_seconds_value>",
          "reset_persistence_auth": "<reset_persistence_auth_value>",
          "override_time_delay_in_seconds": 3600
        },
        "office365_reporting_MailDetailATP_service": {
          "request_period_in_seconds": "<request_period_in_seconds_value>",
          "reset_persistence_auth": "<reset_persistence_auth_value>",
          "override_time_delay_in_seconds": 3600
        },
        "office365_reporting_SafelinksDetail_service": {
          "request_period_in_seconds": "<request_period_in_seconds_value>",
          "reset_persistence_auth": "<reset_persistence_auth_value>",
          "override_time_delay_in_seconds": 3600
        }
      }
    }
  }
}
```

### Details

| **Parameter** | **Data type** | **Necessity** | **Details** |
| --- | --- | --- | --- |
| `input_id` | `integer` | `Mandatory` | Five **unique** digits. |
| `input_status` | `boolean` | `Mandatory` | If the value is `true`, the input definition will be executed. If the value is `false`, the service will be ignored. |
| `requests_per_second` | `integer` | `Optional` | Customize the maximum number of API requests per second. If not used, the default setting will be used: `100000` requests/sec |
| `tenant_id` | `string` | `Mandatory` | Tenant’s ID you created in Microsoft 365. |
| `client_id` | `string` | `Mandatory` | Client’s ID you created in Microsoft 365. |
| `client_secret` | `string` | `Mandatory` | Client’s Secret you created in Microsoft 365. |
| `creds_username` | `string` | `Mandatory` | Username to authenticate to the service.<br>Email format: [username@domain.com](mailto:username@domain.com) |
| `creds_password` | `string` | `Mandatory` | Password to authenticate to the service. |
| `request_period_in_seconds` | `integer` | `Optional` | By default, this service will run every `60` seconds. This parameter allows you to customize this behavior. |
| `reset_persistence_auth` | `string` | `Optional` | This parameter allows you to clear the persistence of the collector and restart the download pipeline.<br>Updating this value will produce the lost of all persisted data and current pipelines.<br>Format: `YYYY-MM-DD` |

## Troubleshooting

This collector has different security layers that detect both an invalid configuration and abnormal operation. This table will help you detect and resolve the most common errors.

| Error Type | Error Id | Error Message | Cause | Solution |
| --- | --- | --- | --- | --- |
| InitVariableError | 0 | credentials section does not exist on the configuration file or is empty | The credentials section is missing or empty. | Add the credentials section with `tenant_id`, `client_id`, and `client_secret`. |
| InitVariableError | 1 | credentials section is not a valid object | The credentials section format is incorrect. | Ensure the credentials section is a valid dictionary/object. |
| InitVariableError | 2 | `tenant_id` doesn't exist on the configuration file or is empty | The `tenant_id` is missing. | Add the `tenant_id` to the credentials section. |
| InitVariableError | 3 | `tenant_id` must be an string | The tenant_id is not a string value. | Ensure the `tenant_id` is provided as a string value. |
| InitVariableError | 4 | `client_id` doesn't exist on the configuration file or is empty | The `client_id` is missing. | Add the `client_id` to the credentials section. |
| InitVariableError | 5 | `client_id` must be an string | The `client_id` is not a string value. | Ensure the client_id is provided as a string value. |
| InitVariableError | 6 | `client_secret `doesn't exist on the configuration file or is empty | The client_secret is missing. | Add the `client_secret` to the credentials section. |
| InitVariableError | 7 | `client_secret `must be an string | The client_secret is not a string value. | Ensure the `client_secret` is provided as a string value. |
| SetupError | 100 | Authentication failed: `{response.text}` | Authentication credentials are invalid. | Check the credentials (`tenant_id`, `client_id`, `client_secret`) and Azure AD app permissions. |
| SetupError | 101 | Unexpected status code when fetching Office365ExchangeReports JWT: `{status_code} {response.text}` | Unexpected error occurred while generating authentication token. | Contact the developer with exact error message and status code. |
| SetupError | 102 | Error occurred while accessing the access_token: `{str(e)}` | Network or other error occurred while generating authentication token. | Check network connectivity and firewall settings. Contact the developer with exact error message. |
| ApiError | 200 | HTTP error occurred while pulling data: `{http_err}` | API request failed. | Check API endpoint availability and network connectivity. |
| PullError | 300 | Error occurred while pulling data: `{e}` | Unexpected error occurred while pulling data. | Contact the developer with exact error message. |

## API Endpoints

| **Endpoint** | **Service** | **Table** |
| --- | --- | --- |
| `https://reports.office365.com/ecp/reportingwebservice/reporting.svc/MailTraffic` | `office365_reporting_MailTraffic_service` | `cloud.office365.reporting.mailtraffic` |
| `https://reports.office365.com/ecp/ReportingWebService/Reporting.svc/DlpDetailReport` | `office365_reporting_DlpDetail_service` | `cloud.office365.reporting.dlpdetail` |
| `https://reports.office365.com/ecp/ReportingWebService/Reporting.svc/SpoofMailReport` | `office365_reporting_SpoofMail_service` | `cloud.office365.reporting.spoofmail` |
| `https://reports.office365.com/ecp/reportingwebservice/reporting.svc/MailTrafficATP` | `office365_reporting_AdvancedThreatProtectionTraffic_service` | `cloud.office365.reporting.atptraffic` |
| `https://reports.office365.com/ecp/ReportingWebService/Reporting.svc/DlpDetectionsReport` | `office365_reporting_Dlp_service` | `cloud.office365.reporting.dlp` |
| `https://reports.office365.com/ecp/ReportingWebService/Reporting.svc/MailDetailATP` | `office365_reporting_MailDetailATP_service` | `cloud.office365.reporting.maildetailatp` |
| `https://reports.office365.com/ecp/ReportingWebService/Reporting.svc/SafelinksDetail` | `office365_reporting_SafelinksDetail_service` | `cloud.office365.reporting.safelinksdetail` |

## Devo collector features

| **Feature** | **Details** |
| --- | --- |
| Allow parallel downloading (`multipod`) | `not allowed` |
| Running environments | - `collector server`
- `on-premise` |

## Release Notes

- **Version 1.3.0** (2025-07-17)
  - The DevoCollectorSDK Python package (devo-collector-sdk) has been updated from "1.16.2" to "1.16.3"
  - Removed Unused service.
- **Version 1.2.0 **(2025-06-03)
  - Updated DCSDK Docker base image from "1.5.0" to "1.5.1" and DevoCollectorSDK Python package from "1.16.1" to "1.16.2"
- **Version 1.1.0** (2025-05-20)
  - Updated DCSDK Docker base image from "1.2.0" to "1.5.0" and DevoCollectorSDK Python package from "1.11.1" to "1.16.1"
- **Version 0.4.1-beta** (2024-05-14)
  - Updated DCSDK from 1.7.2 to 1.11.1 and added auto update SDK feature.
  - Fixed a bug causing 500 errors due to invalid start_time range requests.