I originally published this article on the Microsoft Tech Community.
Microsoft Sentinel’s capability can be greatly enhanced by integrating third-party threat intelligence (TI) feeds (e.g. GreyNoise, Team Cymru) with identity and access logs (e.g. OneLogin, PingOne). This article dives into each connector, its data types, and best practices for enrichment and false-positive reduction. We cover how GreyNoise (including PureSignal/Scout), Team Cymru, OneLogin IAM, PingOne, and Keeper integrate with Sentinel — available connectors, ingested schemas, and configuration — then outline patterns for TI lookup pipelines, scoring, and suppression rules that filter benign noise (e.g. GreyNoise’s known scanners) and enrich alerts with identity context. We map attack chains (credential stuffing, lateral movement, account takeover) to Sentinel data, and propose KQL analytics rules and playbooks with MITRE ATT&CK mappings (e.g. T1110: Brute Force, T1595: Active Scanning).

Threat intel & identity connectors overview
GreyNoise (TI feed). GreyNoise provides “internet background noise” intelligence on IPs seen scanning or probing the internet. The Sentinel GreyNoise Threat Intelligence connector pulls data via GreyNoise’s API into Sentinel’s ThreatIntelligenceIndicator table, using a daily Azure Function to fetch indicators (IP addresses and metadata like classification, noise, last_seen) as STIX-format indicators. Authentication requires a GreyNoise API key and a Sentinel workspace app with Contributor rights. The latest GreyNoise record per IP:
ThreatIntelligenceIndicator
| where IndicatorProvider == "GreyNoise"
| summarize arg_max(TimeGenerated, *) by NetworkDestinationIP
Team Cymru Scout (TI context). Team Cymru’s PureSignal Scout ingests contextual data (not raw logs) about IPs, domains, and account usage into Sentinel custom tables via an Azure Function. An IP query populates tables like Cymru_Scout_IP_Data_Foundation_CL, ..._OpenPorts_CL, ..._PDNS_CL, containing open ports, passive DNS history, X.509 cert info, and fingerprint data. There’s no native indicator insertion; analysts query these tables to enrich events (e.g. join on SourceIP). Requires a Team Cymru account.
OneLogin IAM (identity logs). The OneLogin IAM solution ingests platform events and user info via OneLogin’s REST API (using the Codeless Connector Framework), storing data in OneLoginEventsV2_CL and OneLoginUsersV2_CL. Typical events: sign-ins, MFA actions, app accesses, admin changes. Create an OpenID Connect app in OneLogin and register it in Azure. The connector polls hourly, within OneLogin’s 5,000 calls/hour limit. Failed logins, for example:
OneLoginEventsV2_CL
| where Event_type_s == "UserSessionStart" and Result_s == "Failed"
PingOne (identity logs). The PingOne Audit connector ingests audit activity via REST API into PingOne_AuditActivitiesV2_CL — admin actions, user logins, console events. Configure a PingOne API client (Client ID/Secret) and the CCF, minding license-based rate limits.
Keeper (password-vault logs, optional). Keeper forwards security events to Sentinel via Azure Monitor into a custom table (commonly KeeperLogs_CL) using Data Collection Rules. Register an Azure AD app (“KeeperLogging”), configure Azure Monitor data collection, then set the DCR endpoint in Keeper’s Admin Console. This is a bulk push rather than a scheduled pull.
Connector configuration & data ingestion
- Auth & rate limits: GreyNoise and Team Cymru use single keys/credentials with the Azure Function secured by a managed identity. OneLogin (~5k calls/hour) and PingOne (license-dependent) use client ID/secret. GreyNoise’s community API is limited (10/day free), so production needs an Enterprise plan.
- Sentinel tables: GreyNoise →
ThreatIntelligenceIndicator; Team Cymru → manyCymru_Scout_*_CL; OneLogin →OneLoginEventsV2_CL,OneLoginUsersV2_CL; PingOne →PingOne_AuditActivitiesV2_CL; Keeper →KeeperLogs_CL. Built-in identity tables (IdentityInfo,SigninLogs) are for Microsoft identities; third-party logs arrive in custom tables and can be mapped via parsers.
To enrich a Sentinel event with these feeds — for example, join OneLogin sign-ins with GreyNoise’s list of malicious scanners:
OneLoginEventsV2_CL
| where EventType == "UserLogin" and Result == "Success"
| extend UserIP = ClientIP_s
| join kind=inner (
ThreatIntelligenceIndicator
| where IndicatorProvider == "GreyNoise" and ThreatSeverity >= 3
| project NetworkDestinationIP, Category
) on $left.UserIP == $right.NetworkDestinationIP
Enrichment & false-positive reduction
A robust TI pipeline often uses lookup tables and functions. Key patterns: normalization (map diverse feeds to common STIX fields so rules treat them uniformly), confidence scoring (per vendor or based on recency/frequency), TTL & freshness (use ExpirationDateTime/ValidUntil to avoid stale IOCs), and conflict resolution (when the same IOC comes from multiple sources, merge metadata or take the highest confidence).
False-positive reduction techniques:
- GreyNoise noise scoring — if an IP is labeled
noise=true(just scanning, not actively malicious), deprioritize alerts involving it. - Team Cymru reputation — use Scout context (open-port fingerprints, domain history) to gauge risk and refine a binary IOC.
- Contextual identity signals — combine OneLogin/PingOne context (new country, failed logins across users) with TI to filter or escalate.
- Thresholding & suppression — e.g. only alert on >5 failed logins in 5 min from an IP that is not a known-benign scanner.
Suppress Windows 4625 login failures originating from GreyNoise-known benign scanners:
SecurityEvent
| where EventID == 4625 and Account != "SYSTEM"
| join kind=leftanti (
ThreatIntelligenceIndicator
| where IndicatorProvider == "GreyNoise" and Classification == "benign"
| project NetworkSourceIP
) on $left.IPAddress == $right.NetworkSourceIP
Identity attack chains & detection ideas
- Credential stuffing (T1110) — many login failures followed by a success from a single IP; enrich with GreyNoise to raise severity if the source IP is a known scanner.
- Account takeover / impossible travel (T1198) — sign-ins from distant geographies within a short window; enrich with Team Cymru PDNS.
- Lateral movement (T1021) — the same account authenticating to multiple apps in a short time, then suspicious network activity.
- Privilege escalation (T1098) — admin account changes or MFA resets after an anomalous login; cross-check the actor’s IP against threat feeds.
Credential-stuffing chain (OneLogin + GreyNoise):
let SuspiciousIP =
OneLoginEventsV2_CL
| where EventType == "UserSessionStart" and Result == "Failed"
| summarize CountFailed=count() by ClientIP_s
| where CountFailed > 5;
OneLoginEventsV2_CL
| where EventType == "UserSessionStart" and Result == "Success"
and ClientIP_s in (SuspiciousIP | project ClientIP_s)
| join kind=inner (
ThreatIntelligenceIndicator
| where ThreatType == "ip"
| extend GreyNoiseClass = tostring(Classification)
| project IP=NetworkSourceIP, GreyNoiseClass
) on $left.ClientIP_s == $right.IP
| where GreyNoiseClass == "malicious"
| project TimeGenerated, Account_s, ClientIP_s, GreyNoiseClass
Analytics rules (KQL)
Six illustrative rules combining TI and identity logs. Adjust field names per your schemas and normalize custom tables as needed.
1. Multiple failed logins from a malicious scanner (T1110) — High. Credential stuffing: >5 failed attempts from an IP GreyNoise classifies as malicious.
let BadIP =
OneLoginEventsV2_CL
| where EventType == "UserSessionStart" and Result == "Failed"
| summarize attempts=count() by SourceIP_s
| where attempts >= 5;
OneLoginEventsV2_CL
| where EventType == "UserSessionStart" and Result == "Success"
and SourceIP_s in (BadIP | project SourceIP_s)
| join (
ThreatIntelligenceIndicator
| where IndicatorProvider == "GreyNoise" and ThreatSeverity >= 4
| project MaliciousIP=NetworkDestinationIP
) on $left.SourceIP_s == $right.MaliciousIP
| extend AttackFlow="CredentialStuffing", MITRE="T1110"
| project TimeGenerated, UserName_s, SourceIP_s, MaliciousIP
2. Impossible travel / anomalous geo (T1198) — Medium. A user signs in from two distant locations within an hour.
let lastLogins =
PingOne_AuditActivitiesV2_CL
| where EventType_s == "UserLogin" and Outcome_s == "Success"
| sort by TimeGenerated desc
| summarize first_place=arg_max(TimeGenerated, City_s, Country_s, SourceIP_s, TimeGenerated) by User_s;
let prevLogins =
PingOne_AuditActivitiesV2_CL
| where EventType_s == "UserLogin" and Outcome_s == "Success"
| sort by TimeGenerated desc
| summarize last_place=arg_min(TimeGenerated, City_s, Country_s, SourceIP_s, TimeGenerated) by User_s;
lastLogins
| join kind=inner prevLogins on User_s
| extend dist=geo_distance_2points(first_place_City_s, first_place_Country_s, last_place_City_s, last_place_Country_s)
| where dist > 1000 and (first_place_TimeGenerated - last_place_TimeGenerated) < 1h
| project Time=first_place_TimeGenerated, User=User_s, From=last_place_Country_s, To=first_place_Country_s, MITRE="T1198"
3. Suspicious admin change (T1098) — High. An admin action (role assign, MFA reset) via PingOne from a high-risk IP.
PingOne_AuditActivitiesV2_CL
| where EventType_s in ("UserMFAReset", "UserRoleChange")
| extend ActorIP = tostring(InitiatingIP_s)
| join (
ThreatIntelligenceIndicator
| where ThreatSeverity >= 3
| project BadIP=NetworkDestinationIP
) on $left.ActorIP == $right.BadIP
| extend MITRE="T1098"
| project TimeGenerated, ActorUser_s, Action=EventType_s, ActorIP
4. Malicious domain access (T1498) — Medium. Internal DNS queries to a domain Team Cymru Scout flags as C2.
DeviceDnsEvents
| where QueryType == "A"
| join kind=inner (
Cymru_Scout_Domain_Data_CL
| where ThreatTag_s == "Command-and-Control"
| project DomainName_s
) on $left.QueryText == $right.DomainName_s
| extend MITRE="T1498"
| project TimeGenerated, DeviceName, QueryText
5. Brute-force blocked IP (T1110) — Low–Medium. Many inbound denies from an IP not whitelisted by GreyNoise.
AzureDiagnostics
| where Category == "NetworkSecurityGroupFlowEvent" and msg_s contains "DIRECTION=Inbound" and Action_s == "Deny"
| summarize attemptCount=count() by IP = SourceIp_s, FlowTime=bin(TimeGenerated, 1h)
| where attemptCount > 50
| join kind=leftanti (
ThreatIntelligenceIndicator
| where IndicatorProvider == "GreyNoise" and Classification == "benign"
| project NoiseIP=NetworkDestinationIP
) on $left.IP == $right.NoiseIP
| extend MITRE="T1110"
| project IP, attemptCount, FlowTime
6. New device enrolled (T1078) — Low. A new device/location enrolled for MFA after an unusual login.
OneLoginEventsV2_CL
| where EventType == "NewDeviceEnrollment"
| join kind=inner (
OneLoginEventsV2_CL
| where EventType == "UserSessionStart" and Result == "Success"
| top 1 by TimeGenerated asc
| project User_s, loginTime=TimeGenerated, loginIP=ClientIP_s
) on User_s
| where loginIP != DeviceIP_s
| extend MITRE="T1078"
| project TimeGenerated, User_s, DeviceIP_s, loginIP
Tune thresholds and map event fields to your actual schema; tag rules with MITRE IDs for context.
TI-driven playbooks and automation
- IOC blocking: on alert, a runbook calls Azure Firewall/Defender or an external firewall API to block the offending IP.
- Enrichment workflow: a Logic App queries GreyNoise/Team Cymru in real time for an alert’s IP and tags the incident with the classification.
- Alert suppression: a playbook checks GreyNoise; if the IP is benign, auto-close or mark false-positive.
- Automated TI feed updates: periodically push new indicators into Sentinel’s TI store via the Graph API.
- Incident enrichment: query OneLogin/PingOne for user details (department, location) and add them as a note.
Performance, scalability & cost
Every log and TI indicator is billable by the GB. Use DCRs to apply ingestion-time filters (only store indicators above a confidence threshold). Archive or purge old custom-log data; use materialized views or summary tables for heavy queries. Configure retention per table, and for very large TI volumes consider the Sentinel Data Lake to offload raw ingest cheaply. Schedule connectors to respect API rate limits (daily for TI, hourly for identity), and monitor the Functions running GreyNoise/Scout for failures or throttling.
Connector comparison
| Connector | Data sources | Sentinel tables | Update freq. | Auth | Limits/cost | Notes |
|---|---|---|---|---|---|---|
| GreyNoise | IP intelligence (scanners) | ThreatIntelligenceIndicator |
Daily pull | API key | Paid license for large usage | Filters benign scans; IP-only (no domain/file). |
| Team Cymru Scout | Global IP/domain telemetry | Cymru_Scout_*_CL |
On-demand/daily | Account creds | Subscription; potentially high cost | Rich context (ports, PDNS, certs); custom tables only. |
| OneLogin IAM | OneLogin user/auth logs | OneLoginEventsV2_CL, OneLoginUsersV2_CL |
Hourly poll | OAuth2 | 5K calls/hour | Direct cloud-identity insight; OneLogin-only. |
| PingOne Audit | PingOne audit logs | PingOne_AuditActivitiesV2_CL |
Hourly poll | OAuth2 | Ping license rate limits | Critical identity events; needs Advanced license. |
| Keeper (custom) | Keeper security events | KeeperLogs_CL |
Push | OAuth2 + Azure DCR | Storage cost | Password-vault visibility; manual setup, unparsed by default. |
Data flow

GreyNoise feeds the Threat Intelligence table, Team Cymru feeds enrichment tables, and identity sources push logs. All data converges into Sentinel, where enrichment lookups inform analytics and automated responses.