diff --git a/Plugins/Community Based Plugins/Purview/KQL_DLPEnhanced.yml b/Plugins/Community Based Plugins/Purview/KQL_DLPEnhanced.yml new file mode 100644 index 00000000..91bdd910 --- /dev/null +++ b/Plugins/Community Based Plugins/Purview/KQL_DLPEnhanced.yml @@ -0,0 +1,308 @@ +Descriptor: + Name: DLPEnhancedAnalytics + DisplayName: Enhanced DLP Analytics and Cross-Workload Correlation plugin + Description: Advanced DLP analytics skills for cross-workload correlation, false positive analysis, policy coverage assessment, adaptive protection integration, and DLP health monitoring across Exchange, Teams, SharePoint, OneDrive, and Endpoints + +SkillGroups: + - Format: KQL + Skills: + - Name: DLPCrossWorkloadCorrelation + DisplayName: Correlate DLP alerts for a user across all workloads + Description: Correlates a user's DLP policy violations across Exchange, Teams, SharePoint, OneDrive, and Endpoints in a single view to identify multi-platform data exfiltration patterns + Inputs: + - Name: User + Description: The user UPN to correlate across workloads + Required: true + - Name: LookbackDays + Description: Number of days to look back (default 14) + Required: false + Settings: + Target: Defender + Template: |- + let user = '{{User}}'; + let lookback = iff(isempty('{{LookbackDays}}'), 14, toint('{{LookbackDays}}')); + CloudAppEvents + | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d"))) + | where ActionType has "DlpRuleMatch" + | where tolower(RawEventData.UserId) has tolower(user) + | extend Workload = tostring(RawEventData.Workload) + | extend PolicyName = tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].PolicyName) + | extend RuleName = tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].RuleName) + | extend Severity = tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].Severity) + | extend SensitiveInfoType = tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].ConditionsMatched)).SensitiveInformation))[0].SensitiveInformationTypeName) + | extend Action = tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].Actions))[0]) + | extend FileName = coalesce( + tostring(parse_json(tostring(RawEventData.SharePointMetaData)).FileName), + tostring(parse_json(tostring(RawEventData.Item)).Attachments), + tostring(RawEventData.ObjectId)) + | extend Subject = tostring(parse_json(tostring(RawEventData.ExchangeMetaData)).Subject) + | extend Target = case( + Workload == "Exchange", strcat("To:", RawEventData.ExchangeMetaData.To), + Workload == "MicrosoftTeams", tostring(RawEventData.Members), + Workload == "SharePoint" or Workload == "OneDrive", tostring(parse_json(tostring(RawEventData.SharePointMetaData)).SiteCollectionUrl), + Workload == "Endpoint", tostring(parse_json(tostring(RawEventData.EndpointMetaData)).TargetDomain), + "Unknown") + | project Timestamp, Workload, PolicyName, RuleName, Severity, SensitiveInfoType, Action, FileName, Subject, Target + | sort by Timestamp desc + | summarize + AlertCount = count(), + Policies = make_set(PolicyName), + SensitiveTypes = make_set(SensitiveInfoType), + Actions = make_set(Action), + Files = make_set(FileName, 10), + FirstAlert = min(Timestamp), + LastAlert = max(Timestamp) + by Workload + | extend DaysBetween = datetime_diff('day', LastAlert, FirstAlert) + | sort by AlertCount desc + + - Name: DLPFalsePositiveAnalysis + DisplayName: Analyze DLP false positives and override patterns + Description: Identifies DLP alerts that are likely false positives by analyzing user override rates, repeated policy triggers on the same content, and low-severity matches across all workloads + Inputs: + - Name: PolicyName + Description: The DLP policy name to analyze for false positives (optional, analyzes all if empty) + Required: false + - Name: LookbackDays + Description: Number of days to analyze (default 30) + Required: false + Settings: + Target: Defender + Template: |- + let policyFilter = '{{PolicyName}}'; + let lookback = iff(isempty('{{LookbackDays}}'), 30, toint('{{LookbackDays}}')); + let dlpMatches = CloudAppEvents + | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d"))) + | where ActionType has "DlpRuleMatch" + | where isempty(policyFilter) or tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].PolicyName) has policyFilter + | extend PolicyName = tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].PolicyName) + | extend RuleName = tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].RuleName) + | extend Action = tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].Actions))[0]) + | extend Workload = tostring(RawEventData.Workload) + | extend UserId = tostring(RawEventData.UserId) + | summarize MatchCount = count() by PolicyName, RuleName, Workload, Action; + let dlpOverrides = CloudAppEvents + | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d"))) + | where ActionType has "DlpRuleUndo" + | where isempty(policyFilter) or tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].PolicyName) has policyFilter + | extend PolicyName = tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].PolicyName) + | extend RuleName = tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].RuleName) + | extend Workload = tostring(RawEventData.Workload) + | summarize OverrideCount = count(), UniqueUsers = dcount(tostring(RawEventData.UserId)) by PolicyName, RuleName, Workload; + dlpMatches + | join kind=leftouter dlpOverrides on PolicyName, RuleName, Workload + | extend OverrideCount = coalesce(OverrideCount, 0) + | extend UniqueUsers = coalesce(UniqueUsers, 0) + | extend OverrideRate = round(todouble(OverrideCount) / todouble(MatchCount) * 100, 2) + | extend FalsePositiveRisk = case( + OverrideRate >= 70, "High - Likely False Positive", + OverrideRate >= 40, "Medium - Needs Review", + OverrideRate >= 10, "Low - Mostly Accurate", + "Minimal - Policy Working Well") + | project PolicyName, RuleName, Workload, Action, MatchCount, OverrideCount, OverrideRate, FalsePositiveRisk, UniqueUsers + | sort by OverrideRate desc + + - Name: DLPPolicyCoverageGaps + DisplayName: Identify DLP policy coverage gaps across workloads + Description: Analyzes which workloads and sensitive information types have DLP policy coverage and identifies gaps where sensitive data may not be protected + Inputs: + - Name: LookbackDays + Description: Number of days to analyze (default 30) + Required: false + Settings: + Target: Defender + Template: |- + let lookback = iff(isempty('{{LookbackDays}}'), 30, toint('{{LookbackDays}}')); + let workloadCoverage = CloudAppEvents + | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d"))) + | where ActionType has "DlpRuleMatch" + | extend Workload = tostring(RawEventData.Workload) + | extend PolicyName = tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].PolicyName) + | extend SensitiveInfoType = tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].ConditionsMatched)).SensitiveInformation))[0].SensitiveInformationTypeName) + | extend Severity = tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].Severity) + | summarize + PolicyCount = dcount(PolicyName), + Policies = make_set(PolicyName), + SensitiveTypes = make_set(SensitiveInfoType), + TotalAlerts = count(), + SeverityDistribution = make_bag(pack(Severity, 1)), + UniqueUsers = dcount(tostring(RawEventData.UserId)) + by Workload + | extend SensitiveTypeCount = array_length(SensitiveTypes); + let allWorkloads = datatable(Workload: string) ["Exchange", "MicrosoftTeams", "SharePoint", "OneDrive", "Endpoint"]; + allWorkloads + | join kind=leftouter workloadCoverage on Workload + | extend PolicyCount = coalesce(PolicyCount, 0) + | extend TotalAlerts = coalesce(TotalAlerts, 0) + | extend UniqueUsers = coalesce(UniqueUsers, 0) + | extend SensitiveTypeCount = coalesce(SensitiveTypeCount, 0) + | extend CoverageStatus = case( + PolicyCount == 0, "NO COVERAGE - Critical Gap", + PolicyCount == 1, "Minimal Coverage - Needs Expansion", + PolicyCount <= 3, "Moderate Coverage", + "Good Coverage") + | project Workload, CoverageStatus, PolicyCount, TotalAlerts, UniqueUsers, SensitiveTypeCount, Policies, SensitiveTypes + | sort by PolicyCount asc + + - Name: DLPHighRiskUsersAcrossWorkloads + DisplayName: Get high-risk users with DLP violations across multiple workloads + Description: Identifies users who have triggered DLP alerts across 2 or more workloads, indicating potential coordinated data exfiltration attempts + Inputs: + - Name: LookbackDays + Description: Number of days to analyze (default 14) + Required: false + - Name: MinWorkloads + Description: Minimum number of workloads with violations to flag (default 2) + Required: false + Settings: + Target: Defender + Template: |- + let lookback = iff(isempty('{{LookbackDays}}'), 14, toint('{{LookbackDays}}')); + let minWorkloads = iff(isempty('{{MinWorkloads}}'), 2, toint('{{MinWorkloads}}')); + CloudAppEvents + | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d"))) + | where ActionType has "DlpRuleMatch" + | extend UserId = tostring(RawEventData.UserId) + | extend Workload = tostring(RawEventData.Workload) + | extend PolicyName = tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].PolicyName) + | extend Severity = tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].Severity) + | extend SensitiveInfoType = tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].ConditionsMatched)).SensitiveInformation))[0].SensitiveInformationTypeName) + | summarize + TotalAlerts = count(), + Workloads = make_set(Workload), + WorkloadCount = dcount(Workload), + Policies = make_set(PolicyName), + SensitiveTypes = make_set(SensitiveInfoType), + HighSeverityCount = countif(Severity == "High"), + FirstAlert = min(Timestamp), + LastAlert = max(Timestamp) + by UserId + | where WorkloadCount >= minWorkloads + | extend RiskScore = case( + WorkloadCount >= 4 and HighSeverityCount >= 3, "Critical", + WorkloadCount >= 3 or HighSeverityCount >= 2, "High", + WorkloadCount >= 2, "Medium", + "Low") + | project UserId, RiskScore, WorkloadCount, Workloads, TotalAlerts, HighSeverityCount, Policies, SensitiveTypes, FirstAlert, LastAlert + | sort by WorkloadCount desc, TotalAlerts desc + + - Name: DLPAlertTrendAnalysis + DisplayName: Get DLP alert trend analysis over time + Description: Provides a time-based trend analysis of DLP alerts across all workloads to identify spikes, patterns, and anomalies in data loss prevention events + Inputs: + - Name: LookbackDays + Description: Number of days to analyze trends (default 30) + Required: false + - Name: Workload + Description: Filter to a specific workload (Exchange, MicrosoftTeams, SharePoint, OneDrive, Endpoint) + Required: false + Settings: + Target: Defender + Template: |- + let lookback = iff(isempty('{{LookbackDays}}'), 30, toint('{{LookbackDays}}')); + let workloadFilter = '{{Workload}}'; + CloudAppEvents + | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d"))) + | where ActionType has "DlpRuleMatch" + | where isempty(workloadFilter) or tostring(RawEventData.Workload) has workloadFilter + | extend Workload = tostring(RawEventData.Workload) + | extend Severity = tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].Severity) + | extend PolicyName = tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].PolicyName) + | extend UserId = tostring(RawEventData.UserId) + | summarize + TotalAlerts = count(), + HighSeverity = countif(Severity == "High"), + MediumSeverity = countif(Severity == "Medium"), + LowSeverity = countif(Severity == "Low"), + UniqueUsers = dcount(UserId), + UniquePolicies = dcount(PolicyName), + Workloads = make_set(Workload) + by Day = bin(Timestamp, 1d) + | extend DailyAvg = TotalAlerts + | sort by Day asc + + - Name: DLPLabelDowngradeRemoval + DisplayName: Get sensitivity label downgrade and removal events + Description: Identifies events where users have downgraded or removed sensitivity labels from documents and emails, which may indicate attempts to bypass DLP protections + Inputs: + - Name: User + Description: The user UPN to investigate (optional, shows all users if empty) + Required: false + - Name: LookbackDays + Description: Number of days to look back (default 14) + Required: false + Settings: + Target: Defender + Template: |- + let user = '{{User}}'; + let lookback = iff(isempty('{{LookbackDays}}'), 14, toint('{{LookbackDays}}')); + CloudAppEvents + | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d"))) + | where ActionType in ("SensitivityLabelRemoved", "SensitivityLabeledFileRenamed", "SensitivityLabelUpdated", "FileSensitivityLabelChanged", "MIPLabel") + | where isempty(user) or tolower(RawEventData.UserId) has tolower(user) + | extend UserId = tostring(RawEventData.UserId) + | extend FileName = coalesce( + tostring(RawEventData.SourceFileName), + tostring(RawEventData.ObjectId), + tostring(parse_json(tostring(RawEventData.SharePointMetaData)).FileName)) + | extend OldLabel = tostring(RawEventData.OldSensitivityLabelId) + | extend NewLabel = tostring(RawEventData.SensitivityLabelId) + | extend Justification = tostring(RawEventData.Justification) + | extend Workload = tostring(RawEventData.Workload) + | extend LabelAction = case( + ActionType == "SensitivityLabelRemoved", "Label Removed", + isempty(NewLabel) and isnotempty(OldLabel), "Label Removed", + "Label Changed") + | project Timestamp, UserId, FileName, Workload, LabelAction, OldLabel, NewLabel, Justification, ActionType + | sort by Timestamp desc + + - Name: DLPPolicyHealthCheck + DisplayName: Get DLP policy health check summary + Description: Provides a comprehensive health check of all DLP policies including match rates, override rates, action distribution, and effectiveness metrics to guide policy tuning + Inputs: + - Name: LookbackDays + Description: Number of days to analyze (default 30) + Required: false + Settings: + Target: Defender + Template: |- + let lookback = iff(isempty('{{LookbackDays}}'), 30, toint('{{LookbackDays}}')); + let matches = CloudAppEvents + | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d"))) + | where ActionType has "DlpRuleMatch" + | extend PolicyName = tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].PolicyName) + | extend Workload = tostring(RawEventData.Workload) + | extend Severity = tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].Severity) + | extend Action = tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].Actions))[0]) + | extend UserId = tostring(RawEventData.UserId) + | summarize + TotalMatches = count(), + UniqueUsers = dcount(UserId), + Workloads = make_set(Workload), + WorkloadCount = dcount(Workload), + HighSev = countif(Severity == "High"), + MedSev = countif(Severity == "Medium"), + LowSev = countif(Severity == "Low"), + BlockActions = countif(Action == "Block"), + WarnActions = countif(Action == "Warn" or Action == "NotifyUser"), + AuditActions = countif(Action == "Audit" or Action == "AuditOnly"), + FirstMatch = min(Timestamp), + LastMatch = max(Timestamp) + by PolicyName; + let overrides = CloudAppEvents + | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d"))) + | where ActionType has "DlpRuleUndo" + | extend PolicyName = tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].PolicyName) + | summarize OverrideCount = count() by PolicyName; + matches + | join kind=leftouter overrides on PolicyName + | extend OverrideCount = coalesce(OverrideCount, 0) + | extend OverrideRate = round(todouble(OverrideCount) / todouble(TotalMatches) * 100, 2) + | extend BlockRate = round(todouble(BlockActions) / todouble(TotalMatches) * 100, 2) + | extend HealthStatus = case( + OverrideRate >= 60, "Unhealthy - High Override Rate", + OverrideRate >= 30, "Needs Attention - Moderate Overrides", + TotalMatches <= 5, "Low Activity - Verify Coverage", + "Healthy") + | project PolicyName, HealthStatus, TotalMatches, OverrideCount, OverrideRate, BlockRate, UniqueUsers, WorkloadCount, Workloads, HighSev, MedSev, LowSev, FirstMatch, LastMatch + | sort by TotalMatches desc diff --git a/Plugins/Community Based Plugins/Purview/KQL_DLPEnhanced_README.md b/Plugins/Community Based Plugins/Purview/KQL_DLPEnhanced_README.md new file mode 100644 index 00000000..34f8a09d --- /dev/null +++ b/Plugins/Community Based Plugins/Purview/KQL_DLPEnhanced_README.md @@ -0,0 +1,177 @@ +# Enhanced DLP Analytics and Cross-Workload Correlation Plugin + +## DESCRIPTION + +This plugin extends the existing Data Security Analyst plugin (`KQL_DataAnalyst.yml`) with advanced analytics capabilities for DLP investigations. It provides cross-workload correlation, false positive analysis, policy health monitoring, sensitivity label compliance tracking, and trend analysis — capabilities that are missing from the base plugin. + +### Intended Audience + +- **SOC Analysts** investigating multi-workload DLP incidents +- **Data Security Administrators** tuning DLP policy effectiveness +- **Compliance Officers** assessing DLP policy coverage and label compliance +- **Security Managers** monitoring organizational DLP posture and trends + +### Intended Uses + +- Correlate a user's DLP violations across Exchange, Teams, SharePoint, OneDrive, and Endpoints in a single unified view +- Identify DLP policies with high false positive rates using override pattern analysis +- Detect workloads with no DLP policy coverage (critical protection gaps) +- Flag high-risk users who trigger DLP alerts across multiple platforms simultaneously +- Track sensitivity label downgrades and removals that may indicate policy bypass +- Perform DLP policy health checks with match rates, override rates, and effectiveness metrics +- Analyze DLP alert trends over time to identify spikes and anomalies + +### Supported Microsoft Products + +- [Microsoft Security Copilot](https://learn.microsoft.com/en-us/security-copilot/) +- [Microsoft Purview Data Loss Prevention](https://learn.microsoft.com/en-us/purview/dlp-learn-about-dlp) +- [Microsoft Defender XDR](https://learn.microsoft.com/en-us/defender-xdr/) + +### Limitations + +- Skills query the CloudAppEvents table in Microsoft Defender XDR; results are limited to the data retention period configured in your tenant +- Cross-workload correlation requires DLP policies enabled on the relevant workloads to generate alerts +- False positive analysis uses override rates as a proxy — a high override rate may indicate either false positives or inadequate user training +- Policy coverage gap detection identifies workloads with zero DLP alert matches; a workload with no alerts could also mean no sensitive data activity (not necessarily a gap) +- Label downgrade detection depends on label change events being logged in CloudAppEvents +- This plugin provides read-only analytics — it does not modify policies, labels, or user permissions + +--- + +## TYPE AND REQUIREMENTS +**TYPE**: KQL (Defender)
+**SOURCE**: _CloudAppEvents_ table (Microsoft Defender XDR)
+ +### Pre-requisites + +- [Security Copilot Enabled](https://learn.microsoft.com/en-us/security-copilot/get-started-security-copilot#onboarding-to-microsoft-security-copilot) +- [Access to upload custom plugins](https://learn.microsoft.com/en-us/security-copilot/manage-plugins?tabs=securitycopilotplugin#managing-custom-plugins) +- Microsoft Defender XDR with CloudAppEvents data ingestion enabled +- [DLP policies configured](https://learn.microsoft.com/en-us/purview/dlp-learn-about-dlp) across one or more workloads (Exchange, Teams, SharePoint, OneDrive, Endpoint) +- [Sensitivity labels configured](https://learn.microsoft.com/en-us/purview/sensitivity-labels) for label compliance tracking skills + +### Instructions +#### Upload the Custom Plugin + +1. Obtain the file [KQL_DLPEnhanced.yml](KQL_DLPEnhanced.yml) from this directory. +2. [Upload the custom plugin](https://learn.microsoft.com/en-us/security-copilot/manage-plugins?tabs=securitycopilotplugin#add-custom-plugins) in Security Copilot. +3. Verify the plugin is activated and the skills appear in the skill list. +4. No additional authentication is required — the plugin uses standard Defender XDR permissions. +5. **Note**: This plugin complements the existing `KQL_DataAnalyst.yml` plugin — both can be active simultaneously without conflict. + +--- + +## SKILLS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SkillNameDescriptionParameters
DLPCrossWorkloadCorrelationCorrelates a user's DLP violations across Exchange, Teams, SharePoint, OneDrive, and Endpoints in one unified view +
    +
  • User (required) — UPN of the user
  • +
  • LookbackDays (optional) — Days to look back, default 14
  • +
