Security and AI Essentials
Protect your organization with AI-powered, end-to-end security.
Defend Against Threats
Get ahead of threat actors with integrated solutions.
Secure All Your Clouds
Protection from code to runtime.
Secure All Access
Secure access for any identity, anywhere, to any resource.
Protect Your Data
Comprehensive data security across your entire estate.
Recent Blogs
1. Introduction
Enterprise adoption of Generative AI is accelerating rapidly through Microsoft 365 Copilot, Copilot Studio, Azure AI Foundry Agents, Security Copilot, and custom AI agents integ...
Jul 30, 202674Views
1like
0Comments
How Microsoft Security is responsibly bringing agentic vulnerability discovery to customers with Defender class security, sovereignty, compliance, and operational governance.
Jul 30, 2026105Views
1like
0Comments
Why the platform around the model is the real enterprise differentiator
Enterprise AI has reached a turning point. Beyond answering questions, it can now reason over business context, retrieve know...
Jul 29, 2026333Views
3likes
0Comments
Beginning August 1, the final phase of Microsoft Defender Threat Intelligence (MDTI) convergence will be generally available in the Defender portal, giving customers real-time Microsoft threat intell...
Jul 29, 20261.3KViews
2likes
0Comments
Recent Discussions
Purview SDK
I've been spending quite a bit of time working with Purview APIs, The APIs themselves are fine, but after a while I realized I was writing the same authentication, pagination and relationship handling code over and over again. So instead of construction the same code from project to project, I turned it into a python package, and now it's available on PyPI pip install purview-unified-sdk Right now, the SDK supports most of the common operations, such as creating, retrieving, updating and deleting business domains, data products, glossary terms, objectives, key results and etc., It also make it much easier to work with relationships, add group id as a owner, navigate resources and retrieve metadata across the unified catalog. https://niki9001.github.io/purview-unified-sdk/ https://github.com/purview-unified-sdk Feel free to fork the project, submit a pull request or open an issue if you have ideas or suggestionsUnified Catalog - Why I Think About Governance Domains Vertically and “Domains of Data” Horizontally
One of the more useful ways I have found to think about Microsoft Purview is to separate ownership from meaning. For me, that creates two different but connected structures: Vertical = Ownership Governance Domains tell us WHO owns and governs the data. They provide the organisational structure for accountability. A Governance Domain can contain: Data Products → Data Assets → Critical Data Elements → Columns and Attributes It also gives us the governance context around those objects: Ownership Stewardship Accountability Governance responsibilities Data quality Access Controls So when I look at a Governance Domain, I am really asking: Who is responsible for this data? That is the vertical view. Horizontal = Meaning Enterprise Glossary Terms give us a different perspective. Rather than focusing on who owns the data, they can represent what the data means across the organisation. This is what I think of as a “Domain of Data”. I use the phrase “Domain of Data” as a conceptual way of describing an enterprise business concept that can span multiple Governance Domains. Take Personally Identifiable Information (PII) as a simple example. PII is unlikely to fit neatly within a single Governance Domain. It may exist across: Customer information Complaints and incidents HR and work force data Case management Regulatory data Operational systems Contact information Financial and administrative processes Each Governance Domain may own and govern the PII within its own area. But the concept of PII itself spans all of them. That is where an Enterprise Glossary Term becomes particularly useful. It provides a common enterprise definition that cuts horizontally across multiple ownership boundaries. Why the two structures should not be the same It can be tempting to make the Enterprise Glossary hierarchy simply mirror the Governance Domain hierarchy. I think that misses an important opportunity. They answer different questions. Governance Domains WHO owns and governs the data? They represent: Ownership Accountability Organisational responsibility Enterprise Glossary Terms WHAT does the data represent? They represent: Business meaning Shared concepts Enterprise vocabulary The two structures should connect, but they should not simply duplicate each other. One Governance Domain can contain many Domains of Data A Governance Domain may contain many different business concepts. For example, one Governance Domain might contain: PII Customer Data Location Data Financial Data Operational Data The Governance Domain is therefore not necessarily a “type of data”. It is primarily an ownership and governance boundary. One Domain of Data can cross many Governance Domains The reverse is equally important. A single Domain of Data can exist across many Governance Domains. For example, PII might appear in: Governance Domain 01 – Customer and contact data Governance Domain 02 – Complaints and incident data Governance Domain 03 – Employee and work force data Governance Domain 04 – Regulatory and operational data This gives us a many-to-many relationship: One Governance Domain can contain many Domains of Data. One Domain of Data can exist across many Governance Domains. That is the part I think is especially powerful. Where the two structures intersect This is where the model becomes much more valuable. Think about it as: Governance Domain WHO owns it? Enterprise Glossary Term WHAT does it mean? Governed Business Context For example: HR Governance Domain PII Enterprise Glossary Term The result is: The HR-owned instance of an enterprise-wide PII concept. That intersection gives us both ownership and meaning. Why this matters for data consumers Most data consumers do not necessarily know: which Governance Domain owns the data; which platform contains it; which Data Product it belongs to; what the database table is called; or what the individual column names are. They may simply know the business question they are trying to answer. For example: Where do we hold PII? Which Data Products contain Customer information? Where is Location information used? Which Data Assets contain Financial information? This is where the Enterprise Glossary becomes much more than a list of definitions. It becomes a business discovery layer. From business concept to technical data If the relationships are created properly, a user can begin with a business concept and navigate towards the underlying data. For example: Enterprise Glossary Term → Data Products → Data Assets → Critical Data Elements → Columns and Attributes This creates a bridge between: Business meaning ↔ Technical implementation That is a much more useful experience than expecting users to understand the technical structure of the data estate before they can discover anything. Enterprise terms, local terms and CDEs There is also an important distinction between the different types of business metadata. Enterprise Glossary Terms These should represent concepts that have meaning across multiple Governance Domains. Examples might include: PII Customer Organisation Location Financial Information These provide the horizontal enterprise view. Local Glossary Terms These are better suited to terminology that is specific to: a Governance Domain; a business area; a Data Product; or a specialised process. They provide local business context without forcing every term into the enterprise vocabulary. Critical Data Elements CDEs are different again. A Domain of Data may represent a broad business concept such as PII, while CDEs represent individual important data elements such as: Email Address Date of Birth Customer Identifier Postcode That gives us another useful relationship: Enterprise Glossary Term: PII → Critical Data Element: Email Address → Physical Column: customer_email Now the business concept is connected directly to the technical implementation. The principle I keep coming back to The value is not in creating as many glossary terms as possible. It is in applying: The right term → at the right level → connected to the right data That means asking: Is this genuinely an enterprise-wide concept? Should this be local to one Governance Domain? Is this actually a Critical Data Element? What Data Products and Data Assets should it connect to? The quality of those relationships matters far more than the volume of metadata. The bigger picture This is ultimately why I think the horizontal and vertical model is useful. Vertical = Ownership Governance Domains tell us WHO owns and governs the data. Horizontal = Meaning Enterprise Glossary Terms tell us WHAT the data represents across the organisation. And where they intersect: Ownership + Meaning = Governed Business Context That is what allows Microsoft Purview to move beyond simply listing technical assets. Instead, it starts to create a connected view of: Ownership → Business Meaning → Discovery → Governance across the enterprise data estate. For me, that is where the real value of the catalogue starts to appear.33Views0likes0CommentsRescheduled Webinar: What's New in Azure Firewall
Hi everyone! The webinar "What's New in Azure Firewall" that was originally scheduled for August 6th, has been rescheduled to August 26th. You can find more details on our Community Home. We apologize for the inconvenience, and hope to see you there!18Views0likes0CommentsDoes this Unity Catalog → Purview guidance make sense?
I’ve been working through how Azure Databricks Unity Catalog metadata surfaces in Microsoft Purview after a scan, and I’ve created the attached visual to make the relationship easier to understand. The principle I’m trying to communicate is simple: Maintain Databricks-native technical metadata in Unity Catalog → scan supported metadata into Microsoft Purview → use Purview for the wider enterprise governance, discovery and business context. The short guidance accompanying the visual would be: In Azure Databricks: Navigate to Catalog Explorer → Catalogue → Schema → Table/View. From here, maintain metadata such as table comments, column comments and Unity Catalog tags. Some comments can also be AI-generated as a starting point and reviewed before saving. After the Microsoft Purview scan: Find the corresponding Data Asset in Purview and review the surfaced metadata: Table Comment → Data Asset → Description Column Comment → Data Asset → Schema → Column Description Table Tag → Data Asset → Properties → Tags Column Tag → Data Asset → Schema → Tags Column Name / Data Type → Data Asset → Schema Table/View and Column Lineage → Data Asset → Lineage, subject to the relevant prerequisites. The distinction I’m trying to reinforce is that this is not Purview vs Unity Catalog, and it is not about manually duplicating technical metadata. Unity Catalog remains the Databricks-native governance and technical metadata layer, while Purview can consume supported metadata through scanning and place it into the wider enterprise governance context. I’d be interested in feedback from people implementing Purview + Azure Databricks Unity Catalog: Does the visual and navigation guidance make the relationship clear? In particular, are the field mappings and terminology intuitive enough for Data Engineers, Data Stewards and Data Owners, or is there anything you would simplify, rename or clarify?13Views0likes0CommentsMicrosoft Purview, Databricks Unity Catalog and Medallion Architecture
Microsoft Purview, Databricks Unity Catalog and Medallion Architecture three different responsibilities, one governed data ecosystem. I created this visual because these concepts are often mixed together. 🔵 Microsoft Purview = Enterprise Data Governance & Discovery Purview provides the enterprise-wide governance layer across Databricks and other platforms — Governance Domains, Data Products, glossary, Critical Data Elements, ownership, stewardship, metadata, data quality and discovery. 🔴 Databricks Unity Catalog = Databricks Data & AI Governance + Access Control Unity Catalog is not simply an access-management tool. It governs Databricks data and AI assets, including catalogs, schemas, tables, permissions, technical metadata, lineage, auditing and discovery. 🥉🥈🥇 Medallion = Data Engineering Bronze → Silver → Gold describes how data is progressively refined. It is not a governance hierarchy. That distinction is important: Governance Domains answer: 👉 Who owns and governs the data? Bronze / Silver / Gold answer: 👉 What stage of engineering and refinement is the data in? And Gold does not automatically equal Data Product. My preferred enterprise model is therefore: Purview → Enterprise Governance & Discovery Unity Catalog → Databricks Governance & Access Medallion → Data Engineering & Refinement The goal isn't Purview vs Unity Catalog. It is clearly defining which platform is authoritative for which responsibility and connecting the metadata and lineage into a coherent governance model. The distinction between governance domains (who owns the data) and Medallion layers (what stage of refinement) is one that trips up many implementation teams. In practice, when Microsoft Fabric is the analytics platform, Purview becomes the authoritative governance layer across both Fabric OneLake and Databricks, with Unity Catalog handling Databricks-internal access. Connecting lineage metadata across both is what creates a truly coherent governance model.24Views0likes0CommentsNew Blog | Microsoft Defender for Endpoint’s Safe Deployment Practices
By jweberMSFT For customers it is key to understand that software vendors use safe deployment practices that help them build resilient processes that maintain productivity. This blog addresses Microsoft Defender for Endpoint’s architectural design and its approach to delivering security updates, which is grounded in Safe Deployment Practices (SDP). Microsoft Defender for Endpoint helps protect organizations against sophisticated adversaries while optimizing for resiliency, performance, and compatibility, following best practices for managing security tools in Windows. Security tools running on Windows can balance security and reliability through careful product design, as described in this post by David Weston. Security vendors can use optimized sensors which operate within kernel mode for data collection and enforcement, limiting the risk of reliability issues. The remainder of the security solution, including managing updates, loading content, and user interaction, can occur isolated within user mode, where any reliability issues are less impactful. This architecture enables Defender for Endpoint to limit its reliance on kernel mode while protecting customers in real-time. Read the full post here: Microsoft Defender for Endpoint’s Safe Deployment PracticesSentinel - Defender XDR KQL Queries Library
Hello all, I’ve been building something over the past few weeks that I think the security community might find useful. https://goxdr.fyi is a searchable KQL query library for Microsoft Sentinel and Defender XDR. The name comes from a nickname my colleagues gave me (GoX) combined with XDR. I also picked up https://goxdr.fyi as a short and easy to remember domain for it. You can check it out here: https://goxdr.fyi The idea came from my own day to day work as someone working in IAM and SOC operations. I constantly find myself writing and refining KQL queries for threat hunting, detection engineering and incident investigation. Over time I realized I had a growing collection of queries that I kept going back to and I thought why not make these available to others? It currently has 117 queries covering identity security, BEC/AiTM detection, NTLM and LDAP attack hunting, OAuth governance, AI/Copilot security, Sentinel alert trending, SOC performance metrics and more. Some of these queries are ones I wrote from scratch based on real scenarios I encountered in production environments. Others are community queries I tested and validated in my own setup. Only the ones I found genuinely useful and that actually worked against real data made it in. Each query comes with a description explaining what it detects and why it matters, along with severity levels, platform tags (Sentinel, XDR or both) and a copy button so you can paste it directly into Advanced Hunting or use it as the basis for an Analytics Rule. The site is open source, hosted on GitHub Pages and licensed under CC BY 4.0. No sign-up, no paywall, no tracking. The source is available. I’ll keep adding queries as new scenarios come up. If there’s enough interest I’m also considering adding Cortex XQL queries for Palo Alto environments. Suggestions, feedback or ideas for new detections are always welcome. Feel free to reach out. ThanksPurview archive shipped. Delete policy is still armed.
Roadmap 561208 went GA over the last few weeks with very little noise. Purview retention policies in Data Lifecycle Management can now move inactive OneDrive and SharePoint content into Microsoft 365 Archive. The framing is storage cost. I want to talk about something else, because I think there's a gap here that's going to catch people out, and I'd like to know whether anyone else is seeing it. Archive is a storage tier. It is not a retention state. An archived SharePoint site stays fully in scope of every retention policy that applied to it while it was active. Nothing about archiving protects content. Now layer that onto conflict resolution. Retention beats deletion, so a site policy set to delete after 2 years goes dormant while a label is retaining the item. Dormant, not cancelled. So picture this: A file carries a retention label with a 4-year retention period. The site it lives on has a delete-after-2-years retention policy. The label's end-of-retention action is deactivate retention settings. For four years, everything looks correct. The label holds. The delete policy sits there doing nothing. Then the label reaches end of retention and deactivates. The shield is gone. The delete instruction wakes up, unopposed, two years overdue, and the file goes. Not to archive. Just gone. The reflex here is "explicit wins over implicit." It doesn't apply. That principle only arbitrates between competing delete actions. A label that expires with no delete action of its own brings nothing to the contest. There is no explicit action to outrank the policy with. "Do nothing" sounds like a safe default. It's actually a decision to stop defending the file. Right now you cannot set a label to archive at end of retention. The options are deactivate, delete automatically, disposition review, or hand it to a Power Automate flow. Archive isn't on the list. Microsoft shipped archive at the policy level and left the label level to flows and webhooks. That reads to me like they know the gap exists and haven't decided how to close it. And here's my suspicion about why this shipped now. Archived content is excluded from Copilot indexing. That's Microsoft's own framing in the message center post. Which suggests this feature is going to evolve on Copilot's roadmap rather than records management's. The moment "archive" becomes the button you press to clean up Copilot's answers, people will press it constantly, at scale, without once checking what policy is sitting underneath. Meanwhile Exchange has nothing. Purview retention still can't move mail into an archive mailbox, and we're all still running MRM tags next to Purview years after being told MRM was legacy. Has anyone hit the deactivate-into-delete scenario in a live tenant, or is this still theoretical? And does anyone read the label-level gap differently than I do? Genuinely open to being told I've got this wrong.32Views0likes0CommentsPublished Glossary Terms Not Appearing When Editing Microsoft Purview Data Assets
Help and Support for All Problem Published glossary terms were not available for selection when editing Data Map assets in Microsoft Purview. Although the glossary terms had been created and published within Governance Domains, and the user had the appropriate permissions, the Glossary Terms dropdown remained empty. This prevented glossary terms from being assigned to data assets or individual columns. Symptoms The following behaviour was observed: Published glossary terms existed within Governance Domains in the Unified Catalog. User permissions had been verified and were correctly configured. The Glossary Terms field was visible when editing a Data Map asset. The dropdown opened successfully but did not display any available glossary terms. Glossary terms could not be associated with data assets or columns. Root Cause The issue occurred because Asset Curation had not been enabled in Microsoft Purview. Although glossary terms had been created and published within Governance Domains in the Unified Catalog, the Data Map asset curation experience had not been configured to use Unified Catalog glossary terms. As a result, the Glossary Terms field was displayed when editing an asset, but no terms were available for selection. Microsoft Purview requires Asset Curation to be enabled and configured before Unified Catalog glossary terms can be assigned to Data Map assets and columns. Resolution The following steps resolved the issue: Confirmed that no Classic Glossaries, Classic Glossary Terms or Term Templates existed in the Purview account. Enabled Asset Curation (Preview). Configured Microsoft Purview to use Unified Catalog Glossary Terms. Completed the Asset Curation configuration wizard. Edited a Data Map asset and verified that published glossary terms were now displayed. Successfully assigned glossary terms to both Data Map assets and individual columns. Because no Classic Glossary content existed, there was no glossary content that required migration. Outcome After Asset Curation was enabled and configured, published Unified Catalog glossary terms became available in the Glossary Terms dropdown when editing Data Map assets. Glossary terms could then be successfully assigned to both assets and columns. Key Takeaway Creating and publishing glossary terms within Governance Domains is not sufficient on its own. To use Unified Catalog glossary terms when curating Data Map assets and columns, Asset Curation must also be enabled and configured to use Unified Catalog Glossary Terms.40Views0likes0CommentsJuly 23rd Webinar Canceled: What's New in Azure Bastion
Hello everyone, Unfortunately, the webinar we had scheduled for July 23rd on What's New in Azure Bastion has been canceled for now. We apologize for any inconvenience and appreciate you all for being part of our community. All the best!158Views0likes0CommentsAsk Microsoft Anything: Attack Disruption with Microsoft Defender on July 14
Hey Defender enthusiasts! Just wanted to remind you all that we are holding an AMA next week at 9AM PST on July 14 with the Attack Disruption team. Come learn about Attack Disruption—Microsoft Defender’s built‑in, AI-powered capability that stops in‑progress attacks at machine speed by analyzing attacker intent, identifying compromised assets, and containing threats before they spread. Bring your questions and hear directly from product experts on real‑world scenarios and best practices. Hope to see you there! Event Link: Ask Microsoft Anything: Microsoft Defender Attack Disruption | Microsoft Community Hub58Views0likes0CommentsNeed information on generating sample events for Threat Intelligence" (both duplicate posts)
Two things are tripping this up, and they're common mix-ups: First — Attack Simulation Training doesn't generate Threat Intelligence events. If you used the built-in phishing simulator, its logs only show up under Email & collaboration → Attack simulation training → Simulations — they're intentionally excluded from real Threat Intelligence telemetry. That's likely why nothing's showing up even though you ran a campaign. Second — your EICAR test should actually work, but check the right place: not the generic Office 365 Management Activity API's AuditLogRecordType page in isolation — go specifically to the RecordType values used for Defender for Office 365 threat events: 28 = ThreatIntelligence (phishing/malware events) 41 = ThreatIntelligenceUrl (Safe Links time-of-click/block events) Plus ThreatIntelligenceAtpContent, ThreatFinder, MSTIC To reliably generate one: Confirm Purview audit logging is enabled for the tenant first — if it isn't, nothing downstream gets logged regardless of what you trigger. From an external mailbox, send a test user the EICAR string as a .txt attachment (exact 68-byte string, see Microsoft's anti-malware testing doc). Defender for Office 365 should detect and quarantine it. Verify it landed first in the portal UI: Email & collaboration → Explorer → Malware tab — if it's there, the underlying ThreatIntelligence record exists and the Management API call should return it (allow a short delay; these aren't instant). For the Safe Links side, send a known-safe-but-flagged test URL (Microsoft publishes test URLs for this) to trigger ThreatIntelligenceUrl. If it shows up in Explorer but still doesn't appear via the Management API, that's usually an API subscription/permission issue (you need an active subscription to the DLP.All or relevant Office 365 Management API content type, not just Graph permissions) — worth checking separately from the detection side.Can the Microsoft Defender portal show the server details as per security group?
Yes — this is exactly what Device Groups + RBAC are designed for in Microsoft Defender (assuming you're managing these servers through Defender for Endpoint, which is the typical path for cross-vendor server monitoring). The model: Device groups are the scoping unit (not Entra security groups directly) — create one per vendor/company (e.g., "Company A Servers", "Company B Servers"), using a matching rule (tag, OS, name pattern, etc.) to auto-assign devices. RBAC roles then get tied to an Entra security group and granted access to only specific device groups. So: Company A's people go in an Entra group → that group is assigned an MDE role scoped to "Company A Servers" only → they only ever see those devices, alerts, and incidents in the portal. You as admin keep your existing Global Admin/Security Admin role (or get added to both device groups' RBAC scope), so you retain visibility across both. Path: Settings → Endpoints → Permissions → Device groups to create the groups, then Permissions → Roles to create a role and tie it to your Entra security group with that device group as the scope. One thing to verify before committing to this design: this RBAC model affects what shows in alerts, incidents, advanced hunting (scoped automatically), and inventory — but make sure nobody from Company A/B also needs organization-wide Defender features like global threat analytics, since those aren't scopable the same way. If you're actually talking about servers monitored via Defender for Cloud (Azure subscription-based, not MDE-onboarded), the equivalent mechanism is Azure RBAC at the subscription/resource group level (assign Security Reader scoped to the RG containing Company A's VMs) — different mechanism, same outcome. Worth clarifying which portal/product this is so the right one gets recommended.Microsoft Defender Incident – Handling incident severity change
There's no dedicated history/audit endpoint for field-level transitions (like "this incident went from Low → High at timestamp X") in the /security/incidents Graph API — the incident object only exposes the current severity plus a lastUpdateDateTime, not a change log. So this isn't something you're missing; it genuinely doesn't exist as a queryable history today. Also worth knowing before you build around it: Graph change notifications (webhooks) are not documented as supported for /security/incidents — subscription/webhook support is only documented for the legacy /security/alerts resource, and that resource is deprecated with removal expected around April 2026. So polling is currently the only supported pattern for incidents specifically, not a limitation of your approach — there's no webhook alternative to fall back to yet. Given that, the fix is in your polling strategy, not in finding a hidden feature: instead of filtering once at creation time and then ignoring the incident, poll using $filter=lastUpdateDateTime gt {last_poll_timestamp}. Since lastUpdateDateTime bumps on any property change — including a severity escalation — this catches incidents that started as Low/Informational and later got escalated, without re-fetching everything. A pattern that works well in practice: GET /security/incidents?$filter=lastUpdateDateTime gt {last_poll_time}&$orderby=lastUpdateDateTime asc Then in your own store, diff the incoming severity against what you last recorded for that id to detect the transition yourself — you're effectively reconstructing the history client-side since the API won't give it to you natively. Store (incidentId, severity, lastUpdateDateTime) on each poll and compare. One gotcha: this still won't tell you the exact moment the severity changed if multiple fields changed between polls — only that it changed sometime between your last two poll timestamps. If you need second-level precision on transition timing, you'd need to poll more frequently (your 5-minute interval is probably fine for SOC triage purposes, but not for precise SLA timestamping).Exempt a specific container in MDC
You don't need a full exemption for this — the built-in policy behind "Immutable (read-only) root filesystem should be enforced for containers" already supports per-container and per-image exclusions natively, which is more precise than exempting at the resource/cluster level. This recommendation is implemented via the Azure Policy Add-on for Kubernetes (Gatekeeper constraint) as part of Defender for Cloud's data plane hardening. The underlying policy definition supports these parameters: excludedContainers — exclude by container name excludedImages — exclude by image (supports prefix matching, e.g. myregistry.azurecr.io/legacy-app:*) excludedNamespaces — exclude entire namespaces (e.g., kube-system, useful for system pods that legitimately can't run read-only) To configure: Defender for Cloud → Recommendations → select this recommendation → Take action tab, where you can set these parameters directly without touching raw policy JSON. Alternatively, if you manage policy via Environment Settings → Security policies → Standards, you can set the same parameters on the standard assignment. Given you said multiple containers across airflow/db1, airflow/sql1, etc. show "Unhealthy" — if these are legitimate exceptions (e.g., a database container that needs to write to its filesystem by design, not just a misconfiguration), excludedContainers naming each container is the cleanest fix and keeps the recommendation enforcing everywhere else in the cluster. I'd reserve a full policy exemption (Azure Policy exemption resource) for cases where you need it tracked for compliance/audit purposes specifically — the parameter-based exclusion is the more "native" and maintainable fix for ongoing operational cases like this.23Views0likes0CommentsExempt - Azure CSPM Recommendation" (Terraform exemption
The reason you're not finding a standalone policyAssignmentId/policyDefinitionId for this specific recommendation is that it isn't a standalone assignment — it's one control inside the built-in CSPM initiative (the "ASC Default" / Microsoft Cloud Security Benchmark assignment). That initiative does have an assignment ID; you just need to target the specific control within it, not look for a separate one. In azurerm_resource_policy_exemption (or the subscription/resource-group variants), the relevant fields are: policy_assignment_id → the ID of the initiative assignment (ASC Default / MCSB), not a per-recommendation assignment policy_definition_reference_ids → an array scoping the exemption to just this one control instead of the whole initiative resource "azurerm_resource_policy_exemption" "function_app_network_exemption" { name = "exempt-function-network-restriction" resource_id = azurerm_linux_function_app.example.id policy_assignment_id = data.azurerm_subscription_policy_assignment.asc_default.id policy_definition_reference_ids = [ "<reference-id-for-the-specific-control>" ] exemption_category = "Waiver" # or "Mitigated" if an equivalent control exists expires_on = "2026-12-31T00:00:00Z" } To find the policy_definition_reference_id for this specific control: in the Azure Portal, go to Policy → Definitions, search for "Restricted network access should be configured on Internet exposed Function app" to get its definition ID, then open the initiative definition (ASC Default) and find the matching entry in its policyDefinitions[].policyDefinitionReferenceId array — that string is what goes in the array above. Two things worth deciding upfront before automating this: Waiver vs Mitigated — if you've genuinely restricted access another way (e.g., Private Endpoint), use Mitigated so it's distinguishable from accepted risk in reporting. Consider whether the exemption belongs at the resource scope (just this Function App) vs resource group/subscription — narrower is safer, but if you have a pattern of similar apps, a tagged-based resourceSelectors block can scale this without per-resource blocks.Remediation Workflow Automation — Biggest Gap vs. Competing Exposure Management Platforms?
Exposure graph and attack path correlation in MSEM are genuinely strong — the cross-domain visibility (endpoints, identities, cloud, external surface) is one of the better implementations I've worked with, especially for shops already standardized on the Microsoft stack. The gap I keep running into is closed-loop remediation orchestration. Right now, when an attack path or critical exposure is identified, there's no native way to auto-generate a ticket, assign ownership, and track an SLA against it — that handoff still has to be built externally (Logic Apps, Sentinel playbooks, or a 3rd-party ITSM integration). This isn't just my experience; it's echoed in published Gartner Peer Insights reviews of the product, where users specifically flag the absence of in-platform workflows to raise tickets automatically and route them to the owning team. For comparison, Qualys built this natively into their Enterprise TruRisk Platform (QFlow) — automatic ticket creation in ServiceNow/Jira, ownership assignment, and SLA tracking, all without manual handoffs. Tenable One markets "workflow automation" as a core differentiator of its unified platform for the same reason: it's what turns continuous detection into continuous risk reduction, not just a better dashboard. Questions for the team / community: Is closed-loop ticketing/SLA tracking on the roadmap natively, or is the expectation that this stays external (Logic Apps/Sentinel)? For those running MSEM at scale — how are you currently bridging this gap operationally? Custom playbooks, or a 3rd-party orchestration layer on top?Microsoft Defender (GCC) - User Submitted "Mark and Notify" for Third Party Phishing Simulations
Our Microsoft 365 tenant is in the GCC environment, and we use a third party phishing simulation platform along with the built in Outlook Report Message button (not a third party reporting add in). When a user correctly reports one of our simulated phishing emails, the message appears in Microsoft Defender > User Submitted as expected. The problem is what happens next. When we select Mark and notify, the only available options are: Phishing Spam No threat found There is no option to notify the user that the email was actually part of a phishing simulation. This creates a difficult situation: If we choose No threat found, Defender tells the user the message was safe, making it appear they incorrectly reported the email even though they did exactly what we trained them to do. If we choose Phishing, the user receives the correct feedback, but the message is counted as a real phishing event, affecting our Defender metrics and potentially generating false incidents and reporting. It feels like we're stuck in a design loop where neither option provides the desired outcome. My questions are: Is there a supported way in Microsoft Defender (particularly GCC) to notify users that a reported message was a simulated phishing email when using the native Outlook Report Message button? Is this capability available in Commercial tenants but not GCC, or is it unavailable across all environments? If this functionality does not exist, what is the recommended process for submitting a feature request specifically for the GCC version of Microsoft Defender? This seems like a valuable enhancement for organizations that use third party phishing simulation platforms while relying on Microsoft's native reporting experience. Has anyone else found a good workflow for this scenario?Reminder: Next Tuesday 6/23 at 9AM PST we will be hosting an 'Ask Microsoft Anything' session on Tech Community for the Sentinel SIEM Migration Experience!
Join us for a live demo and AMA on the Microsoft Sentinel SIEM migration experience. We’ll show how the experience helps teams move from legacy SIEMs like Splunk and QRadar into Microsoft Sentinel with a more guided, lower-friction path. We’ll cover what it does today, how it works, and the questions customers ask most, then open it up for live Q&A. Link here: Ask Microsoft Anything: The Microsoft Sentinel SIEM Migration Experience Hope to see you there!45Views0likes0CommentsCampaign-Centric Hunting with Microsoft Defender XDR and Microsoft Sentinel
Phishing investigations usually start with one suspicious email. A user reports a message. An alert is generated. An analyst opens the email details, checks the sender, reviews the URL, and tries to understand whether the message is malicious. That is a normal starting point. However, in a real SOC investigation, one email is rarely the full story. Attackers usually operate in campaigns. They reuse sender infrastructure, similar subjects, URLs, payloads, templates, and delivery techniques. A single email may be only one part of a wider phishing or malware campaign targeting multiple users. This is why campaign-centric hunting is important. I wrote this article from the perspective of a SOC analyst who often needs to move quickly from a single suspicious email to the full campaign impact. The goal is simple: use Microsoft Defender XDR and Microsoft Sentinel together to understand who was targeted, what was delivered, who clicked, and what should be prioritized first. Why Campaign-Centric Hunting When investigating a phishing or malware email, analysts usually need to answer practical questions: How many users received messages from the same campaign? Were the messages blocked, junked, delivered, or remediated? Did any user click the URL? Did anyone click through a Safe Links warning? Were any priority or high-risk users affected? Was the email removed after delivery? Are there related Defender XDR or Sentinel incidents? If we only investigate one message, we may miss the bigger picture. Campaign-centric hunting helps the SOC move from this question: Is this email malicious? To this question: What is the full impact of this campaign? That shift is important because the response priority should be based on campaign impact, not only on a single alert. What Campaign Views Provides Campaign Views in Microsoft Defender for Office 365 help analysts investigate coordinated email attacks such as phishing and malware campaigns. From Campaign Views, analysts can review campaign-level information such as: Campaign name Campaign type Campaign subtype Targeted users Inboxed messages Clicked users Visited links Sender domains Sender IPs Payload URLs Delivery actions Campaign timeline Campaign flow This is useful during triage because it quickly shows whether an email is part of a wider attack. For example, one reported phishing message may look small at first. But if Campaign Views shows that the same campaign targeted 50 users, delivered messages to 15 inboxes, and had 2 users click the URL, the investigation becomes much more urgent. Where CampaignInfo Fits The CampaignInfo table gives analysts a KQL-based way to query campaign-related data. Some useful fields are: Field Purpose CampaignId Unique identifier for the campaign CampaignName Name of the campaign CampaignType Campaign category, such as Phish or Malware CampaignSubtype Additional context, such as brand being phished or malware family NetworkMessageId Unique identifier for the email message RecipientEmailAddress Recipient affected by the campaign Timestamp Time when the event was recorded For correlation, the most important field is usually: NetworkMessageId This field can help connect campaign data with other Defender XDR email tables, including: EmailEvents UrlClickEvents EmailPostDeliveryEvents EmailAttachmentInfo EmailUrlInfo This makes CampaignInfo a useful pivot table for campaign-level hunting. Important note: CampaignInfo is currently documented as Preview. Before using these queries in production analytics rules, validate the table availability, schema, and results in your own tenant. Practical Scenario An analyst receives a phishing alert in Microsoft Defender XDR. The alert is related to a user who received a suspicious email with a credential-harvesting URL. The analyst opens Campaign Views and sees that the message belongs to a wider phishing campaign. At that point, the investigation should not stop with the original user. The analyst should now ask: Who else received this campaign? How many messages were delivered? Which users clicked? Did any users click through the Safe Links warning? Were the messages removed after delivery? Are there related incidents in Microsoft Sentinel? The investigation flow could look like this: Start from Campaign Views in Microsoft Defender XDR. Identify the campaign details. Use CampaignInfo to list affected users and messages. Join with EmailEvents to validate delivery status. Join with UrlClickEvents to identify user interaction. Join with EmailPostDeliveryEvents to confirm remediation. Review related Microsoft XDR incidents in Microsoft Sentinel. Prioritize response based on campaign impact. Query 1: List Recent Campaigns The first query gives a simple overview of recent campaigns. CampaignInfo | where Timestamp > ago(14d) | summarize FirstSeen = min(Timestamp), LastSeen = max(Timestamp), AffectedUsers = dcount(RecipientEmailAddress), Messages = dcount(NetworkMessageId) by CampaignId, CampaignName, CampaignType, CampaignSubtype | order by LastSeen desc This helps analysts quickly identify campaigns that affected the organization during the selected period. Useful questions to ask from this output: Which campaigns are most recent? Which campaigns affected the most users? Are the campaigns phishing, malware, or spam? Is there a specific brand or malware family in the subtype? Are similar campaigns appearing repeatedly? Query 2: Understand Delivery Impact After identifying campaigns, the next step is to understand delivery impact. A campaign that was fully blocked is different from a campaign that reached user inboxes. let Campaigns = CampaignInfo | where Timestamp > ago(14d) | project CampaignId, CampaignName, CampaignType, CampaignSubtype, NetworkMessageId, RecipientEmailAddress; Campaigns | join kind=leftouter ( EmailEvents | where Timestamp > ago(14d) | project NetworkMessageId, RecipientEmailAddress, Subject, SenderFromAddress, SenderFromDomain, SenderIPv4, DeliveryAction, DeliveryLocation, ThreatTypes, DetectionMethods, Timestamp ) on NetworkMessageId, RecipientEmailAddress | summarize Messages = dcount(NetworkMessageId), AffectedUsers = dcount(RecipientEmailAddress), Subjects = make_set(Subject, 5), SenderDomains = make_set(SenderFromDomain, 10), SenderIPs = make_set(SenderIPv4, 10) by CampaignId, CampaignName, CampaignType, CampaignSubtype, DeliveryAction, DeliveryLocation | order by AffectedUsers desc, Messages desc This query helps separate campaigns that were blocked from campaigns that actually reached users. From a SOC perspective, delivered messages deserve closer attention, especially if they reached the inbox. Query 3: Identify Users Who Clicked Campaign URLs Delivery is important, but clicks usually increase the priority of the incident. This query joins campaign data with UrlClickEvents. let Campaigns = CampaignInfo | where Timestamp > ago(14d) | project CampaignId, CampaignName, CampaignType, CampaignSubtype, NetworkMessageId, RecipientEmailAddress; Campaigns | join kind=inner ( UrlClickEvents | where Timestamp > ago(14d) | project NetworkMessageId, AccountUpn, Url, ActionType, IsClickedThrough, ThreatTypes, DetectionMethods, IPAddress, Workload, ClickTime = Timestamp ) on NetworkMessageId | summarize FirstClick = min(ClickTime), LastClick = max(ClickTime), ClickEvents = count(), ClickedUsers = dcount(AccountUpn), ClickThroughUsers = dcountif(AccountUpn, IsClickedThrough == true), ClickedUrls = make_set(Url, 10), SourceIPs = make_set(IPAddress, 10) by CampaignId, CampaignName, CampaignType, CampaignSubtype | order by ClickThroughUsers desc, ClickedUsers desc, LastClick desc This query helps identify campaigns where users interacted with the payload. If a user clicked a phishing URL, the next step should usually include identity-focused investigation, such as reviewing sign-in activity, MFA status, session activity, and possible risky sign-ins. Query 4: Focus on Click-Through Events Safe Links may block access to a malicious site. In some cases, however, a user may continue through a warning page. Those cases should be reviewed carefully. let Campaigns = CampaignInfo | where Timestamp > ago(30d) | project CampaignId, CampaignName, CampaignType, CampaignSubtype, NetworkMessageId, RecipientEmailAddress; Campaigns | join kind=inner ( UrlClickEvents | where Timestamp > ago(30d) | where IsClickedThrough == true | project NetworkMessageId, AccountUpn, Url, ActionType, ThreatTypes, IPAddress, ClickTime = Timestamp ) on NetworkMessageId | project ClickTime, CampaignId, CampaignName, CampaignType, CampaignSubtype, AccountUpn, RecipientEmailAddress, Url, ActionType, ThreatTypes, IPAddress | order by ClickTime desc This is one of the most useful views during incident response. A click-through event does not automatically mean compromise, but it is a strong reason to investigate the user account further. Query 5: Confirm Post-Delivery Remediation A malicious message may be delivered first and removed later by ZAP, AIR, or manual remediation. This query joins CampaignInfo with EmailPostDeliveryEvents. let Campaigns = CampaignInfo | where Timestamp > ago(30d) | project CampaignId, CampaignName, CampaignType, CampaignSubtype, NetworkMessageId, RecipientEmailAddress; Campaigns | join kind=leftouter ( EmailPostDeliveryEvents | where Timestamp > ago(30d) | project NetworkMessageId, RecipientEmailAddress, RemediationTime = Timestamp, Action, ActionType, ActionTrigger, ActionResult, DeliveryLocation, SourceLocation ) on NetworkMessageId, RecipientEmailAddress | summarize RemediatedMessages = dcountif(NetworkMessageId, isnotempty(ActionType)), RemediationTypes = make_set(ActionType, 10), RemediationResults = make_set(ActionResult, 10), LastRemediation = max(RemediationTime) by CampaignId, CampaignName, CampaignType, CampaignSubtype | order by LastRemediation desc This helps answer a very important question: Were the delivered malicious messages actually removed? This is useful for both SOC triage and reporting because it shows not only detection, but also response. Query 6: Campaign Blast Radius Summary The following query combines campaign, delivery, click, and remediation data into one campaign-level view. let TimeRange = 30d; let Campaigns = CampaignInfo | where Timestamp > ago(TimeRange) | project CampaignId, CampaignName, CampaignType, CampaignSubtype, NetworkMessageId, RecipientEmailAddress; let Delivery = EmailEvents | where Timestamp > ago(TimeRange) | summarize DeliveryActions = make_set(DeliveryAction, 10), DeliveryLocations = make_set(DeliveryLocation, 10), DeliveredMessages = dcountif(NetworkMessageId, DeliveryAction =~ "Delivered"), JunkedMessages = dcountif(NetworkMessageId, DeliveryAction =~ "Junked"), BlockedMessages = dcountif(NetworkMessageId, DeliveryAction =~ "Blocked"), Subjects = make_set(Subject, 5), SenderDomains = make_set(SenderFromDomain, 10) by NetworkMessageId, RecipientEmailAddress; let Clicks = UrlClickEvents | where Timestamp > ago(TimeRange) | summarize ClickEvents = count(), ClickThroughEvents = countif(IsClickedThrough == true), FirstClick = min(Timestamp), LastClick = max(Timestamp), ClickedUrls = make_set(Url, 10) by NetworkMessageId; let Remediation = EmailPostDeliveryEvents | where Timestamp > ago(TimeRange) | summarize RemediationActions = make_set(ActionType, 10), LastRemediation = max(Timestamp) by NetworkMessageId, RecipientEmailAddress; Campaigns | join kind=leftouter Delivery on NetworkMessageId, RecipientEmailAddress | join kind=leftouter Clicks on NetworkMessageId | join kind=leftouter Remediation on NetworkMessageId, RecipientEmailAddress | summarize AffectedUsers = dcount(RecipientEmailAddress), Messages = dcount(NetworkMessageId), DeliveredMessages = sum(DeliveredMessages), JunkedMessages = sum(JunkedMessages), BlockedMessages = sum(BlockedMessages), TotalClickEvents = sum(ClickEvents), ClickThroughEvents = sum(ClickThroughEvents), Subjects = make_set(Subjects, 10), SenderDomains = make_set(SenderDomains, 10), ClickedUrls = make_set(ClickedUrls, 10), RemediationActions = make_set(RemediationActions, 10), LastClick = max(LastClick), LastRemediation = max(LastRemediation) by CampaignId, CampaignName, CampaignType, CampaignSubtype | extend SuggestedPriority = case( ClickThroughEvents > 0, "High", TotalClickEvents > 0, "Medium", DeliveredMessages > 0, "Medium", "Low" ) | order by SuggestedPriority asc, AffectedUsers desc, Messages desc This type of query can be useful during hunting sessions, incident review, and campaign reporting. The goal is not only to collect more data. The goal is to help the analyst decide what needs attention first. Correlating Campaign Activity with Microsoft Sentinel When Microsoft Defender XDR is connected to Microsoft Sentinel, incidents and alerts can be synchronized into the Sentinel incident queue. This allows the SOC to correlate campaign-related email activity with other security signals, such as: Suspicious sign-ins Identity alerts Endpoint alerts Cloud app activity OAuth consent activity Data exfiltration attempts Related Microsoft XDR incidents For example, if a user clicked a phishing URL, the SOC can then review whether the same user had suspicious sign-in activity shortly after the click. The following query is a simple starting point for reviewing Microsoft XDR incidents in Microsoft Sentinel. SecurityIncident | where TimeGenerated > ago(30d) | where ProviderName == "Microsoft XDR" | where Title has_any ("phish", "phishing", "email", "malware", "campaign") | summarize Incidents = count(), HighSeverity = countif(Severity == "High"), MediumSeverity = countif(Severity == "Medium"), Closed = countif(Status == "Closed"), Active = countif(Status == "Active") by bin(TimeGenerated, 1d) | order by TimeGenerated desc This query does not replace campaign hunting. It simply helps analysts understand how email-related activity is represented in the Sentinel incident queue. Suggested SOC Workflow A practical campaign-centric workflow could look like this: Step 1: Start from Campaign Views Review campaigns with delivered messages, clicked users, visited links, or high user impact. Step 2: Pivot to KQL Use CampaignInfo to list campaign-related messages and affected recipients. Step 3: Validate Delivery Join with EmailEvents to confirm whether messages were blocked, junked, delivered, or replaced. Step 4: Review User Interaction Join with UrlClickEvents to identify users who clicked URLs or clicked through Safe Links warnings. Step 5: Confirm Remediation Join with EmailPostDeliveryEvents to confirm whether delivered messages were removed after delivery. Step 6: Correlate in Sentinel Review related Microsoft XDR incidents and correlate with identity, endpoint, and cloud activity. Step 7: Decide Response Depending on the impact, the SOC may decide to: Escalate the incident Notify affected users Review user sign-ins Revoke user sessions Reset passwords Block sender domains or URLs Submit false negatives Create a watchlist for related indicators Tune analytics rules or response processes Suggested Priority Logic Not every campaign needs the same level of response. A simple triage model could be: Condition Suggested priority Campaign blocked before delivery Low Campaign delivered to junk Low to Medium Campaign delivered to inbox Medium Campaign delivered to multiple inboxes Medium to High User clicked URL High User clicked through warning High Priority account clicked High Click followed by suspicious sign-in Critical This model should be adapted to each organization’s risk profile and response process. Limitations and Things to Validate Before using this approach in production, validate the following: Defender for Office 365 Plan 2 availability Campaign Views permissions CampaignInfo table availability Defender XDR connector configuration Advanced hunting event streaming Field names in your environment Retention period Data latency Join behavior using NetworkMessageId Whether click events can be joined to email metadata in all cases One important limitation is that some URL click events may not join cleanly with email metadata. For example, clicks from Drafts or Sent Items may not have the same message metadata available for correlation. Also, because CampaignInfo is currently documented as Preview, I would avoid depending on it alone for critical production automation without testing and validation.