POST 19: Microsoft Sentinel KQL Detection Rules for .NET — Brute Force, Anomaly Detection & App Insights
Post 19 of 45 · Phase 3: Storage and Observability (final post) · 23 min read · No Azure subscription required · Paid early access
Post 18 covered the universal KQL operators — the pipe chain, time functions, aggregation, and rendering — that work identically in Application Insights, Azure Monitor, ADX, and Sentinel.
Post 19 covers what makes KQL unique: the operators with no SQL equivalent. make-series converts a tabular result into a time-series array. series_decompose_anomalies runs a machine-learning decomposition against that array and returns which points are statistically anomalous. mv-expand explodes array columns back into rows so you can filter on the anomaly scores. And workspace() lets a single query span multiple Log Analytics workspaces — the multi-region observability join.
Post 19 also covers Sentinel detection rules — the KQL queries that run on a schedule and create Incidents when their results are non-empty. The five rules in docs/sentinel-detection-rules.md cover brute-force login detection, anomalous order volume, DLQ accumulation, elevated DeliveryCount, and Polly retry storm proximity. All five have App Insights equivalents testable against real series telemetry without a Sentinel licence.
/users/login-failed is added to UserService — a new endpoint that generates failed login records for the brute-force detection exercise. Call it 10 times in rapid succession; the KQL rule returns the IP and user count that triggered the threshold.
Career skill this post adds:
make-series+series_decompose_anomalies— the KQL pattern that appears in advanced Azure Monitor alert rules and Sentinel hunting queries. Sentinel SIEM KQL authoring appears on Azure security engineer and senior architect job specifications. The detection rule pattern — “query on a schedule, alert if rows returned” — is the same structure used in every enterprise SIEM including Splunk, Elastic SIEM, and IBM QRadar. Learning it in Sentinel transfers across products.
make-series— converting tabular counts into a time-series arrayseries_decompose_anomalies— ML anomaly detection in one function callmv-expand— exploding array results back into filterable rowsworkspace()andcluster()— cross-workspace and cross-cluster queriesSentinel detection rules — the “query on schedule → alert if non-empty” pattern
System state: where we are
Phase 3 is complete after Post 19. The documentation set (docs/) now contains:
telemetry-schema.md— the OTel attribute contractstorage-decision.md— 5-service decision frameworkblob-lifecycle-policy.json— 4 lifecycle rules for Azurite containerskql-queries.md— 12+ production App Insights querieskql-operators-reference.md— operator quick referencesentinel-detection-rules.md— 5 Sentinel/App Insights detection rules ← Post 19
Starting point:
git checkout post/19-kql-advancedRun.\verify.ps1— all 41 Post 1–18 checks must pass. Run/users/login-failed10 times to generate exercise data before starting the brute-force rule exercise