+
DLPFalsePositiveAnalysisIdentifies likely false positives by analyzing override rates and classifying policy effectiveness +
    +
  • PolicyName (optional) — Filter to specific policy
  • +
  • LookbackDays (optional) — Days to analyze, default 30
  • +
+
DLPPolicyCoverageGapsDetects workloads with no DLP policy coverage and flags critical gaps +
    +
  • LookbackDays (optional) — Days to analyze, default 30
  • +
+
DLPHighRiskUsersAcrossWorkloadsFlags users with DLP violations across 2+ workloads and assigns risk scores (Critical/High/Medium/Low) +
    +
  • LookbackDays (optional) — Days to analyze, default 14
  • +
  • MinWorkloads (optional) — Minimum workloads threshold, default 2
  • +
+
DLPAlertTrendAnalysisTime-series DLP alert trend analysis by day, showing spikes and severity distribution +
    +
  • LookbackDays (optional) — Days to analyze, default 30
  • +
  • Workload (optional) — Filter to specific workload
  • +
+
DLPLabelDowngradeRemovalTracks sensitivity label downgrades and removals that may indicate DLP bypass attempts +
    +
  • User (optional) — UPN of the user
  • +
  • LookbackDays (optional) — Days to look back, default 14
  • +
+
DLPPolicyHealthCheckComprehensive policy health dashboard with match/override rates and Healthy/Unhealthy status +
    +
  • LookbackDays (optional) — Days to analyze, default 30
  • +
