investigation
58 TopicsUnderstand New Sentinel Pricing Model with Sentinel Data Lake Tier
Introduction on Sentinel and its New Pricing Model Microsoft Sentinel is a cloud-native Security Information and Event Management (SIEM) and Security Orchestration, Automation, and Response (SOAR) platform that collects, analyzes, and correlates security data from across your environment to detect threats and automate response. Traditionally, Sentinel stored all ingested data in the Analytics tier (Log Analytics workspace), which is powerful but expensive for high-volume logs. To reduce cost and enable customers to retain all security data without compromise, Microsoft introduced a new dual-tier pricing model consisting of the Analytics tier and the Data Lake tier. The Analytics tier continues to support fast, real-time querying and analytics for core security scenarios, while the new Data Lake tier provides very low-cost storage for long-term retention and high-volume datasets. Customers can now choose where each data type lands—analytics for high-value detections and investigations, and data lake for large or archival types—allowing organizations to significantly lower cost while still retaining all their security data for analytics, compliance, and hunting. Please flow diagram depicts new sentinel pricing model: Now let's understand this new pricing model with below scenarios: Scenario 1A (PAY GO) Scenario 1B (Usage Commitment) Scenario 2 (Data Lake Tier Only) Scenario 1A (PAY GO) Requirement Suppose you need to ingest 10 GB of data per day, and you must retain that data for 2 years. However, you will only frequently use, query, and analyze the data for the first 6 months. Solution To optimize cost, you can ingest the data into the Analytics tier and retain it there for the first 6 months, where active querying and investigation happen. After that period, the remaining 18 months of retention can be shifted to the Data Lake tier, which provides low-cost storage for compliance and auditing needs. But you will be charged separately for data lake tier querying and analytics which depicted as Compute (D) in pricing flow diagram. Pricing Flow / Notes The first 10 GB/day ingested into the Analytics tier is free for 31 days under the Analytics logs plan. All data ingested into the Analytics tier is automatically mirrored to the Data Lake tier at no additional ingestion or retention cost. For the first 6 months, you pay only for Analytics tier ingestion and retention, excluding any free capacity. For the next 18 months, you pay only for Data Lake tier retention, which is significantly cheaper. Azure Pricing Calculator Equivalent Assuming no data is queried or analyzed during the 18-month Data Lake tier retention period: Although the Analytics tier retention is set to 6 months, the first 3 months of retention fall under the free retention limit, so retention charges apply only for the remaining 3 months of the analytics retention window. Azure pricing calculator will adjust accordingly. Scenario 1B (Usage Commitment) Now, suppose you are ingesting 100 GB per day. If you follow the same pay-as-you-go pricing model described above, your estimated cost would be approximately $15,204 per month. However, you can reduce this cost by choosing a Commitment Tier, where Analytics tier ingestion is billed at a discounted rate. Note that the discount applies only to Analytics tier ingestion—it does not apply to Analytics tier retention costs or to any Data Lake tier–related charges. Please refer to the pricing flow and the equivalent pricing calculator results shown below. Monthly cost savings: $15,204 – $11,184 = $4,020 per month Now the question is: What happens if your usage reaches 150 GB per day? Will the additional 50 GB be billed at the Pay-As-You-Go rate? No. The entire 150 GB/day will still be billed at the discounted rate associated with the 100 GB/day commitment tier bucket. Azure Pricing Calculator Equivalent (100 GB/ Day) Azure Pricing Calculator Equivalent (150 GB/ Day) Scenario 2 (Data Lake Tier Only) Requirement Suppose you need to store certain audit or compliance logs amounting to 10 GB per day. These logs are not used for querying, analytics, or investigations on a regular basis, but must be retained for 2 years as per your organization’s compliance or forensic policies. Solution Since these logs are not actively analyzed, you should avoid ingesting them into the Analytics tier, which is more expensive and optimized for active querying. Instead, send them directly to the Data Lake tier, where they can be retained cost-effectively for future audit, compliance, or forensic needs. Pricing Flow Because the data is ingested directly into the Data Lake tier, you pay both ingestion and retention costs there for the entire 2-year period. If, at any point in the future, you need to perform advanced analytics, querying, or search, you will incur additional compute charges, based on actual usage. Even with occasional compute charges, the cost remains significantly lower than storing the same data in the Analytics tier. Realized Savings Scenario Cost per Month Scenario 1: 10 GB/day in Analytics tier $1,520.40 Scenario 2: 10 GB/day directly into Data Lake tier $202.20 (without compute) $257.20 (with sample compute price) Savings with no compute activity: $1,520.40 – $202.20 = $1,318.20 per month Savings with some compute activity (sample value): $1,520.40 – $257.20 = $1,263.20 per month Azure calculator equivalent without compute Azure calculator equivalent with Sample Compute Conclusion The combination of the Analytics tier and the Data Lake tier in Microsoft Sentinel enables organizations to optimize cost based on how their security data is used. High-value logs that require frequent querying, real-time analytics, and investigation can be stored in the Analytics tier, which provides powerful search performance and built-in detection capabilities. At the same time, large-volume or infrequently accessed logs—such as audit, compliance, or long-term retention data—can be directed to the Data Lake tier, which offers dramatically lower storage and ingestion costs. Because all Analytics tier data is automatically mirrored to the Data Lake tier at no extra cost, customers can use the Analytics tier only for the period they actively query data, and rely on the Data Lake tier for the remaining retention. This tiered model allows different scenarios—active investigation, archival storage, compliance retention, or large-scale telemetry ingestion—to be handled at the most cost-effective layer, ultimately delivering substantial savings without sacrificing visibility, retention, or future analytical capabilities.Solved3.1KViews2likes6CommentsHunting AI Agent Configuration Drift with Microsoft Sentinel
Four KQL patterns for detecting instruction changes, new MCP servers, ownership changes, and organization-wide sharing I recently authored and contributed four new Microsoft Sentinel hunting queries for detecting security-relevant configuration drift in AI agents. They have been reviewed, approved, and merged into Microsoft's public Azure-Sentinel repository. I built the queries around four changes that can materially affect an agent's behavior, access, or exposure: instructions being modified, MCP servers being connected, owners being added, and sharing being expanded to the entire organization. Each modification may be legitimate, but each deserves enough context for a security team to verify that it was expected and authorized. For a security operations team, the difficult question is often not what does this agent look like now? It is what changed since the last known state? Microsoft Sentinel's AgentsInfo table provides inventory-style snapshots of AI agents and their associated configuration. That makes it useful for more than posture reporting. By comparing a recent snapshot with an earlier baseline, we can hunt for configuration drift that deserves investigation. This post walks through four practical hunting scenarios: Instructions changed on a previously published agent A newly observed MCP server on an existing agent An owner added to an MCP-enabled agent Sharing expanded from a restricted scope to the entire organization The complete hunting queries are available in Microsoft's public https://github.com/Azure/Azure-Sentinel/tree/master/Hunting%20Queries/AI%20Agents. The focus here is the detection design behind them, the KQL patterns they share, and the investigation questions they help answer. What I contributed I wrote the four standalone hunting queries discussed in this article and submitted them to Azure/Azure-Sentinel in https://github.com/Azure/Azure-Sentinel/pull/14702: AI Agents - Instructions changed on previously published agent AI Agents - Newly observed MCP server on existing agent AI Agents - Owner added to MCP-enabled agent AI Agents - Sharing expanded to organization-wide The contribution went through several rounds of technical review. Across six commits, I aligned the queries with the unified AgentsInfo schema, added schema-tolerant IdentityInfo enrichment, improved entity mappings, bounded the identity lookback, expanded all owner values, and kept the ATT&CK mappings limited to scenarios where a precise technique could be defended. Repository collaborator v-atulyadav approved the final revision, and the four queries were merged into master on July 20, 2026. This article explains the detection logic and engineering decisions behind that contribution rather than simply reproducing the final YAML files. Why current-state queries are not enough A current-state query can answer questions such as: Which agents are published? Which agents have MCP servers configured? Which agents are shared with the organization? Who owns a particular agent? Those are important posture questions, but they do not tell us whether the state is new. An agent with an MCP server might have been reviewed and approved months ago. The same MCP server appearing for the first time today is a different security signal. Configuration-drift hunting adds the missing time dimension. Instead of treating a risky-looking property as an event, it compares two states of the same agent and reports only meaningful transitions. The common detection pattern I used the same basic time model across all four hunts: let lookback = 14d; let recent = 2d; The latest snapshot observed during the last two days becomes the current state. The latest snapshot from the preceding portion of the 14-day lookback becomes the baseline. Conceptually, the comparison looks like this: let CurrentState = AgentsInfo | where Timestamp > ago(recent) | summarize arg_max(Timestamp, *) by AgentId | where LifecycleStatus != "Deleted"; let BaselineState = AgentsInfo | where Timestamp between (ago(lookback) .. ago(recent)) | where LifecycleStatus != "Deleted" | summarize arg_max(Timestamp, *) by AgentId; CurrentState | join kind=inner BaselineState on AgentId Several details matter here: arg_max(Timestamp, *) by AgentId selects the latest available state for each agent in the relevant time range. The inner join restricts results to agents that exist in both periods. A newly created agent is therefore not automatically treated as configuration drift on an existing agent. Deleted lifecycle snapshots are excluded so that a deletion record does not become the effective baseline or current configuration. The two-day current window is operationally significant. To retain coverage, these hunts should run within two days of a change. The 14-day and two-day values are practical defaults, not universal constants. Environments with different ingestion cadence or retention requirements can adjust them, but the current and baseline windows must remain non-overlapping. Scenario 1: Instructions changed on a published agent An agent's instructions define its default behavior, persona, and operating boundaries. Changing them can be part of normal development, but it can also weaken restrictions, redirect the agent's behavior, or modify how it uses connected capabilities. The first hunt compares the current and previous instruction values only when the agent was published in both snapshots: CurrentState | join kind=inner BaselineState on AgentId | where CurrentInstructions != PreviousInstructions | extend PreviousInstructionsHash = hash_sha256(PreviousInstructions), CurrentInstructionsHash = hash_sha256(CurrentInstructions), InstructionsLengthDelta = strlen(CurrentInstructions) - strlen(PreviousInstructions) I deliberately chose to expose hashes and a length delta rather than returning both instruction bodies in plaintext. This confirms that a change occurred without unnecessarily spreading potentially sensitive prompts through query results, exports, or screenshots. Useful investigation questions include: Was the change associated with an approved development or release process? Did the agent remain published while the instructions changed? Were guardrails, declared tools, permissions, or sharing settings modified around the same time? Do audit records identify an expected actor and change path? The query maps well to an integrity-focused investigation. Its MITRE ATT&CK mapping is T1565.001 (Stored Data Manipulation), but the result is still a hunting lead rather than proof of malicious manipulation. https://github.com/Azure/Azure-Sentinel/blob/master/Hunting%20Queries/AI%20Agents/AgentsInfoInstructionsChangedOnPublishedAgent.yaml Scenario 2: A newly observed MCP server Model Context Protocol servers can extend an agent with external tools, data sources, or actions. From a defender's perspective, the important transition is not simply that an MCP server exists. It is that a server name appears in the current configuration but was absent from the baseline. The query expands the dynamic McpServers array and builds a set of server names for each agent: let CurrentMcp = CurrentRaw | mv-expand Mcp = McpServers | extend McpName = tostring(Mcp.name) | where isnotempty(McpName) | summarize CurrentMcpServers = make_set(McpName) by AgentI It performs the same normalization for the baseline, then calculates the difference: | extend AddedMcpServers = set_difference(CurrentMcpServers, BaselineMcpServers) | where array_length(AddedMcpServers) > 0 Using set_difference() avoids raising a result merely because the order of array elements changed. The hunt reports only MCP server names present in the current set and absent from the previous set. An analyst should validate more than the displayed name: Is the MCP integration part of the approved inventory? What endpoint, authentication method, and permissions are associated with it? Which tools or data can the server expose to the agent? Was the integration introduced through an expected deployment path? Did ownership, instructions, or sharing change in the same period? I did not assign an ATT&CK technique to this query. Adding an MCP server does not, by itself, prove command execution, persistence, or a specific attacker behavior. Avoiding an overly broad mapping keeps the signal honest. https://github.com/Azure/Azure-Sentinel/blob/master/Hunting%20Queries/AI%20Agents/AgentsInfoNewlyObservedMcpServer.yaml Scenario 3: An owner added to an MCP-enabled agent Ownership is a control-plane relationship. A newly added owner may be able to modify an agent's configuration, instructions, integrations, or publication state. The risk becomes more interesting when the agent already has MCP servers configured. The hunt first limits the current state to MCP-enabled agents: | where array_length(coalesce(McpServers, dynamic([]))) > 0 | project AgentId, Timestamp, Name, Platform, CreatedDateTime, CurrentOwners = coalesce(Owners, dynamic([])), McpServers It then compares the owner arrays as sets: | extend AddedOwners = set_difference(CurrentOwners, PreviousOwners) | where array_length(AddedOwners) > 0 | mv-expand AddedOwnerId = AddedOwners to typeof(string) Expanding AddedOwners produces one row per newly observed owner. This is more useful than returning one opaque dynamic array because every added identity can be enriched, mapped, and investigated independently. I kept the raw object identifier in the result even when identity enrichment fails: | extend AddedOwnerUpn = AccountUpn, UnresolvedAddedOwnerId = iff(isempty(AccountUpn), AddedOwnerId, "") That fallback matters. A missing UPN should not hide the underlying ownership change. Investigation should establish: Is the added owner an expected person, service identity, or administrative group? Does the identity's role and business function justify control of this agent? Was the owner added before other configuration changes? Does the identity appear in related sign-in, audit, or privileged-access activity? Should ownership be removed while the change is reviewed? This query maps to T1098 (Account Manipulation) under Persistence and Privilege Escalation. As with the instruction-change hunt, the mapping frames an investigation hypothesis; it does not label every ownership change as malicious. https://github.com/Azure/Azure-Sentinel/blob/master/Hunting%20Queries/AI%20Agents/AgentsInfoOwnerAddedToMcpAgent.yaml Scenario 4: Sharing expanded to the entire organization An agent can move from a limited audience to organization-wide availability without changing its underlying tools or instructions. That transition can materially increase exposure, especially when the agent has MCP integrations or declared tools. The hunt treats "*" in SharedWith as the organization-wide state. The current snapshot must contain it, while the baseline must not: // Current state | where set_has_element(coalesce(SharedWith, dynamic([])), "*") // Baseline state | where not(set_has_element(coalesce(SharedWith, dynamic([])), "*")) The result also counts MCP servers and declared tools: | extend McpServerCount = array_length(coalesce(McpServers, dynamic([]))), DeclaredToolCount = array_length(coalesce(DeclaredTools, dynamic([]))) | extend HasElevatedCapabilities = McpServerCount > 0 or DeclaredToolCount > 0 | sort by HasElevatedCapabilities desc, Timestamp desc I use HasElevatedCapabilities as a prioritization field, not a verdict. It brings agents with connected capabilities to the top of the result set so analysts can review the potentially larger blast radius first. Questions for triage include: Was organization-wide publication explicitly approved? Is the agent intended for every user, or was a group-based scope expected? What data sources, tools, and MCP servers can organization-wide users reach through it? Do the instructions contain assumptions that were safe only for a restricted audience? Were access reviews or user-acceptance tests completed before the expansion? No ATT&CK mapping is assigned because a broader sharing scope is a security-relevant exposure change, but not a sufficiently precise adversary technique on its own. https://github.com/Azure/Azure-Sentinel/blob/master/Hunting%20Queries/AI%20Agents/AgentsInfoSharingExpandedToOrgWide.yaml Resolving owners without making the hunt schema-fragile The Owners field contains identifiers. Human-readable identity context makes results easier to triage, and entity mappings make those identities more useful in Sentinel investigations. I built a small, materialized IdentityInfo lookup that is shared by the four hunts: let IdentityIdtoUPN = materialize( IdentityInfo | extend ResolvedAccountUpn = tostring( column_ifexists("AccountUpn", column_ifexists("AccountUPN", ""))), IdentityTimestamp = todatetime( column_ifexists("Timestamp", column_ifexists("TimeGenerated", datetime(null)))) | where IdentityTimestamp >= ago(lookback) | where isnotempty(AccountObjectId) and isnotempty(ResolvedAccountUpn) | summarize arg_max(IdentityTimestamp, ResolvedAccountUpn) by AccountObjectId | project AccountObjectId = tostring(AccountObjectId), AccountUpn = ResolvedAccountUpn); There are three design choices worth noting: column_ifexists() accommodates observed IdentityInfo naming variants without maintaining separate query versions. The lookup is bounded by the same lookback period instead of scanning unbounded identity history. arg_max() keeps the latest usable identity record for each object ID. After enrichment, the queries map the account using the UPN components and the Entra object ID: entityMappings: - entityType: Account fieldMappings: - identifier: Name columnName: OwnerAccountName - identifier: UPNSuffix columnName: OwnerAccountUPNSuffix - identifier: AadUserId columnName: OwnerId The strong AadUserId identifier remains valuable even when display information changes. Microsoft Sentinel can use mapped entities in bookmarks and investigation experiences, so mapping the changed owner is more than cosmetic enrichment. Turning a result into an investigation These queries intentionally stop at the configuration transition. AgentsInfo tells us that two snapshots differ; it does not necessarily tell us who performed the change, through which interface, or whether the action was authorized. A practical investigation workflow is: Confirm that the two snapshots represent the expected agent and time period. Review the exact changed property and the agent's current capabilities. Identify the owner or newly added owner through IdentityInfo and Entra ID context. Correlate the transition with the relevant audit source for actor attribution. Check for related changes to permissions, tools, data sources, publication state, and sharing. Validate the change against an approved request, release, or ownership process. Restrict, unpublish, or revert the agent if the exposure cannot be justified. Expected changes can still be useful findings. Repeated legitimate results may reveal that a deployment process lacks a stable change window, that ownership is managed through noisy automation, or that the hunt's timing needs to be aligned with release activity. Tuning the hunts for your environment Before operational use, consider the following adjustments: Run cadence: Execute within the two-day current window. A daily cadence provides overlap without blending current and baseline periods. Lookback: Increase the 14-day lookback only if snapshot history and query cost support it. A longer lookback does not compensate for missing the current window. Known change windows: Add watchlists or environment-specific suppression logic for well-controlled automated deployments, while retaining enough context to audit the change. Agent scope: Filter by platform, business unit, agent naming convention, or owner if different teams require separate triage queues. Risk prioritization: Raise agents with sensitive declared data sources, powerful tools, privileged owners, or broad availability to the top of the result set. Audit correlation: Keep attribution logic separate unless the audit source and join keys are stable in your environment. This makes the configuration-drift hunt reusable while allowing each organization to attach its own control-plane evidence. Test with representative snapshots before treating any hunt as an operational control. In particular, validate array shapes for Owners, McpServers, and SharedWith, confirm the identity fields present in your workspace, and exercise both changed and unchanged states. Using the queries The four YAML definitions have been merged into the Hunting Queries/AI Agents folder of Microsoft's Azure-Sentinel repository. Each file contains the complete KQL, description, entity mappings, and ATT&CK mappings where a precise technique applies. https://github.com/Azure/Azure-Sentinel/blob/master/Hunting%20Queries/AI%20Agents/AgentsInfoInstructionsChangedOnPublishedAgent.yaml https://github.com/Azure/Azure-Sentinel/blob/master/Hunting%20Queries/AI%20Agents/AgentsInfoNewlyObservedMcpServer.yaml https://github.com/Azure/Azure-Sentinel/blob/master/Hunting%20Queries/AI%20Agents/AgentsInfoOwnerAddedToMcpAgent.yaml https://github.com/Azure/Azure-Sentinel/blob/master/Hunting%20Queries/AI%20Agents/AgentsInfoSharingExpandedToOrgWide.yaml The broader pattern is reusable beyond these four scenarios: select a stable current snapshot, select a non-overlapping baseline, normalize dynamic properties into comparable sets, calculate the transition, and enrich only after the drift has been identified. That keeps the core detection explainable and gives the analyst the before-and-after context needed for a defensible investigation. References https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/agentsinfo https://learn.microsoft.com/en-us/azure/azure-monitor/reference/queries/agentsinfo https://learn.microsoft.com/en-us/azure/azure-monitor/reference/tables/identityinfo https://learn.microsoft.com/en-us/azure/sentinel/entities-reference https://github.com/Azure/Azure-Sentinel/pull/14702 I authored the four hunting queries discussed in this article and contributed them to Microsoft's Azure-Sentinel repository as https://github.com/Azure/Azure-Sentinel/pull/14702. The complete implementations and review history are publicly available through the links above.246Views1like2CommentsBehavior Analytics, investigation Priority
Hello, Regarding the field investigation Priority in the Behavior Analytics table, what would be the value that Microsoft considers to be high/critical to look into the user's account? By analyzing the logs i would say, 7 or higher, if someone could tell me, and thank you in advance.259Views1like1CommentFetching alerts from Sentinel using logic apps
Hello everyone, I have a requirement to archive alerts from sentinel. To do that I need to do the following: Retrieve the alerts from Sentinel Send the data to an external file share As a solution, I decided to proceed with using logic apps where I will be running a script to automate this process. My questions are the following: -> Which API endpoints in sentinel are relevant to retrieve alerts or to run kql queries to get the needed data. -> I know that I will need some sort of permissions to interact with the API endpoint. What type of service account inside azure should I create and what permissions should I provision to it ? -> Is there any existing examples of logic apps interacting with ms sentinel ? That would be helpful for me as I am new to Azure. Any help is much appreciated !622Views1like4CommentsHandling Entity Data in Sentinel
So, I have set up some playbooks that allow me to add IPs/Domains/File Hashes to the MDE Indicators list, which is awesome to have and saves time when we need to block malicious entities. However, I have not found a great way for Sentinel to give me more information regarding File Hashes. Really, my main worry with just a list of hashes in an incident is not knowing the file name for each hash, like so: So, in this case, I am to just assume that both file hashes go to the 'FileCoAuth' file. Easy enough. But, are there ever cases where something like msedge.exe shows up in this list of file hashes? Right now, I feel like in this 'Info' tab, it might be more helpful to have 'File Name', but I might be looking at this all wrong. I guess, I am just looking for some guidance into this entity so that I don't accidentally block the wrong file and end up breaking systems. Even if these hashes only ever correspond to the one file entity in the incident, I am still a bit confused at how little data comes over into this. Even for the File entity: Great, I know the name of the file and the path.. However, over in Defender, I get TONS of info for the file, including all the hashes connected to it, First seen / last seen, basic VirusTotal info, and a bunch of other items. Am I expecting too much by hoping that we wouldn't have to jump over to Defender? We set up Sentinel with the hopes of making it the go-to, but still find ourselves going right back to Defender for investigations and I wasn't sure if there was something that I am missing in this setup, or if there was a way to get more data enrichment without having to pay VirusTotal's insane bill (we are SMB and were quoted 90k per year, minimum). Even then, when Defender has some of the basic VirusTotal info, I was hoping Sentinel would have that and more..530Views1like0CommentsLog Analytics Workspace Daily Cap
Hello everyone, I am new to Microsoft Sentinel, and I hope all of you are doing good. I wanted to know that I set a daily cap limit on my log analytics workspace of 23 MB, as it was the lowest I could go in my test environment. I created alerts on that too, like whenever the daily cap is reached I am notified via email. I wanted to know a couple of things. If I set the daily cap limit, it should stop ingesting data after reaching 23 MB right? Considering that the data is coming from my windows and Linux virtual machines via AMA. But I can see around 27 MB of data being ingested as of today. I want to know the reason behind it. If it is not stopping the ingestion of data is there any rule that I can configure which forces to stop this ingestion? I have gone through all the Alerts that are present in the Log Analytics Workspace but there is no option. Thanking in advance. Best Regards, Sharjeel Khan.1.9KViews1like5CommentsMicrosoft 365 defender alerts not capturing fields (entities) in azure sentinel
We got an alert from 365 defenders to azure sentinel ( A potentially malicious URL click was detected). To investigate this alert we have to check in the 365 defender portal. We noticed that entities are not capturing (user, host, IP). How can we resolve this issue? Note: This is not a custom rule.2.8KViews1like3Comments