Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
{
"name": "CloudflareSecurityEventsDefinition",
"apiVersion": "2025-07-01-preview",
"type": "Microsoft.SecurityInsights/dataConnectorDefinitions",
"location": "{{location}}",
"kind": "Customizable",
"properties": {
"connectorUiConfig": {
"id": "CloudflareSecurityEventsDefinition",
"title": "Cloudflare Security Events (via Codeless Connector Framework)",
"publisher": "Cloudflare",
"descriptionMarkdown": "The [Cloudflare](https://www.cloudflare.com/) Security Events connector ingests Cloudflare [security events](https://developers.cloudflare.com/waf/analytics/security-events/) into Microsoft Sentinel using the Cloudflare [GraphQL Analytics API](https://developers.cloudflare.com/analytics/graphql-api/) (the `firewallEventsAdaptive` dataset, queried at account scope).\n\nSecurity events capture requests acted on by Cloudflare security products, including the WAF managed and custom rulesets, rate limiting, L7 DDoS mitigation, IP reputation, and bot mitigations.\n\n**Underlying Microsoft Technologies used:**\n\nThis solution takes a dependency on the following technologies, and some of these dependencies either may be in Preview state or might result in additional ingestion or operational costs:\n\na. [Codeless Connector Framework (CCF)](https://learn.microsoft.com/en-us/azure/sentinel/create-custom-connector)",
"graphQueriesTableName": "CloudflareSecurityEvents_CL",
"graphQueries": [
{
"metricName": "Total events received",
"legend": "Cloudflare Security Events",
"baseQuery": "{{graphQueriesTableName}}"
}
],
"sampleQueries": [
{
"description": "Get sample Cloudflare Security Events",
"query": "{{graphQueriesTableName}}\n | take 10"
},
{
"description": "Cloudflare Security Events by action",
"query": "{{graphQueriesTableName}}\n | summarize count() by Action"
},
{
"description": "Top client IPs blocked by the Cloudflare WAF",
"query": "{{graphQueriesTableName}}\n | where Action == 'block'\n | summarize count() by ClientIP\n | top 10 by count_"
}
],
"dataTypes": [
{
"name": "CloudflareSecurityEvents_CL",
"lastDataReceivedQuery": "{{graphQueriesTableName}}\n | where TimeGenerated > ago(12h) | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
}
],
"connectivityCriteria": [
{
"type": "HasDataConnectors"
}
],
"availability": {
"isPreview": true,
"status": 1
},
"permissions": {
"resourceProvider": [
{
"provider": "Microsoft.OperationalInsights/workspaces",
"permissionsDisplayText": "Read and Write permissions are required.",
"providerDisplayName": "Workspace",
"scope": "Workspace",
"requiredPermissions": {
"read": true,
"write": true,
"delete": true,
"action": false
}
}
],
"customs": [
{
"name": "Cloudflare Account API token",
"description": "A Cloudflare Account API token with **Account Analytics > Read** permission is required to query the GraphQL Analytics API. Refer to the [Cloudflare documentation](https://developers.cloudflare.com/fundamentals/api/get-started/account-owned-tokens/) for instructions on creating an account-owned API token."
},
{
"name": "Cloudflare Account ID",
"description": "Your Cloudflare Account ID is available in the Cloudflare dashboard URL or under **Account Home > Overview**. Refer to the [Cloudflare documentation](https://developers.cloudflare.com/fundamentals/setup/find-account-and-zone-ids/) for instructions."
}
]
},
"instructionSteps": [
{
"title": "Connect Cloudflare Security Events to Microsoft Sentinel",
"description": "To enable ingestion of Cloudflare security events, provide your Cloudflare Account ID and Cloudflare Account API token below, then select **Connect**.\n\n> **Note:** Ensure your API token has the **Account Analytics > Read** permission scope. Security events are collected across all zones in the account.",
"instructions": [
{
"type": "Textbox",
"parameters": {
"label": "Cloudflare Account ID",
"placeholder": "Enter your Cloudflare Account ID (e.g. 9a7806061c88ada191ed06f989cc3dac)",
"type": "text",
"name": "accountId",
"validations": {
"required": true
}
}
},
{
"type": "Textbox",
"parameters": {
"label": "Cloudflare Account API token",
"placeholder": "Enter your Cloudflare Account API token",
"type": "password",
"name": "apikey",
"validations": {
"required": true
}
}
},
{
"type": "ConnectionToggleButton",
"parameters": {
"connectLabel": "Connect",
"name": "Connect"
}
}
]
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
[
{
"name": "CloudflareSecurityEventsDCR",
"apiVersion": "2023-04-01-preview",
"type": "Microsoft.Insights/dataCollectionRules",
"location": "{{location}}",
"properties": {
"dataCollectionEndpointId": "{{dataCollectionEndpointId}}",
"streamDeclarations": {
"Custom-CloudflareSecurityEvents_CL": {
"columns": [
{
"name": "TimeGenerated",
"type": "datetime"
},
{
"name": "Action",
"type": "string"
},
{
"name": "Source",
"type": "string"
},
{
"name": "Kind",
"type": "string"
},
{
"name": "Description",
"type": "string"
},
{
"name": "Ref",
"type": "string"
},
{
"name": "RuleId",
"type": "string"
},
{
"name": "RulesetId",
"type": "string"
},
{
"name": "MatchIndex",
"type": "int"
},
{
"name": "RayName",
"type": "string"
},
{
"name": "OriginatorRayName",
"type": "string"
},
{
"name": "SampleInterval",
"type": "int"
},
{
"name": "ClientIP",
"type": "string"
},
{
"name": "ClientIPClass",
"type": "string"
},
{
"name": "ClientAsn",
"type": "string"
},
{
"name": "ClientASNDescription",
"type": "string"
},
{
"name": "ClientCountryName",
"type": "string"
},
{
"name": "ClientRequestHTTPHost",
"type": "string"
},
{
"name": "ClientRequestHTTPMethodName",
"type": "string"
},
{
"name": "ClientRequestHTTPProtocol",
"type": "string"
},
{
"name": "ClientRequestPath",
"type": "string"
},
{
"name": "ClientRequestQuery",
"type": "string"
},
{
"name": "ClientRequestScheme",
"type": "string"
},
{
"name": "ClientRefererHost",
"type": "string"
},
{
"name": "ClientRefererPath",
"type": "string"
},
{
"name": "ClientRefererQuery",
"type": "string"
},
{
"name": "ClientRefererScheme",
"type": "string"
},
{
"name": "UserAgent",
"type": "string"
},
{
"name": "EdgeColoName",
"type": "string"
},
{
"name": "EdgeResponseStatus",
"type": "int"
},
{
"name": "OriginResponseStatus",
"type": "int"
},
{
"name": "HttpApplicationVersion",
"type": "long"
},
{
"name": "ZoneTag",
"type": "string"
},
{
"name": "ZoneVersion",
"type": "long"
}
]
}
},
"destinations": {
"logAnalytics": [
{
"workspaceResourceId": "{{workspaceResourceId}}",
"name": "clv2ws1"
}
]
},
"dataFlows": [
{
"streams": [
"Custom-CloudflareSecurityEvents_CL"
],
"destinations": [
"clv2ws1"
],
"transformKql": "source",
"outputStream": "Custom-CloudflareSecurityEvents_CL"
}
]
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[
{
"name": "CloudflareSecurityEventsPoller",
"apiVersion": "2025-03-01",
"type": "Microsoft.SecurityInsights/dataConnectors",
"location": "{{location}}",
"kind": "RestApiPoller",
"properties": {
"connectorDefinitionName": "CloudflareSecurityEventsDefinition",
"dataType": "CloudflareSecurityEvents_CL",
"dcrConfig": {
"streamName": "Custom-CloudflareSecurityEvents_CL",
"dataCollectionEndpoint": "{{dataCollectionEndpoint}}",
"dataCollectionRuleImmutableId": "{{dataCollectionRuleImmutableId}}"
},
"auth": {
"type": "APIKey",
"ApiKey": "[[parameters('apikey')]",
"ApiKeyName": "Authorization",
"ApiKeyIdentifier": "Bearer"
},
"request": {
"apiEndpoint": "https://api.cloudflare.com/client/v4/graphql",
"httpMethod": "POST",
"queryWindowInMin": 10,
"queryTimeFormat": "yyyy-MM-ddTHH:mm:ssZ",
"rateLimitQPS": 5,
"retryCount": 3,
"timeoutInSeconds": 60,
"headers": {
"Accept": "application/json",
"Content-Type": "application/json",
"User-Agent": "Scuba"
},
"isPostPayloadJson": true,
"queryParametersTemplate": "[[concat('{\"query\":\"{ viewer { accounts(filter: {accountTag: \\\"', parameters('accountId'), '\\\"}) { firewallEventsAdaptive(filter: {datetime_geq: \\\"{_QueryWindowStartTime}\\\", datetime_leq: \\\"{_QueryWindowEndTime}\\\"}, limit: 10000, orderBy: [datetime_ASC]) { TimeGenerated: datetime, Action: action, Source: source, Kind: kind, Description: description, Ref: ref, RuleId: ruleId, RulesetId: rulesetId, MatchIndex: matchIndex, RayName: rayName, OriginatorRayName: originatorRayName, SampleInterval: sampleInterval, ClientIP: clientIP, ClientIPClass: clientIPClass, ClientAsn: clientAsn, ClientASNDescription: clientASNDescription, ClientCountryName: clientCountryName, ClientRequestHTTPHost: clientRequestHTTPHost, ClientRequestHTTPMethodName: clientRequestHTTPMethodName, ClientRequestHTTPProtocol: clientRequestHTTPProtocol, ClientRequestPath: clientRequestPath, ClientRequestQuery: clientRequestQuery, ClientRequestScheme: clientRequestScheme, ClientRefererHost: clientRefererHost, ClientRefererPath: clientRefererPath, ClientRefererQuery: clientRefererQuery, ClientRefererScheme: clientRefererScheme, UserAgent: userAgent, EdgeColoName: edgeColoName, EdgeResponseStatus: edgeResponseStatus, OriginResponseStatus: originResponseStatus, HttpApplicationVersion: httpApplicationVersion, ZoneTag: zoneTag, ZoneVersion: zoneVersion } } } }\"}')]"
},
"response": {
"eventsJsonPaths": [
"$.data.viewer.accounts[0].firewallEventsAdaptive"
],
"format": "json"
}
}
}
]
Loading
Loading