+
+ +--- + +## SAMPLE PROMPTS + +- `Correlate all DLP alerts for user user@contoso.com across Exchange, Teams, SharePoint, OneDrive, and Endpoints in the last 14 days` +- `Which DLP policies have the highest false positive override rates?` +- `Identify DLP policy coverage gaps across all workloads — which workloads have no protection?` +- `Show me users with DLP violations across 2 or more workloads — who are the highest risk?` +- `Show me DLP alert trends over the last 30 days — are there any spikes?` +- `Which users have downgraded or removed sensitivity labels in the last 14 days?` +- `Run a DLP policy health check — show match rates, override rates, and effectiveness for all policies` + +--- + +## RELATIONSHIP TO EXISTING PLUGINS + +This plugin **complements** the existing `KQL_DataAnalyst.yml` plugin without overlap: + +| Capability | `KQL_DataAnalyst.yml` (existing) | `KQL_DLPEnhanced.yml` (this plugin) | +|-----------|----------------------------------|--------------------------------------| +| Per-workload DLP alerts | ✅ 15 skills | — | +| Sensitivity file monitoring | ✅ 16 skills | — | +| DLP policy tuning suggestions | ✅ 5 skills | — | +| **Cross-workload correlation** | ❌ | ✅ | +| **False positive analysis** | ❌ | ✅ | +| **Policy coverage gaps** | ❌ | ✅ | +| **High-risk user scoring** | ❌ | ✅ | +| **Alert trend analysis** | ❌ | ✅ | +| **Label downgrade tracking** | ❌ | ✅ | +| **Policy health dashboard** | ❌ | ✅ | + +--- + +For more information, see: [Microsoft Purview Data Loss Prevention](https://learn.microsoft.com/en-us/purview/dlp-learn-about-dlp) diff --git a/Plugins/Community Based Plugins/Purview/readme.md b/Plugins/Community Based Plugins/Purview/readme.md index ee2e1cbd..09861285 100644 --- a/Plugins/Community Based Plugins/Purview/readme.md +++ b/Plugins/Community Based Plugins/Purview/readme.md @@ -22,4 +22,7 @@ The plugin can monitor applications accessing sensitive content and provide deta ### Promptbooks These are valuable resources for implementing standard operating procedures for security incidents, helping to identify various dimensions of an incident and summarize outcomes. +### Enhanced DLP Analytics (KQL_DLPEnhanced.yml) +This companion plugin provides advanced DLP analytics capabilities including cross-workload correlation, false positive analysis, policy coverage gap detection, high-risk user scoring, alert trend analysis, sensitivity label compliance tracking, and policy health dashboards. See [KQL_DLPEnhanced_README.md](KQL_DLPEnhanced_README.md) for full documentation. + [Learn more](https://techcommunity.microsoft.com/t5/security-compliance-and-identity/learn-how-to-customize-and-optimize-copilot-for-security-with/ba-p/4120147) diff --git a/Sample Prompts/Microsoft Purview/Readme.md b/Sample Prompts/Microsoft Purview/Readme.md index 31086b3f..e522df1a 100644 --- a/Sample Prompts/Microsoft Purview/Readme.md +++ b/Sample Prompts/Microsoft Purview/Readme.md @@ -36,4 +36,24 @@ Documentation for Microsoft Purview and Copilot for Secuity can be found here : - What Suspicious Actions Have Been Performed On This Files? - Tell me more about Sensitivity label X +## Cross-Workload DLP Correlation +- Correlate all DLP alerts for user `` across Exchange, Teams, SharePoint, OneDrive, and Endpoints in the last 14 days +- Show me users who have triggered DLP alerts across 2 or more workloads in the last 14 days +- Which users have the highest cross-workload DLP risk score? + +## DLP False Positive Analysis +- Analyze DLP false positive rates for policy `` in the last 30 days +- Which DLP policies have the highest override rates and are likely false positives? +- Show me the override patterns for DLP policy `` — is it working effectively? + +## DLP Policy Health and Coverage +- Run a DLP policy health check — show me match rates, override rates, and effectiveness for all policies +- Identify DLP policy coverage gaps across all workloads — which workloads have no DLP protection? +- Show me DLP alert trends over the last 30 days — are there any spikes or anomalies? + +## Sensitivity Label Compliance +- Show me sensitivity label downgrade and removal events for user `` in the last 14 days +- Which users have removed sensitivity labels from documents recently? +- Are there any unauthorized label downgrade events that need investigation? + Disclaimer: Please know these are sample prompts and are subject to Change