Microsoft Sentinel Analytic Rules
cloudbrothers.infoAzure Sentinel RepoToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage

Azure DevOps Administrator Group Monitoring

Back
Id89e6adbd-612c-4fbe-bc3d-32f81baf3b6c
RulenameAzure DevOps Administrator Group Monitoring
DescriptionThis detection monitors for additions to projects or project collection administration groups in an Azure DevOps Organization.
SeverityMedium
TacticsPersistence
TechniquesT1098
KindScheduled
Query frequency4h
Query period4h
Trigger threshold0
Trigger operatorgt
Source Urihttps://github.com/Azure/Azure-Sentinel/blob/master/Solutions/AzureDevOpsAuditing/Analytic Rules/AzDOAdminGroupAdditions.yaml
Version1.0.4
Arm template89e6adbd-612c-4fbe-bc3d-32f81baf3b6c.json
Deploy To Azure
// Change to true to monitor for Project Administrator adds to *any* project
let MonitorAllProjects = false;
// If MonitorAllProjects is false, trigger only on Project Administrator add for the following projects
let ProjectsToMonitor = dynamic(['<project_X>','<project_Y>']);
AzureDevOpsAuditing
| where Area == "Group" and OperationName == "Group.UpdateGroupMembership.Add"
| where Details has 'Administrators'
| where Details has "was added as a member of group" and (Details endswith '\\Project Administrators' or Details endswith '\\Project Collection Administrators')
| parse Details with AddedIdentity ' was added as a member of group [' EntityName ']\\' GroupName
| extend Level = iif(GroupName == 'Project Collection Administrators', 'Organization', 'Project'), AddedIdentityId = Data.MemberId
| extend Severity = iif(Level == 'Organization', 'High', 'Medium'), AlertDetails = strcat('At ', TimeGenerated, ' UTC ', ActorUPN, '/', ActorDisplayName, ' added ', AddedIdentity, ' to the ', EntityName, ' ', Level)
| where MonitorAllProjects == true or EntityName in (ProjectsToMonitor) or Level == 'Organization'
| project TimeGenerated, Severity, Adder = ActorUPN, AddedIdentity, AddedIdentityId, AlertDetails, Level, EntityName, GroupName, ActorAuthType = AuthenticationMechanism,
  ActorIpAddress = IpAddress, ActorUserAgent = UserAgent, RawDetails = Details
| extend timestamp = TimeGenerated
| extend AccountName = tostring(split(Adder, "@")[0]), AccountUPNSuffix = tostring(split(Adder, "@")[1])
relevantTechniques:
- T1098
name: Azure DevOps Administrator Group Monitoring
requiredDataConnectors: []
entityMappings:
- fieldMappings:
  - identifier: FullName
    columnName: Adder
  - identifier: Name
    columnName: AccountName
  - identifier: UPNSuffix
    columnName: AccountUPNSuffix
  entityType: Account
- fieldMappings:
  - identifier: Address
    columnName: ActorIpAddress
  entityType: IP
triggerThreshold: 0
id: 89e6adbd-612c-4fbe-bc3d-32f81baf3b6c
tactics:
- Persistence
version: 1.0.4
OriginalUri: https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/AzureDevOpsAuditing/Analytic Rules/AzDOAdminGroupAdditions.yaml
queryPeriod: 4h
kind: Scheduled
queryFrequency: 4h
severity: Medium
status: Available
description: |
    'This detection monitors for additions to projects or project collection administration groups in an Azure DevOps Organization.'
query: |
  // Change to true to monitor for Project Administrator adds to *any* project
  let MonitorAllProjects = false;
  // If MonitorAllProjects is false, trigger only on Project Administrator add for the following projects
  let ProjectsToMonitor = dynamic(['<project_X>','<project_Y>']);
  AzureDevOpsAuditing
  | where Area == "Group" and OperationName == "Group.UpdateGroupMembership.Add"
  | where Details has 'Administrators'
  | where Details has "was added as a member of group" and (Details endswith '\\Project Administrators' or Details endswith '\\Project Collection Administrators')
  | parse Details with AddedIdentity ' was added as a member of group [' EntityName ']\\' GroupName
  | extend Level = iif(GroupName == 'Project Collection Administrators', 'Organization', 'Project'), AddedIdentityId = Data.MemberId
  | extend Severity = iif(Level == 'Organization', 'High', 'Medium'), AlertDetails = strcat('At ', TimeGenerated, ' UTC ', ActorUPN, '/', ActorDisplayName, ' added ', AddedIdentity, ' to the ', EntityName, ' ', Level)
  | where MonitorAllProjects == true or EntityName in (ProjectsToMonitor) or Level == 'Organization'
  | project TimeGenerated, Severity, Adder = ActorUPN, AddedIdentity, AddedIdentityId, AlertDetails, Level, EntityName, GroupName, ActorAuthType = AuthenticationMechanism,
    ActorIpAddress = IpAddress, ActorUserAgent = UserAgent, RawDetails = Details
  | extend timestamp = TimeGenerated
  | extend AccountName = tostring(split(Adder, "@")[0]), AccountUPNSuffix = tostring(split(Adder, "@")[1])  
