Wazuh Office 365 - Microsoft 365 Audit Monitoring

Wazuh provides security monitoring for Microsoft 365 through the office365 module, which collects audit logs from the Office 365 Management Activity API. The module tracks user actions across Exchange Online, SharePoint Online, Microsoft Teams, Azure Active Directory, and DLP events. This integration enables detection of suspicious sign-ins, unauthorized mailbox access, DLP policy violations, and administrative actions within a Microsoft 365 tenant.

Office 365 Management Activity API

The Office 365 Management Activity API is a REST API that provides access to audit and activity logs from various Microsoft 365 services. The API uses a subscription model: the client subscribes to specific content types and periodically requests new events.

Content Types

Content TypeDescription
Audit.AzureActiveDirectoryAuthentication events, user and group management in Microsoft Entra ID
Audit.ExchangeMailbox operations, transport rules, anti-spam actions
Audit.SharePointFile operations, site management, permission changes in SharePoint and OneDrive
Audit.GeneralWorkload events not covered by other categories (Teams, Power BI)
DLP.AllData Loss Prevention policy triggers for Exchange, SharePoint, and OneDrive

Azure AD Application Registration

The module requires a registered application in Microsoft Entra ID with permissions to access the Management Activity API.

Registration Procedure

  1. Navigate to portal.azure.com and open Microsoft Entra ID - App registrations
  2. Select New registration
  3. Provide a name (for example, Wazuh-Office365-Monitor)
  4. Select Accounts in this organizational directory only (Single tenant)
  5. Record the values from the Overview section:
    • Application (client) ID
    • Directory (tenant) ID

Creating a Client Secret

  1. Navigate to Certificates & Secrets
  2. Select New client secret
  3. Provide a description and expiration period (12-24 months recommended)
  4. Copy the secret value (displayed only once)

Assigning API Permissions

  1. Navigate to API permissions - Add a permission
  2. Select Office 365 Management APIs
  3. Select Application permissions
  4. Add the following permissions:
PermissionDescription
ActivityFeed.ReadRead activity data for your organization
ActivityFeed.ReadDlpRead DLP policy events including detected sensitive data
  1. Select Grant admin consent for [Your Organization]

Module Configuration (office365)

The module is configured in ossec.conf on the Wazuh server.

Basic Configuration

<office365>
  <enabled>yes</enabled>
  <interval>1m</interval>
  <curl_max_size>1M</curl_max_size>
  <only_future_events>yes</only_future_events>
  <api_auth>
    <tenant_id>YOUR_TENANT_ID</tenant_id>
    <client_id>YOUR_CLIENT_ID</client_id>
    <client_secret>YOUR_CLIENT_SECRET</client_secret>
    <api_type>commercial</api_type>
  </api_auth>
  <subscriptions>
    <subscription>Audit.AzureActiveDirectory</subscription>
    <subscription>Audit.Exchange</subscription>
    <subscription>Audit.SharePoint</subscription>
    <subscription>Audit.General</subscription>
    <subscription>DLP.All</subscription>
  </subscriptions>
</office365>

Government Cloud Configuration (GCC)

<office365>
  <enabled>yes</enabled>
  <interval>5m</interval>
  <curl_max_size>1M</curl_max_size>
  <only_future_events>yes</only_future_events>
  <api_auth>
    <tenant_id>YOUR_TENANT_ID</tenant_id>
    <client_id>YOUR_CLIENT_ID</client_id>
    <client_secret>YOUR_CLIENT_SECRET</client_secret>
    <api_type>gcc-high</api_type>
  </api_auth>
  <subscriptions>
    <subscription>Audit.AzureActiveDirectory</subscription>
    <subscription>Audit.Exchange</subscription>
  </subscriptions>
</office365>

Multi-Tenant Configuration

When monitoring multiple Microsoft 365 tenants, add multiple api_auth blocks:

<office365>
  <enabled>yes</enabled>
  <interval>1m</interval>
  <curl_max_size>1M</curl_max_size>
  <only_future_events>yes</only_future_events>
  <api_auth>
    <tenant_id>TENANT_ID_1</tenant_id>
    <client_id>CLIENT_ID_1</client_id>
    <client_secret>CLIENT_SECRET_1</client_secret>
    <api_type>commercial</api_type>
  </api_auth>
  <api_auth>
    <tenant_id>TENANT_ID_2</tenant_id>
    <client_id>CLIENT_ID_2</client_id>
    <client_secret>CLIENT_SECRET_2</client_secret>
    <api_type>commercial</api_type>
  </api_auth>
  <subscriptions>
    <subscription>Audit.AzureActiveDirectory</subscription>
    <subscription>Audit.General</subscription>
  </subscriptions>
</office365>

Module Parameters

ParameterDefaultDescription
enabledyesEnable or disable the module
interval10mAPI polling interval (s/m/h/d)
curl_max_size1MMaximum API response size
only_future_eventsyesCollect only new events after the first run
tenant_id-Azure AD tenant identifier
client_id-Application (client) identifier
client_secret-Client secret value
api_typecommercialSubscription type (commercial, gcc, gcc-high)

