Microsoft 365 Activity Logs with Cribl Stream

Tenant activity into the pipeline, configured per the source page.

What the source collects

The Microsoft 365 Activity Source page says Cribl Stream supports receiving data from the Office 365 Management Activity API, facilitating "analyzing actions and events on Microsoft Entra ID, Exchange, and SharePoint, along with global auditing and Data Loss Prevention data." Its summary marks the source as Pull type, notes TLS is supported over HTTPS, and lists Event Breaker support.

Polling is configured independently per content type; the page lists these types of audit data:

Each enabled content type gets its own separate scheduled job. Per the page, the Source retrieves data via Cribl Stream scheduled Collection jobs, which include Discover and Collection phases, and the Discover phase task returns the URL of the content to collect.

Setting up the source

The source page prerequisites name a registered application with the Microsoft identity platform. You take the Application (client) ID, Directory (tenant) ID, and credentials from it into the Cribl Stream Source; the page links Cribl's Knowledge Base article, Microsoft 365 App Registration for Cribl Sources, for the registration walkthrough. The application representing your Cribl Stream instance needs two Microsoft application permissions: ActivityFeed.Read, required for all Content Types except DLP.All, and ActivityFeed.ReadDlp, required for the DLP.All Content Type. The permission Type for both must be Application; Delegated is not sufficient.

You reach the Source in Cribl Stream via QuickConnect (Routing, QuickConnect, Add Source) or Routes (Data, Sources, Add Source). The New Source modal's General Settings include:

Under Authentication, the Authentication method dropdown offers:

Optional Settings cover:

In the Content Types table, the Interval Description column is informational only, and Interval optionally overrides the default polling interval. Cribl Stream uses the Interval value to establish the search date range and the cron schedule, so intervals in minutes must divide evenly into 60. The page names 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, and 60 as acceptable, and says it rejects intervals like 23, 42, 45, or 75. Each row also offers Log Level (debug, info the default, warn, error) and an Enabled toggle.

Processing defines new or modified fields with JavaScript expressions; the Value is the expression that computes it. Pre-Processing selects a single existing Pipeline or Pack to process this input's data before the Routes.

Retries exposes:

In Advanced:

Then select Save, then Commit & Deploy.

Finally, the page separates two "subscription" concepts. The Subscription Plan in General Settings names the Microsoft 365 plan your organization runs. Content subscriptions are different: the page says each Content Type needs its own, Cribl Stream does not support starting or stopping Microsoft 365 subscriptions, and they are required before Cribl Stream can begin retrieving O365 data. If your existing Azure-registered application ID already has subscriptions started, the page says to ignore this section; for a newly registered application ID, or one whose subscriptions are stopped, use its PowerShell or curl procedure.

The page's PowerShell script obtains a token, lists subscriptions, and posts a start request per Content Type, commenting the endpoint per plan: manage.office.com for Enterprise, manage-gcc.office.com for GCC, manage.office365.us for GCC High, manage.protection.apps.mil for DoD. The first curl command, copied from the Microsoft 365 Activity Source page, obtains an auth token:

curl -X POST "https://login.windows.net/<tenantId>/oauth2/token" \
-d "client_secret=<client secret>&resource=https://manage.office.com&client_id=<app id>&grant_type=client_credentials"

The second command, copied from the Microsoft 365 Activity Source page, uses the auth token from that response to start the subscription:

curl -X POST "https://manage.office.com/api/v1.0/<tenantId>/activity/feed/subscriptions/start?contentType=<content_type_name>" \
-H "Authorization: Bearer <token>" \
-d ""

Run the second command once per Content Type with the page's exact strings: Audit.AzureActiveDirectory, Audit.Exchange, Audit.SharePoint, Audit.General, DLP.All. Its example response is {"contentType":"Audit.AzureActiveDirectory","status":"enabled","webhook":null}; a stop operation produces no output.

What the docs flag

Timing is the first flag. The page is explicit that Microsoft 365 activity events are not delivered in real time and can be delayed by tens of minutes to several hours before becoming available to be collected; in some cases, delays of 24 hours or more have been observed. Those delays can make recent events appear missing in Cribl Stream and create event-count discrepancies versus tools such as Splunk or Microsoft-native views.

The compensation is the Ingestion lag (minutes) setting under Advanced Settings, which configures how far back the API should look for events to retrieve. Its default of 0 means don't look back; the page says that "in real environments often leads to missed events due to Microsoft's delays." The maximum value is 7200 minutes (120 hours). The page advises starting in the 90-360 minute range when it is important to avoid data loss, since many environments see 60-90 minute delays or longer, then tuning based on observed behavior. When the ingestion lag is longer than the delivery delay, events still fall within the time window; outside that window, a separate backfill process must query the affected historical time range. Larger values also increase the data the API returns and the chance of overlapping or duplicate events if you run multiple jobs.

The page also addresses stuck jobs. A scheduled job can fail yet keep running for hours or days, and a "stuck", "orphaned," or "zombie" job left alone will never complete, causing missing events downstream plus HTTP timeout or similar errors in logs. Its fix: first set Advanced > Timeout (secs) shorter than the default 300 seconds (5 minutes); if that does not fix it, set the global Job Timeout, whose default of 0 allows a job to run indefinitely.

Two narrower caveats:

Frequently asked questions

Which Microsoft permissions must the app registration have for the Cribl Stream Microsoft 365 Activity Source?

Two application permissions: ActivityFeed.Read, required for all Content Types except DLP.All, and ActivityFeed.ReadDlp, required for the DLP.All Content Type. The page states the permission Type for both must be Application, and that Delegated is not sufficient.

Can Cribl Stream start Microsoft 365 content subscriptions on its own?

No. Cribl Stream does not support starting or stopping Microsoft 365 subscriptions, and each Content Type needs its own subscription. You start them with the PowerShell or curl procedure the source page documents.

Why do recent Microsoft 365 events look missing in Cribl Stream?

Events are not delivered in real time: the page reports delays from tens of minutes to several hours, with 24 hours or more observed in some cases. The Ingestion lag (minutes) setting configures how far back the API looks; its default of zero means don't look back, which in real environments often leads to missed events due to Microsoft's delays.

What polling interval values does the Cribl Stream Microsoft 365 Activity Source accept?

Minutes values that divide evenly into 60, because the value establishes the cron schedule. The page names 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, and 60 as acceptable, and rejects intervals like 23, 42, or 45, or 75.

Source

Verified against Cribl Stream 4.20 documentation on August 20, 2026.