triggerOperator: gt
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "workspace": {
      "type": "String"
    }
  },
  "resources": [
    {
      "apiVersion": "2024-01-01-preview",
      "id": "[concat(resourceId('Microsoft.OperationalInsights/workspaces/providers', parameters('workspace'), 'Microsoft.SecurityInsights'),'/alertRules/89e6adbd-612c-4fbe-bc3d-32f81baf3b6c')]",
      "kind": "Scheduled",
      "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/89e6adbd-612c-4fbe-bc3d-32f81baf3b6c')]",
      "properties": {
        "alertRuleTemplateName": "89e6adbd-612c-4fbe-bc3d-32f81baf3b6c",
        "customDetails": null,
        "description": "'This detection monitors for additions to projects or project collection administration groups in an Azure DevOps Organization.'\n",
        "displayName": "Azure DevOps Administrator Group Monitoring",
        "enabled": true,
        "entityMappings": [
          {
            "entityType": "Account",
            "fieldMappings": [
              {
                "columnName": "Adder",
                "identifier": "FullName"
              },
              {
                "columnName": "AccountName",
                "identifier": "Name"
              },
              {
                "columnName": "AccountUPNSuffix",
                "identifier": "UPNSuffix"
              }
            ]
          },
          {
            "entityType": "IP",
            "fieldMappings": [
              {
                "columnName": "ActorIpAddress",
                "identifier": "Address"
              }
            ]
          }
        ],
        "OriginalUri": "https://github.com/Azure/Azure-Sentinel/blob/master/Solutions/AzureDevOpsAuditing/Analytic Rules/AzDOAdminGroupAdditions.yaml",
        "query": "// Change to true to monitor for Project Administrator adds to *any* project\nlet MonitorAllProjects = false;\n// If MonitorAllProjects is false, trigger only on Project Administrator add for the following projects\nlet ProjectsToMonitor = dynamic(['<project_X>','<project_Y>']);\nAzureDevOpsAuditing\n| where Area == \"Group\" and OperationName == \"Group.UpdateGroupMembership.Add\"\n| where Details has 'Administrators'\n| where Details has \"was added as a member of group\" and (Details endswith '\\\\Project Administrators' or Details endswith '\\\\Project Collection Administrators')\n| parse Details with AddedIdentity ' was added as a member of group [' EntityName ']\\\\' GroupName\n| extend Level = iif(GroupName == 'Project Collection Administrators', 'Organization', 'Project'), AddedIdentityId = Data.MemberId\n| extend Severity = iif(Level == 'Organization', 'High', 'Medium'), AlertDetails = strcat('At ', TimeGenerated, ' UTC ', ActorUPN, '/', ActorDisplayName, ' added ', AddedIdentity, ' to the ', EntityName, ' ', Level)\n| where MonitorAllProjects == true or EntityName in (ProjectsToMonitor) or Level == 'Organization'\n| project TimeGenerated, Severity, Adder = ActorUPN, AddedIdentity, AddedIdentityId, AlertDetails, Level, EntityName, GroupName, ActorAuthType = AuthenticationMechanism,\n  ActorIpAddress = IpAddress, ActorUserAgent = UserAgent, RawDetails = Details\n| extend timestamp = TimeGenerated\n| extend AccountName = tostring(split(Adder, \"@\")[0]), AccountUPNSuffix = tostring(split(Adder, \"@\")[1])\n",
        "queryFrequency": "PT4H",
        "queryPeriod": "PT4H",
        "severity": "Medium",
        "status": "Available",
        "subTechniques": [],
        "suppressionDuration": "PT1H",
        "suppressionEnabled": false,
        "tactics": [
          "Persistence"
        ],
        "techniques": [
          "T1098"
        ],
        "templateVersion": "1.0.4",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 0
      },
      "type": "Microsoft.OperationalInsights/workspaces/providers/alertRules"
    }
  ]
}