Query Details

Azure Dev Ops Token Administration Activity From Non Corporate IP

Query

# *Azure DevOps Token Administration Activity from Non-Corporate IP*

## Query Information

#### MITRE ATT&CK Technique(s)

| Technique ID | Title    | Link    |
| ---  | --- | --- |
| T1528 | Steal Application Access Token | https://attack.mitre.org/techniques/T1528 |
| T1550.001 | Use Alternate Authentication Material: Application Access Token | https://attack.mitre.org/techniques/T1550/001 |

#### Description

This rule detects administrative activities related to tokens (Personal Access Tokens, Access Tokens, identity/security context) within Azure DevOps audit logs that originate from IP addresses outside of the defined corporate network range. This could indicate unauthorized access or suspicious activity related to credential management.

#### Author <Optional>
- **Name: Benjamin Zulliger**
- **Github: https://github.com/benscha/KQLAdvancedHunting**
- **LinkedIn: https://www.linkedin.com/in/benjamin-zulliger/**

#### Possible false positives
- Legitimate administrative actions performed by users working remotely or from non-corporate networks (e.g., home, public Wi-Fi) if the corporate IP range is not comprehensive.
- Third-party integrations or automated processes that manage tokens from external IP addresses.

## Defender XDR
```KQL
let CorporateIPRange = "xx.xx.0.0/16";
// Query audit logs for activities related to tokens (PATs, access tokens, identity/security context)
ADOAuditLogs_CL
| where Area in~ ("TokenAdmin", "TokenAdministration", "Security", "Identities") 
    or Details has "Access Token" 
    or Details has "Personal Access Token"
// Parse JSON payload for structured access to additional fields
| extend DataJson = parse_json(Data)
// Try to extract scopes if available; otherwise fall back to free text field (Filter)
| extend Scopes = coalesce(tostring(DataJson.Scopes), tostring(DataJson.Filter))
// Exclude events originating from trusted corporate network range
| where not(ipv4_is_in_range(IpAddress, (CorporateIPRange)))
```

Explanation

This query is designed to detect potentially unauthorized or suspicious administrative activities related to token management in Azure DevOps. It focuses on activities that originate from IP addresses outside the designated corporate network range, which could indicate unauthorized access attempts. Here's a simple breakdown of the query:

  1. Corporate IP Range: The query defines a range of IP addresses that are considered part of the corporate network. Any activity from outside this range is flagged for further inspection.

  2. Audit Log Filtering: The query examines Azure DevOps audit logs for activities related to token administration, security, and identity management. It specifically looks for actions involving Personal Access Tokens (PATs) and other access tokens.

  3. JSON Parsing: The query parses JSON data within the logs to extract additional details, such as the scopes of the tokens involved.

  4. IP Address Check: It filters out any events that originate from IP addresses within the trusted corporate network, focusing only on those from external sources.

  5. Purpose: The goal is to identify potentially unauthorized access or suspicious activities involving token management that occur from non-corporate IP addresses, which could be indicative of credential theft or misuse.

  6. False Positives: The query acknowledges that legitimate activities might be flagged if users are working remotely or if third-party services interact with Azure DevOps from outside the corporate network.

Overall, this query helps in monitoring and securing Azure DevOps environments by identifying unusual token-related activities from external IP addresses.

Details

Benjamin Zulliger profile picture

Benjamin Zulliger

Released: June 18, 2026

Tables

ADOAuditLogs_CL

Keywords

AzureDevOpsTokenAdministrationActivityIPAddressesAuditLogsTokensAccessTokenPersonalAccessTokenSecurityIdentitiesDataJsonScopesFilterNetworkRange

Operators

letin~orhasextendparse_jsoncoalescetostringwherenotipv4_is_in_range

Actions