API Endpoints by Subscription Type

TypeURL
Enterprisehttps://manage.office.com/api/v1.0/{tenant_id}/activity/feed/{operation}
GCChttps://manage-gcc.office.com/api/v1.0/{tenant_id}/activity/feed/{operation}
GCC Highhttps://manage.office365.us/api/v1.0/{tenant_id}/activity/feed/{operation}
DoDhttps://manage.protection.apps.mil/api/v1.0/{tenant_id}/activity/feed/{operation}

Alert Examples

Suspicious Sign-In Activity

{
  "rule": {
    "id": "91545",
    "level": 6,
    "description": "Office 365: Suspicious sign-in activity detected"
  },
  "data": {
    "office365": {
      "Workload": "AzureActiveDirectory",
      "Operation": "UserLoginFailed",
      "UserId": "user@company.com",
      "ClientIP": "198.51.100.42",
      "ResultStatus": "Failed",
      "LogonError": "InvalidUserNameOrPassword",
      "DeviceProperties": {
        "OS": "Windows 10",
        "BrowserType": "Chrome"
      }
    }
  }
}

Non-Owner Mailbox Access

{
  "rule": {
    "id": "91550",
    "level": 7,
    "description": "Office 365: Mailbox accessed by non-owner"
  },
  "data": {
    "office365": {
      "Workload": "Exchange",
      "Operation": "MailboxLogin",
      "UserId": "admin@company.com",
      "MailboxOwnerUPN": "ceo@company.com",
      "ClientIP": "10.0.1.50",
      "LogonType": 1,
      "ResultStatus": "Succeeded"
    }
  }
}

DLP Policy Violation

{
  "rule": {
    "id": "91560",
    "level": 10,
    "description": "Office 365: DLP policy violation detected"
  },
  "data": {
    "office365": {
      "Workload": "Exchange",
      "Operation": "DlpRuleMatch",
      "UserId": "user@company.com",
      "PolicyDetails": [{
        "PolicyName": "Credit Card Number Detection",
        "Rules": [{
          "RuleName": "Block external sharing of credit cards",
          "Severity": "High",
          "ConditionsMatched": {
            "SensitiveInformation": [{
              "SensitiveInformationTypeName": "Credit Card Number",
              "Count": 3
            }]
          }
        }]
      }]
    }
  }
}

Administrative Action

{
  "rule": {
    "id": "91570",
    "level": 8,
    "description": "Office 365: Admin role assigned to user"
  },
  "data": {
    "office365": {
      "Workload": "AzureActiveDirectory",
      "Operation": "Add member to role",
      "UserId": "globaladmin@company.com",
      "ObjectId": "user@company.com",
      "ModifiedProperties": [{
        "Name": "Role.DisplayName",
        "NewValue": "Global Administrator"
      }]
    }
  }
}

Use Cases

Detecting Suspicious Sign-Ins

  • Multiple failed login attempts (brute force)
  • Sign-ins from geographically distant locations within a short period (impossible travel)
  • Sign-ins from anonymous IP addresses
  • Successful login following a series of failures (password spraying)

Monitoring Mailbox Access

  • Delegate access to another user’s mailbox
  • Creation of mail forwarding rules to external addresses
  • Bulk message deletion
  • Calendar permission changes

Detecting DLP Violations

  • Sending documents containing credit card numbers
  • Forwarding files with personal data to external addresses
  • Uploading sensitive documents to SharePoint with open access
  • Detection of sensitive data patterns in Teams

Monitoring Administrative Actions

  • Assignment of privileged roles (Global Admin, Exchange Admin)
  • Modification of conditional access policies
  • Creation or modification of Exchange transport rules
  • Disabling audit logging or multi-factor authentication

Troubleshooting

Module Not Receiving Events

  • Verify that tenant_id, client_id, and client_secret are correct
  • Confirm that ActivityFeed.Read and ActivityFeed.ReadDlp permissions are assigned
  • Check that admin consent has been granted
  • Allow up to 24 hours after initial activation, as the API may need time to prepare subscriptions

Authentication Error

  • Verify the client secret has not expired
  • Confirm that api_type matches your subscription (commercial, gcc, gcc-high)
  • Check that the application is not blocked in Azure AD
  • Review /var/ossec/logs/ossec.log for HTTP 401/403 errors

Empty API Responses

  • Confirm that auditing is enabled in the Microsoft 365 admin center
  • Verify that subscriptions for the required content types are active
  • For the initial run, set only_future_events to no to retrieve historical data
  • Check that the tenant has activity for the requested period

High Event Volume

  • Limit subscriptions to only the required content types
  • Increase the interval value to reduce polling frequency
  • Create Wazuh rules to filter noisy events
  • Use curl_max_size to limit the data volume per request

Related Sections

Last updated on