Detection rules › Kusto
GitLab - SSO - Sign-Ins Burst
'This query relies on Microsoft Entra ID sign-in activity when Microsoft Entra ID is used for SSO with GitLab to highlights GitLab accounts associated with multiple authentications from different geographical locations in a short space of time.'
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Credential Access | T1110 Brute Force |
Rules detecting the same action
Other rules on this platform that filter on the same API call or operation.
- Anomalous sign-in location by user account and authenticating application (Kusto)
- Anomalous Single Factor Signin (Kusto)
- Authentications of Privileged Accounts Outside of Expected Controls (Kusto)
- Azure Many Failed SignIns (Panther)
- Azure Portal sign in from another Azure Tenant (Kusto)
- Azure Service Principal Sign-In Followed by Arc Cluster Credential Access (Elastic)
- Azure SignIn via Legacy Authentication Protocol (Panther)
- Detect non-admin requesting token for admin applications (Kusto)
Rule body kusto
id: 57b1634b-531d-4eab-a456-8b855887428f
name: GitLab - SSO - Sign-Ins Burst
description: |
'This query relies on Microsoft Entra ID sign-in activity when Microsoft Entra ID is used for SSO with GitLab to highlights GitLab accounts associated with multiple authentications from different geographical locations in a short space of time.'
severity: Medium
status: Available
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- SigninLogs
queryFrequency: 1h
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
relevantTechniques:
- T1110
query: |
let locationCountMin = 1;
let appRegistrationName = "GitLab";
SigninLogs
| where AppDisplayName == appRegistrationName
| where ResultType == 0
| where Location != ""
| summarize CountOfLocations = dcount(Location), Locations = make_set(Location) by User = Identity
| where CountOfLocations > locationCountMin
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: User
version: 1.0.1
kind: Scheduled
Stages and Predicates
Parameters
let locationCountMin = 1;
let appRegistrationName = "GitLab";
Stage 1: source
SigninLogs
Stage 2: where
| where AppDisplayName == appRegistrationName
Stage 3: where
| where ResultType == 0
Stage 4: where
| where Location != ""
Stage 5: summarize
| summarize CountOfLocations = dcount(Location), Locations = make_set(Location) by User = Identity
Stage 6: where
| where CountOfLocations > locationCountMin
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
AppDisplayName | eq |
|
CountOfLocations | gt |
|
ResultType | eq |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
CountOfLocations | summarize |
Locations | summarize |
User | summarize |