↳ GitHub sourceAnalytics ruleMedium

Azure DevOps Service Connection Abuse

Description

'Flags builds/releases that use a large number of service connections if they aren't manually in the allow list. This is to determine if someone is hijacking a build/release and adding many service connections in order to abuse or dump credentials from service connections.'
Rule type
Scheduled
Version
1.0.6
Declared status
Available
Query frequency
1d
Query period
14d
Trigger
gt 0

Declared MITRE coverage

KQL query

Original query, unchanged.

// How many greater than Service Connections you want to view per build/release
let ServiceConnectionThreshold = 4;
let BypassDefIds = datatable(DefId:string, Type:string, ProjectName:string)
[
//"103", "Release", "ProjectA",
//"42", "Release", "ProjectB",
//"122", "Build", "ProjectB"
];
ADOAuditLogs
| where OperationName == "Library.ServiceConnectionExecuted"
| extend DefId = tostring(Data.DefinitionId), Type = tostring(Data.PlanType), ConnectionId = tostring(Data.ConnectionId)
| parse ScopeDisplayName with OrganizationName ' (Organization)'
| summarize CurrentCount = dcount(tostring(ConnectionId)), ConnectionNames = make_set(tostring(Data.ConnectionName)), StartTime = min(TimeGenerated), EndTime = max(TimeGenerated)
  by OrganizationName, tostring(DefId), tostring(Type), ProjectId, ProjectName, ActorUPN, IpAddress
| where CurrentCount > ServiceConnectionThreshold
| join kind=anti BypassDefIds on $left.DefId==$right.DefId and $left.Type == $right.Type and $left.ProjectName == $right.ProjectName
| extend link = iif(
  Type == "Build", strcat('https://dev.azure.com/', OrganizationName, '/', ProjectName, '/_build?definitionId=', DefId),
  strcat('https://dev.azure.com/', OrganizationName, '/', ProjectName, '/_release?_a=releases&view=mine&definitionId=', DefId))
| extend timestamp = StartTime
| extend AccountName = tostring(split(ActorUPN, "@")[0]), AccountUPNSuffix = tostring(split(ActorUPN, "@")[1])

Declared entities

AccountIP

Related content

Links established from declared identifiers and solution manifests.

Source provenance

GitHub

Displayed values come from files in Azure/Azure-Sentinel. They describe the published template, not your workspace configuration.

Source identifier
d564ff12-8f53-41b8-8649-44f76b37b99f
Additional source files 3Solutions/AzureDevOpsAuditing/Analytic Rules/AzDOServiceConnectionUsage.yamlsource ↗Detections/AzureDevOpsAuditing/AzDOServiceConnectionUsage.yamlmigration-note ↗Solutions/AzureDevOpsAuditing/Data/Solution_AzureDevOpsAuditing.jsonsolution-membership ↗
GSTEP / CATALOG TRACKING

Added to catalog : 16 Sept 2026 · 05:49 UTC
Last change observed : 16 Sept 2026 · 05:49 UTC

GSTEP sync dates, separate from the source content’s publication dates.