diff --git a/Plugins/Community Based Plugins/ChatCommunicationProtection/KQL_ChatProtection.yml b/Plugins/Community Based Plugins/ChatCommunicationProtection/KQL_ChatProtection.yml
new file mode 100644
index 00000000..79b01051
--- /dev/null
+++ b/Plugins/Community Based Plugins/ChatCommunicationProtection/KQL_ChatProtection.yml
@@ -0,0 +1,286 @@
+Descriptor:
+ Name: ChatCommunicationProtection
+ DisplayName: Chat and Communication Protection plugin
+ Description: Data Security skills to query Teams chat DLP events, communication compliance violations, meeting transcript analysis, and cross-channel sensitive data exposure for investigation and response
+
+SkillGroups:
+ - Format: KQL
+ Skills:
+ - Name: ChatDLPGetTeamsChatAlerts
+ DisplayName: Get DLP alerts triggered in Teams chat messages
+ Description: Fetches all DLP policy violations that occurred in Teams chat messages, including private chats and group chats, with details on the policy matched, sensitive information types detected, and actions taken
+ Inputs:
+ - Name: User
+ Description: The user UPN associated with the Teams chat DLP alert
+ Required: false
+ - Name: LookbackDays
+ Description: Number of days to look back for alerts (default 7)
+ Required: false
+ Settings:
+ Target: Defender
+ Template: |-
+ let user = '{{User}}';
+ let lookback = iff(isempty('{{LookbackDays}}'), 7, toint('{{LookbackDays}}'));
+ CloudAppEvents
+ | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d")))
+ | where ActionType has "DlpRuleMatch"
+ | where RawEventData.Workload == "MicrosoftTeams"
+ | where isempty(user) or tolower(RawEventData.UserId) has tolower(user)
+ | 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 MessageType = case(
+ RawEventData.MessageType == "Chat", "Private Chat",
+ RawEventData.MessageType == "Channel", "Channel Message",
+ RawEventData.MessageType == "Meeting", "Meeting Chat",
+ tostring(RawEventData.MessageType))
+ | extend UserId = tostring(RawEventData.UserId)
+ | extend Recipients = tostring(RawEventData.Members)
+ | project Timestamp, UserId, MessageType, PolicyName, RuleName, Severity, SensitiveInfoType, Action, Recipients
+ | sort by Timestamp desc
+
+ - Name: ChatDLPGetChannelViolations
+ DisplayName: Get DLP violations in Teams channels
+ Description: Fetches DLP policy violations in Teams channel messages with details on the channel, team, policy triggered, and sensitive content detected
+ Inputs:
+ - Name: LookbackDays
+ Description: Number of days to look back for violations (default 7)
+ Required: false
+ Settings:
+ Target: Defender
+ Template: |-
+ let lookback = iff(isempty('{{LookbackDays}}'), 7, toint('{{LookbackDays}}'));
+ CloudAppEvents
+ | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d")))
+ | where ActionType has "DlpRuleMatch"
+ | where RawEventData.Workload == "MicrosoftTeams"
+ | where RawEventData.MessageType == "Channel"
+ | 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)
+ | extend Action = tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].Actions))[0])
+ | extend UserId = tostring(RawEventData.UserId)
+ | extend TeamName = tostring(RawEventData.TeamName)
+ | extend ChannelName = tostring(RawEventData.ChannelName)
+ | project Timestamp, UserId, TeamName, ChannelName, PolicyName, Severity, SensitiveInfoType, Action
+ | summarize AlertCount = count(), LatestAlert = max(Timestamp) by TeamName, ChannelName, PolicyName, SensitiveInfoType
+ | sort by AlertCount desc
+
+ - Name: ChatDLPGetExternalSharingInTeams
+ DisplayName: Get sensitive data shared with external users in Teams
+ Description: Identifies instances where sensitive information was shared with external or guest users through Teams chats, channels, or file sharing
+ Inputs:
+ - Name: User
+ Description: The internal user UPN to investigate
+ 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 RawEventData.Workload == "MicrosoftTeams"
+ | where isempty(user) or tolower(RawEventData.UserId) has tolower(user)
+ | where RawEventData.Members has "#EXT#" or RawEventData.Members has "guest"
+ | extend UserId = tostring(RawEventData.UserId)
+ | extend MessageType = tostring(RawEventData.MessageType)
+ | extend ExternalRecipients = RawEventData.Members
+ | extend HasDLPMatch = iff(ActionType has "DlpRuleMatch", "Yes", "No")
+ | extend PolicyName = iff(HasDLPMatch == "Yes", tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].PolicyName), "N/A")
+ | extend SensitiveInfoType = iff(HasDLPMatch == "Yes", tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].ConditionsMatched)).SensitiveInformation))[0].SensitiveInformationTypeName), "N/A")
+ | project Timestamp, UserId, MessageType, ExternalRecipients, HasDLPMatch, PolicyName, SensitiveInfoType
+ | sort by Timestamp desc
+
+ - Name: ChatDLPGetMeetingChatViolations
+ DisplayName: Get DLP violations in Teams meeting chats
+ Description: Fetches DLP alerts that were triggered during Teams meeting chat sessions, helping analysts identify sensitive data disclosed during meetings
+ Inputs:
+ - Name: LookbackDays
+ Description: Number of days to look back for meeting violations (default 7)
+ Required: false
+ Settings:
+ Target: Defender
+ Template: |-
+ let lookback = iff(isempty('{{LookbackDays}}'), 7, toint('{{LookbackDays}}'));
+ CloudAppEvents
+ | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d")))
+ | where ActionType has "DlpRuleMatch"
+ | where RawEventData.Workload == "MicrosoftTeams"
+ | where RawEventData.MessageType == "Meeting"
+ | 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)
+ | extend UserId = tostring(RawEventData.UserId)
+ | extend MeetingId = tostring(RawEventData.MeetingId)
+ | extend Action = tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].Actions))[0])
+ | project Timestamp, UserId, MeetingId, PolicyName, Severity, SensitiveInfoType, Action
+ | sort by Timestamp desc
+
+ - Name: ChatDLPGetUserOverrides
+ DisplayName: Get DLP policy overrides by users in Teams
+ Description: Identifies instances where users overrode DLP policy warnings in Teams, indicating potential intentional data sharing of sensitive content
+ Inputs:
+ - Name: User
+ Description: The user UPN to check for overrides
+ Required: false
+ - Name: LookbackDays
+ Description: Number of days to look back (default 30)
+ Required: false
+ Settings:
+ Target: Defender
+ Template: |-
+ let user = '{{User}}';
+ let lookback = iff(isempty('{{LookbackDays}}'), 30, toint('{{LookbackDays}}'));
+ CloudAppEvents
+ | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d")))
+ | where ActionType has "DlpRuleUndo"
+ | where RawEventData.Workload == "MicrosoftTeams"
+ | where isempty(user) or tolower(RawEventData.UserId) has tolower(user)
+ | extend UserId = tostring(RawEventData.UserId)
+ | 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 Justification = tostring(RawEventData.Justification)
+ | extend MessageType = tostring(RawEventData.MessageType)
+ | project Timestamp, UserId, MessageType, PolicyName, RuleName, Justification
+ | summarize OverrideCount = count(), LatestOverride = max(Timestamp), Justifications = make_set(Justification) by UserId, PolicyName
+ | sort by OverrideCount desc
+
+ - Name: ChatDLPGetCommunicationComplianceSummary
+ DisplayName: Get communication compliance violation summary
+ Description: Provides a summary of communication compliance events across Teams, Exchange, and other communication channels including policy violations related to offensive language, regulatory compliance, and conflict of interest
+ Inputs:
+ - Name: User
+ Description: The user UPN to investigate
+ Required: false
+ - Name: LookbackDays
+ Description: Number of days to look back (default 30)
+ Required: false
+ Settings:
+ Target: Defender
+ Template: |-
+ let user = '{{User}}';
+ let lookback = iff(isempty('{{LookbackDays}}'), 30, toint('{{LookbackDays}}'));
+ CloudAppEvents
+ | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d")))
+ | where ActionType has "SupervisoryReviewPolicyMatch" or ActionType has "CommunicationCompliancePolicyMatch"
+ | where isempty(user) or tolower(RawEventData.UserId) has tolower(user)
+ | extend UserId = tostring(RawEventData.UserId)
+ | extend PolicyName = tostring(RawEventData.PolicyName)
+ | extend Workload = tostring(RawEventData.Workload)
+ | extend MessageType = case(
+ Workload == "MicrosoftTeams", "Teams Message",
+ Workload == "Exchange", "Email",
+ Workload)
+ | extend ViolationType = tostring(RawEventData.ClassifierType)
+ | extend Severity = tostring(RawEventData.Severity)
+ | project Timestamp, UserId, Workload, MessageType, PolicyName, ViolationType, Severity
+ | summarize ViolationCount = count(), LatestViolation = max(Timestamp) by UserId, Workload, PolicyName, ViolationType
+ | sort by ViolationCount desc
+
+ - Name: ChatDLPGetSensitiveDataInChats
+ DisplayName: Get sensitive information types detected in Teams chats
+ Description: Identifies and summarizes the types of sensitive information detected in Teams chat messages, grouped by sensitive information type and user
+ Inputs:
+ - Name: LookbackDays
+ Description: Number of days to look back (default 7)
+ Required: false
+ Settings:
+ Target: Defender
+ Template: |-
+ let lookback = iff(isempty('{{LookbackDays}}'), 7, toint('{{LookbackDays}}'));
+ CloudAppEvents
+ | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d")))
+ | where ActionType has "DlpRuleMatch"
+ | where RawEventData.Workload == "MicrosoftTeams"
+ | extend UserId = tostring(RawEventData.UserId)
+ | 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 Confidence = tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].ConditionsMatched)).SensitiveInformation))[0].Confidence)
+ | extend Count = toint(parse_json(tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].ConditionsMatched)).SensitiveInformation))[0].Count)
+ | extend MessageType = tostring(RawEventData.MessageType)
+ | project Timestamp, UserId, MessageType, SensitiveInfoType, Confidence, Count, PolicyName
+ | summarize TotalDetections = sum(Count), UniqueUsers = dcount(UserId), LatestDetection = max(Timestamp) by SensitiveInfoType, PolicyName
+ | sort by TotalDetections desc
+
+ - Name: ChatDLPGetChatExfiltrationTimeline
+ DisplayName: Get timeline of potential data exfiltration via Teams chat
+ Description: Builds a chronological timeline of a user's sensitive data activities across Teams chat to help identify patterns of data exfiltration through chat channels
+ Inputs:
+ - Name: User
+ Description: The user UPN to investigate for exfiltration patterns
+ 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}}'));
+ let teamsDLP = CloudAppEvents
+ | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d")))
+ | where RawEventData.Workload == "MicrosoftTeams"
+ | where tolower(RawEventData.UserId) has tolower(user)
+ | where ActionType has "DlpRuleMatch" or ActionType has "DlpRuleUndo"
+ | extend EventType = iff(ActionType has "DlpRuleUndo", "DLP Override", "DLP Match")
+ | 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 MessageType = tostring(RawEventData.MessageType)
+ | extend HasExternalRecipient = iff(RawEventData.Members has "#EXT#" or RawEventData.Members has "guest", "Yes", "No")
+ | project Timestamp, EventType, MessageType, PolicyName, SensitiveInfoType, HasExternalRecipient;
+ let teamsFileShare = CloudAppEvents
+ | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d")))
+ | where RawEventData.Workload == "MicrosoftTeams"
+ | where tolower(RawEventData.UserId) has tolower(user)
+ | where ActionType in ("FileUploaded", "FileShared", "FileDownloaded", "FileCopied")
+ | extend EventType = strcat("File: ", ActionType)
+ | extend FileName = tostring(RawEventData.SourceFileName)
+ | extend MessageType = "File Operation"
+ | extend PolicyName = ""
+ | extend SensitiveInfoType = ""
+ | extend HasExternalRecipient = iff(RawEventData.TargetUserOrGroupName has "#EXT#", "Yes", "No")
+ | project Timestamp, EventType, MessageType, PolicyName, SensitiveInfoType, HasExternalRecipient;
+ union teamsDLP, teamsFileShare
+ | sort by Timestamp asc
+
+ - Name: ChatDLPGetTeamsPolicyCoverage
+ DisplayName: Get Teams DLP policy coverage analysis
+ Description: Analyzes the current DLP policy coverage for Teams communications, identifying which policies are actively matching and potential coverage gaps
+ Inputs:
+ - Name: LookbackDays
+ Description: Number of days to analyze for policy coverage (default 30)
+ Required: false
+ Settings:
+ Target: Defender
+ Template: |-
+ let lookback = iff(isempty('{{LookbackDays}}'), 30, toint('{{LookbackDays}}'));
+ CloudAppEvents
+ | where Timestamp >= ago(totimespan(strcat(tostring(lookback), "d")))
+ | where ActionType has "DlpRuleMatch"
+ | where RawEventData.Workload == "MicrosoftTeams"
+ | 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 Action = tostring(parse_json(tostring(parse_json(tostring(parse_json(tostring(RawEventData.PolicyDetails))[0].Rules))[0].Actions))[0])
+ | 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 MessageType = case(
+ RawEventData.MessageType == "Chat", "Private Chat",
+ RawEventData.MessageType == "Channel", "Channel Message",
+ RawEventData.MessageType == "Meeting", "Meeting Chat",
+ tostring(RawEventData.MessageType))
+ | summarize
+ TotalMatches = count(),
+ UniqueUsers = dcount(tostring(RawEventData.UserId)),
+ MessageTypes = make_set(MessageType),
+ SensitiveTypes = make_set(SensitiveInfoType),
+ Actions = make_set(Action),
+ FirstMatch = min(Timestamp),
+ LastMatch = max(Timestamp)
+ by PolicyName, RuleName, Severity
+ | sort by TotalMatches desc
diff --git a/Plugins/Community Based Plugins/ChatCommunicationProtection/Readme.md b/Plugins/Community Based Plugins/ChatCommunicationProtection/Readme.md
new file mode 100644
index 00000000..e3cf9511
--- /dev/null
+++ b/Plugins/Community Based Plugins/ChatCommunicationProtection/Readme.md
@@ -0,0 +1,186 @@
+# Chat and Communication Protection Plugin
+
+## DESCRIPTION
+This plugin provides comprehensive Data Loss Prevention (DLP) and communication compliance skills for Microsoft Teams chat, channel messages, and meeting conversations. It enables Security Analysts to investigate sensitive data exposure in Teams communications, identify policy violations, track user override patterns, detect data exfiltration through chat channels, and assess DLP policy coverage for Teams workloads.
+
+### Intended Audience
+- **SOC Analysts** investigating DLP incidents involving Teams communications
+- **Data Security Administrators** monitoring Teams DLP policy effectiveness
+- **Compliance Officers** tracking communication compliance violations
+- **Incident Responders** building exfiltration timelines across Teams channels
+
+### Intended Uses
+- Investigate DLP policy violations in Teams private chats, channel messages, and meeting chats
+- Detect sensitive data shared with external or guest users through Teams
+- Identify users who override DLP policy warnings and analyze override patterns
+- Monitor communication compliance violations across Teams and Exchange
+- Build chronological exfiltration timelines to support incident investigations
+- Assess DLP policy coverage for Teams and identify protection gaps
+
+### Supported Microsoft Products
+- [Microsoft Security Copilot](https://learn.microsoft.com/en-us/security-copilot/)
+- [Microsoft Purview DLP for Teams](https://learn.microsoft.com/en-us/purview/dlp-microsoft-teams)
+- [Microsoft Purview Communication Compliance](https://learn.microsoft.com/en-us/purview/communication-compliance)
+- [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
+- Communication compliance skills depend on communication compliance policies being configured in Microsoft Purview
+- DLP alerts are only available for workloads where DLP policies targeting the Microsoft Teams location are enabled
+- Meeting chat DLP detection requires DLP policies scoped to Teams chat — meeting recordings/transcripts are not analyzed
+- External/guest user detection relies on `#EXT#` identifiers in user records; federated tenant users may not be detected
+- This plugin provides read-only investigation capabilities — it does not block, modify, or remediate any content
+
+---
+
+## 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 for Microsoft Teams workload](https://learn.microsoft.com/en-us/purview/dlp-microsoft-teams)
+- (Optional) [Communication Compliance policies](https://learn.microsoft.com/en-us/purview/communication-compliance-policies) configured for the CommunicationComplianceSummary skill
+
+### Instructions
+#### Upload the Custom Plugin
+
+1. Obtain the file [KQL_ChatProtection.yml](KQL_ChatProtection.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 configuration is required — the plugin uses standard Defender XDR permissions.
+
+---
+
+## SKILLS
+
+
| SkillName | +Description | +Parameters | +
|---|---|---|
| ChatDLPGetTeamsChatAlerts | +Fetches DLP policy violations in Teams chat messages including private, group, and channel messages | +
+
|
+
| ChatDLPGetChannelViolations | +Gets DLP violations in Teams channels, summarized by team, channel, and policy | +
+
|
+
| ChatDLPGetExternalSharingInTeams | +Identifies sensitive data shared with external/guest users through Teams | +
+
|
+
| ChatDLPGetMeetingChatViolations | +Fetches DLP alerts triggered during Teams meeting chat sessions | +
+
|
+
| ChatDLPGetUserOverrides | +Identifies DLP policy overrides by users in Teams, showing intentional bypass patterns | +
+
|
+
| ChatDLPGetCommunicationComplianceSummary | +Summarizes communication compliance violations across Teams and Exchange | +
+
|
+
| ChatDLPGetSensitiveDataInChats | +Identifies sensitive information types detected in Teams chats, grouped by type | +
+
|
+
| ChatDLPGetChatExfiltrationTimeline | +Builds a chronological timeline of sensitive data activities in Teams for exfiltration analysis | +
+
|
+
| ChatDLPGetTeamsPolicyCoverage | +Analyzes DLP policy coverage for Teams communications and identifies gaps | +
+
|
+