Query Details
id: a033b1c2-d3e4-4f5a-6b7c-8d9e0f1a2b3c
name: "Zscaler ZPA - First-Time Access to Internal Application - Possible Lateral Movement"
version: 1.0.0
kind: Scheduled
description: |
Detects ZPA users successfully accessing internal applications they have never connected to in the previous 14 days. In a well-managed ZPA deployment, users have defined app segment policies; accessing new applications outside their normal pattern can indicate logical lateral movement — an attacker using valid credentials to explore internal resources, privilege escalation that granted access to additional app segments, or a legitimate administrator testing new policies. MITRE ATT&CK: T1078 (Valid Accounts), T1021 (Remote Services).
severity: Medium
requiredDataConnectors:
- connectorId: CommonSecurityEvents
dataTypes:
- CommonSecurityLog
queryFrequency: PT1H
queryPeriod: P14D
triggerOperator: gt
triggerThreshold: 0
tactics:
- LateralMovement
- InitialAccess
relevantTechniques:
- T1078
- T1021
query: |
let recentWindow = 1h;
let baselineWindow = 14d;
let baseline = CommonSecurityLog
| where TimeGenerated between (ago(baselineWindow) .. ago(recentWindow))
| where DeviceVendor == "Zscaler" and DeviceProduct has "ZPA"
| where DeviceAction !in ("block", "BLOCK", "Blocked", "Failed", "Error")
| where isnotempty(SourceUserName) and isnotempty(DestinationHostName)
| summarize HistoricApps = make_set(DestinationHostName)
by SourceUserName;
let recent = CommonSecurityLog
| where TimeGenerated > ago(recentWindow)
| where DeviceVendor == "Zscaler" and DeviceProduct has "ZPA"
| where DeviceAction !in ("block", "BLOCK", "Blocked", "Failed", "Error")
| where isnotempty(SourceUserName) and isnotempty(DestinationHostName)
| summarize
RecentApps = make_set(DestinationHostName),
ConnectionCount = count(),
SourceIPs = make_set(SourceIP, 5)
by SourceUserName;
recent
| join kind=leftouter baseline on SourceUserName
| extend HistoricApps = coalesce(HistoricApps, dynamic([]))
| extend FirstTimeApps = set_difference(RecentApps, HistoricApps)
| where array_length(FirstTimeApps) > 0
| project SourceUserName, FirstTimeApps, ConnectionCount, SourceIPs, RecentApps
| order by ConnectionCount desc
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: SourceUserName
customDetails:
ConnectionCount: ConnectionCount
FirstTimeApps: FirstTimeApps
alertDetailsOverride:
alertDisplayNameFormat: "ZPA First-Time App Access - {{SourceUserName}} (new internal apps)"
alertDescriptionFormat: "ZPA user {{SourceUserName}} accessed {{ConnectionCount}} connections to internal apps never seen in 14-day baseline: {{FirstTimeApps}}."
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
lookbackDuration: PT6H
matchingMethod: Selected
groupByEntities:
- Account
groupByAlertDetails: []
groupByCustomDetails: []
This query is designed to detect unusual access patterns in a Zscaler Private Access (ZPA) environment, which could indicate potential security threats such as lateral movement by an attacker. Here's a simple breakdown of what the query does:
Purpose: It identifies users who have accessed internal applications for the first time within the last hour, where they haven't accessed these applications in the previous 14 days. This could suggest unauthorized exploration of internal resources.
Data Source: The query uses data from the CommonSecurityLog, specifically looking at logs from Zscaler ZPA.
Time Frames:
1h).14d).Process:
Output: The query produces a list of users who have accessed new applications, along with details such as the number of connections made, the new applications accessed, and the source IPs used.
Alerting: If any first-time access is detected, an alert is generated with details about the user and the new applications accessed. The alert is categorized under tactics like Lateral Movement and Initial Access, referencing MITRE ATT&CK techniques T1078 (Valid Accounts) and T1021 (Remote Services).
Incident Management: The system is set up to create incidents for these alerts, with configurations for grouping related alerts by user account.
In summary, this query helps security teams monitor for potential unauthorized access or lateral movement within their network by identifying users accessing new internal applications, which could indicate a security breach or policy testing.

David Alonso
Released: March 2, 2026
Tables
Keywords
Operators