{
    "version": "https://jsonfeed.org/version/1",
    "title": "Fluency Ingext User Manual Blog",
    "home_page_url": "https://manual.ingext.io/release",
    "description": "Fluency Ingext User Manual Blog",
    "items": [
        {
            "id": "https://manual.ingext.io/release/2026-10-23-password-spray-takeover",
            "content_html": "<p>A detection release for password-spray account takeover in Microsoft 365, published October 23, 2026. A new high-severity behavior rule, <code>EntraID_SignIn_After_Block</code>, alerts when an attacker who holds a user's password gets into the account after Conditional Access blocked their earlier attempts. It catches the Azure CLI password spraying that Huntress has reported since June 2026, when a risk policy stops the sprayer once and they come back from another address. A precision fix to <code>EntraID_Valid_Password_Blocked</code> ships with it.</p>\n<p>No action is needed: the rules sync to every instance automatically.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"rollout-and-requirements\">Rollout and requirements<a href=\"https://manual.ingext.io/release/2026-10-23-password-spray-takeover#rollout-and-requirements\" class=\"hash-link\" aria-label=\"Direct link to Rollout and requirements\" title=\"Direct link to Rollout and requirements\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\"><strong>Rollout.</strong> Both rules are published to the default rule set and reach each instance through resource sync within about two hours. No configuration is needed.</li>\n<li class=\"\"><strong>Data sources.</strong> Both rules read the Entra ID sign-in logs, collected by <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/entraid-audit-eventhubs\">Entra ID Audit via Event Hubs</a> or <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/azuread-audit\">Microsoft Graph</a>. Interactive sign-ins are enough.</li>\n<li class=\"\"><strong>Entra ID P2.</strong> <code>EntraID_SignIn_After_Block</code> needs Microsoft's sign-in risk rating, which the sign-in logs carry only for tenants with an Entra ID P2 licence. Other tenants get the value <code>hidden</code>, and the rule cannot arm. The improved <code>EntraID_Valid_Password_Blocked</code> works without P2.</li>\n<li class=\"\"><strong>Expected volume.</strong> <code>EntraID_SignIn_After_Block</code> is built to be rare. It needs a correct password, a block rated high risk and a success from somewhere else, all within two hours, so password typos, travel and moves between office and home do not trigger it. Over the 14 days before release it would have fired once across the Fluency fleet: on the real compromise described below. Its severity is high for now and will be reviewed against the first weeks of live alerts.</li>\n</ul>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"the-attack\">The attack<a href=\"https://manual.ingext.io/release/2026-10-23-password-spray-takeover#the-attack\" class=\"hash-link\" aria-label=\"Direct link to The attack\" title=\"Direct link to The attack\" translate=\"no\">​</a></h3>\n<p>Password spraying against Microsoft 365 grew fast in 2026: Huntress saw credential spray attacks against its customers rise over 155 times in six months. One campaign made more than 81 million sign-in attempts between June 12 and June 26 against the Azure command-line client (Azure CLI), and compromised 78 accounts at 64 organizations. It signs in through Azure CLI's password-only flow (OAuth ROPC), which sends the password straight to Microsoft's token endpoint with no MFA prompt. The actor sprayed from a hosting provider's IPv6 range and from Tor exit nodes. When the provider shut it down, it moved to other providers and kept spraying low and slow: in July, about 900 attempts per address across some 12,800 addresses.</p>\n<p>The passwords come from old breaches that were never rotated. Accounts fall when MFA does not cover the sign-in: MFA required only for admins or some groups, only for some apps, only from untrusted locations, or left in report-only mode.</p>\n<p>Fluency saw the same pattern in a customer tenant in October 2026:</p>\n<ol>\n<li class=\"\">Microsoft blocked four attempts that used the user's correct password, from Portugal, Singapore and Russia, because it rated them high risk.</li>\n<li class=\"\">Four minutes later the attacker used the same password from a residential address in the user's own country. Microsoft rated that sign-in risk-free, and it succeeded without MFA.</li>\n</ol>\n<p>Each record looks normal on its own: the block is the policy working, and the success is a routine sign-in. Before this release, the blocked attempts raised <code>EntraID_Valid_Password_Blocked</code> alerts, but nothing tied them to the successful sign-in that followed.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-and-changed-detections\">New and changed detections<a href=\"https://manual.ingext.io/release/2026-10-23-password-spray-takeover#new-and-changed-detections\" class=\"hash-link\" aria-label=\"Direct link to New and changed detections\" title=\"Direct link to New and changed detections\" translate=\"no\">​</a></h3>\n<table><thead><tr><th>ID</th><th>Rule</th><th>Change</th><th>Severity</th><th>Fires when</th></tr></thead><tbody><tr><td>102185</td><td><code>EntraID_SignIn_After_Block</code></td><td>New</td><td>High</td><td>A user signs in successfully within two hours after Conditional Access blocked a sign-in of theirs that Microsoft rated high risk and that presented their correct password, and the success comes from an IP address none of the blocked attempts came from.</td></tr><tr><td>102127</td><td><code>EntraID_Valid_Password_Blocked</code></td><td>Improved</td><td>Medium</td><td>Conditional Access blocks a sign-in that presented the user's correct password. It now matches Microsoft's \"Correct password\" result exactly, so a blocked sign-in with a wrong password (\"Incorrect password\") is no longer reported as a known password.</td></tr></tbody></table>\n<p>For both rules, a block is a sign-in Conditional Access stopped by policy (result 53003 or 530032) or because the device was not compliant or not managed (53000, 53001).</p>\n<p><code>EntraID_SignIn_After_Block</code> does <strong>not</strong> fire for:</p>\n<ul>\n<li class=\"\">a success from an address one of the blocked attempts came from, such as the user getting through on a compliant device after a non-compliant one;</li>\n<li class=\"\">a blocked attempt with a wrong password, or one Microsoft did not rate high risk;</li>\n<li class=\"\">a success more than two hours after the last blocked attempt;</li>\n<li class=\"\">non-interactive sign-ins, blocked or successful;</li>\n<li class=\"\">sign-ins that carry no session ID;</li>\n<li class=\"\">tenants without Entra ID P2;</li>\n<li class=\"\">an attacker whose very first attempt succeeds, from an address Microsoft does not flag, with nothing blocked before it. No sign-in log can tell that apart from the real user; MFA is the control for that case.</li>\n</ul>\n<p>It is keyed on the <strong>user</strong> and alerts at most once per user in two hours. Each alert names the successful sign-in (IP address, network, country, application, resource, user agent, session and sign-in IDs) and the blocked attempts before it (their addresses and count, result code, risk level, country and sign-in ID), with the seconds between the last block and the success.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"triage-guidance\">Triage guidance<a href=\"https://manual.ingext.io/release/2026-10-23-password-spray-takeover#triage-guidance\" class=\"hash-link\" aria-label=\"Direct link to Triage guidance\" title=\"Direct link to Triage guidance\" translate=\"no\">​</a></h3>\n<p>Treat an <code>EntraID_SignIn_After_Block</code> alert as a likely account takeover until you show otherwise.</p>\n<ol>\n<li class=\"\"><strong>Contain first.</strong> Revoke the user's sessions and reset the password in Entra ID. Disable the account if the user does not need it.</li>\n<li class=\"\"><strong>Confirm with the user.</strong> Ask whether they signed in at that time, from that place, with that application. Admin and scripting clients such as Azure CLI or PowerShell are a strong signal when the user is not an administrator.</li>\n<li class=\"\"><strong>Check what the session did.</strong> Review the user's sign-ins after the success, including non-interactive ones, and directory changes made by or for the account: MFA methods, devices, app consents, mailbox rules.</li>\n<li class=\"\"><strong>Look for other targets.</strong> The same campaign usually sprays many users in the tenant. Make sure they are all covered by MFA.</li>\n</ol>\n<p>An <code>EntraID_Valid_Password_Blocked</code> alert on its own means someone else knows the password, even though that attempt was stopped. Reset it and require MFA for that user.</p>\n<p>To find these alerts, search behavior events by rule name. Each rule is also listed by name on the <a class=\"\" href=\"https://manual.ingext.io/page-functionality/siem/behavior-rules\">Behavior Rules</a> page.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"hardening-to-recommend\">Hardening to recommend<a href=\"https://manual.ingext.io/release/2026-10-23-password-spray-takeover#hardening-to-recommend\" class=\"hash-link\" aria-label=\"Direct link to Hardening to recommend\" title=\"Direct link to Hardening to recommend\" translate=\"no\">​</a></h3>\n<p>Detection shortens an attacker's window; MFA closes it. These steps follow Huntress's guidance and what we saw in the field:</p>\n<ul>\n<li class=\"\"><strong>Require MFA for all users, all cloud apps and all client app types,</strong> with no group, app, location or report-only exceptions. Accounts outside an \"admins\" or \"knowledge workers\" group are the ones being taken over.</li>\n<li class=\"\"><strong>Restrict Azure CLI and Azure PowerShell to the people who need them.</strong> Require assignment on the Microsoft Azure CLI enterprise app and assign it to an IT group, or block Azure management for everyone else.</li>\n<li class=\"\"><strong>Turn off password-only (ROPC) sign-in where nothing depends on it.</strong> Conditional Access has no separate setting for it: requiring MFA for all client app types makes ROPC sign-ins fail, and restricting Azure CLI takes away the client this campaign uses.</li>\n<li class=\"\"><strong>Don't rely on location alone.</strong> IP geolocation is often wrong: Huntress found spray addresses that geolocation placed in the U.S., which passed trusted-location rules. In the case above, the successful sign-in came from a residential address in the user's own country.</li>\n<li class=\"\"><strong>Disable dormant accounts.</strong> An account nobody signs in to has no owner to notice a takeover.</li>\n</ul>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"references\">References<a href=\"https://manual.ingext.io/release/2026-10-23-password-spray-takeover#references\" class=\"hash-link\" aria-label=\"Direct link to References\" title=\"Direct link to References\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\">Huntress, <a href=\"https://www.huntress.com/blog/lshiy-password-spray-attack\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\"><em>No (Bad) CAP: Inside an Ongoing LSHIY Password Spray Attack</em></a>, June 30, 2026, updated July 2026.</li>\n<li class=\"\">Huntress, <a href=\"https://www.huntress.com/blog/twist-the-nozzle-on-password-spraying-a-tradecraft-tuesday-recap\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\"><em>Twist the Nozzle on Password Spraying: A Tradecraft Tuesday Recap</em></a>, July 22, 2026.</li>\n<li class=\"\">Microsoft Learn, <a href=\"https://learn.microsoft.com/en-us/graph/api/resources/signin\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\"><em>signIn resource type</em></a> (sign-in risk levels require Entra ID P2).</li>\n</ul>",
            "url": "https://manual.ingext.io/release/2026-10-23-password-spray-takeover",
            "title": "Password-Spray Account Takeover Detection",
            "summary": "A detection release for password-spray account takeover in Microsoft 365, published October 23, 2026. A new high-severity behavior rule, EntraIDSignInAfterBlock, alerts when an attacker who holds a user's password gets into the account after Conditional Access blocked their earlier attempts. It catches the Azure CLI password spraying that Huntress has reported since June 2026, when a risk policy stops the sprayer once and they come back from another address. A precision fix to EntraIDValidPasswordBlocked ships with it.",
            "date_modified": "2026-10-23T21:55:00.000Z",
            "author": {
                "name": "Sysadmin",
                "url": "https://github.com/SecurityDo"
            },
            "tags": [
                "release",
                "detections"
            ]
        },
        {
            "id": "https://manual.ingext.io/release/2026-10-23-entra-app-identity",
            "content_html": "<p>A detection release for Microsoft Entra ID, published October 23, 2026. Four new behavior rules alert when an app (a service principal acting with no user signed in) assigns directory roles or adds credentials to other apps. An attacker does exactly this with a stolen app certificate or secret, as in the Storm-0940 compromise of ConnectWise's multi-tenant apps that Microsoft reported on October 21. Until now, role assignments and credential changes made by an app were only context, or one step of the <code>EntraID_App_Takeover</code> correlation.</p>\n<p>No action is needed: the rules sync to every instance automatically. These notes also correct how the October 18–20 notes described <code>EntraID_DeviceCode_UserApp</code>.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"rollout-and-requirements\">Rollout and requirements<a href=\"https://manual.ingext.io/release/2026-10-23-entra-app-identity#rollout-and-requirements\" class=\"hash-link\" aria-label=\"Direct link to Rollout and requirements\" title=\"Direct link to Rollout and requirements\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\"><strong>Rollout.</strong> All four rules are published to the default rule set and reach each instance through resource sync within about two hours. No configuration is needed.</li>\n<li class=\"\"><strong>Data sources.</strong> The rules read the Entra ID audit logs, collected by <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/entraid-audit-eventhubs\">Entra ID Audit via Event Hubs</a> or <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/azuread-audit\">Microsoft Graph</a>. Tenants that send only the Microsoft 365 unified audit log, with no Entra ID audit logs, are not covered yet.</li>\n<li class=\"\"><strong>A first week of learning.</strong> Three of the rules alert on an app's first time in 30 days. Each one learns for 7 days from the first event it sees in a tenant and raises no alert in that time. <code>EntraID_App_Privileged_Role_Assigned</code>, <code>EntraID_App_Role_Assigned</code> and <code>EntraID_App_Credential_By_App</code> therefore start alerting about a week after they reach a tenant. <code>EntraID_App_Self_Role_Assigned</code> alerts from the start.</li>\n<li class=\"\"><strong>Recommended.</strong> Collect service principal sign-ins as well. They are where an app signing in with a stolen credential shows up. See <a href=\"https://manual.ingext.io/release/2026-10-23-entra-app-identity#not-covered-yet\" class=\"\">Not covered yet</a>.</li>\n</ul>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"the-attack\">The attack<a href=\"https://manual.ingext.io/release/2026-10-23-entra-app-identity#the-attack\" class=\"hash-link\" aria-label=\"Direct link to The attack\" title=\"Direct link to The attack\" translate=\"no\">​</a></h3>\n<p>Microsoft Threat Intelligence attributes the compromise to Storm-0940, a China state-aligned actor. It automated the attack with ARTEX, an open-source agentic AI penetration-testing framework. Its targets were ConnectWise Cloud Backup (formerly SkyKick) and the ConnectWise Cloud Management apps, which MSPs and their customers had consented to in their Microsoft 365 tenants.</p>\n<ul>\n<li class=\"\"><strong>October 10–14.</strong> A password spray against 327 accounts at eight organizations, peaking at 2,900 failed attempts a minute. Microsoft saw no successful sign-in in this phase.</li>\n<li class=\"\"><strong>October 15.</strong> The attacker signed in as the apps, with no user, using the apps' own credentials. Microsoft reports attempts against more than 2,250 tenants. Huntress had confirmed unauthorized sign-ins in 162 tenants by the next day.</li>\n<li class=\"\"><strong>Same day.</strong> In about 50 tenants that Huntress monitors, the Cloud Management apps assigned themselves directory roles, mostly Exchange Administrator. In one tenant, the Teams management app made itself Global Administrator. It then ran a Python script that added client secrets to two other apps. Microsoft also saw Graph reconnaissance and bulk reads of Key Vault secrets. In several cases, it measured under three hours from first targeting to privileged access.</li>\n<li class=\"\"><strong>October 17.</strong> ConnectWise disabled the apps.</li>\n</ul>\n<p>User-based rules miss this. No user signs in, so there is no MFA prompt, no risky sign-in and no new device. The app is one the tenant already trusts, so app-creation and consent rules do not fire either. What the audit log does show is a service principal assigning roles, often to itself, and adding secrets to other apps.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-detections\">New detections<a href=\"https://manual.ingext.io/release/2026-10-23-entra-app-identity#new-detections\" class=\"hash-link\" aria-label=\"Direct link to New detections\" title=\"Direct link to New detections\" translate=\"no\">​</a></h3>\n<table><thead><tr><th>ID</th><th>Rule</th><th>Severity</th><th>Alerts</th><th>Fires when</th></tr></thead><tbody><tr><td>102184</td><td><code>EntraID_App_Self_Role_Assigned</code></td><td>Critical</td><td>Every time</td><td>An app assigns any directory role to its own service principal. Apps are given roles by an administrator, so an app granting itself one is never routine.</td></tr><tr><td>102168</td><td><code>EntraID_App_Privileged_Role_Assigned</code></td><td>High confidence</td><td>First time per app in 30 days</td><td>An app assigns a privileged directory role (Global, Exchange, Privileged Role or Application Administrator and the like) to a user or group, or any directory role to another service principal.</td></tr><tr><td>102169</td><td><code>EntraID_App_Role_Assigned</code></td><td>Medium</td><td>First time per app in 30 days</td><td>An app assigns a non-privileged directory role to a user or group.</td></tr><tr><td>102170</td><td><code>EntraID_App_Credential_By_App</code></td><td>Medium</td><td>First time per app in 30 days</td><td>An app adds a secret or certificate to another app or service principal, so that its access survives the original credential being revoked. An app re-keying itself, such as Entra Connect or a vendor's connector, is not counted.</td></tr></tbody></table>\n<p>The role rules map to MITRE ATT&amp;CK T1098.003 (Additional Cloud Roles), and the credential rule to T1098.001 (Additional Cloud Credentials).</p>\n<p>Some apps do these things as their job: a just-in-time access broker grants admin roles every week, and CI pipelines rotate other apps' secrets. So the three first-time rules alert only the first time an app does it in 30 days, keyed on the app ID; repeats are not recorded. A compromised app that already does this routinely will not trip them. Self-assignment has no such allowance.</p>\n<p>Microsoft's own service apps are excluded by app ID: Privileged Identity Management, Microsoft support's GDAP access, Approval Management, ESTS, managed identities, Purview, Dynamics and AAD App Management. Role grants through PIM therefore stay with <code>EntraID_Privileged_Role_Assigned</code> (102119).</p>\n<p>Each alert is keyed on the app's name. The app ID, service principal ID, role and target are in the event's attributes.</p>\n<p><strong>Parser change.</strong> <code>EntraID_AuditRules</code> now also emits a line keyed on the acting app for role and credential operations. Its existing output, and the rules that read it, are unchanged.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"not-covered-yet\">Not covered yet<a href=\"https://manual.ingext.io/release/2026-10-23-entra-app-identity#not-covered-yet\" class=\"hash-link\" aria-label=\"Direct link to Not covered yet\" title=\"Direct link to Not covered yet\" translate=\"no\">​</a></h3>\n<table><thead><tr><th>Step</th><th>Why it is not covered</th><th>What helps</th></tr></thead><tbody><tr><td>The app signs in with a stolen credential</td><td>Most tenants do not collect service principal sign-ins, so an app that only reads (Graph reconnaissance, mail, files) leaves no trace.</td><td>Collect service principal sign-ins: select the <code>ServicePrincipalSignInLogs</code> category in the Entra ID diagnostic setting that feeds <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/entraid-audit-eventhubs#microsoft-entra-id-logs\">Entra ID Audit via Event Hubs</a>. The Microsoft Graph template collects interactive sign-ins only. Volume varies widely between tenants, so check it first. Non-interactive user sign-ins are not needed for this.</td></tr><tr><td>The app uses Exchange Administrator</td><td>No rule yet looks at Exchange admin cmdlets run by an app identity.</td><td>Planned.</td></tr><tr><td>Tenants with only the Microsoft 365 audit log</td><td>The unified audit log's version of these operations is not matched yet.</td><td>Planned. Entra ID audit logs, through Event Hubs or Microsoft Graph, cover it today.</td></tr><tr><td>Key Vault secrets read in bulk</td><td>Key Vault logs are rarely collected.</td><td>Ask us for a hunt if you send Key Vault diagnostics.</td></tr></tbody></table>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"correction-entraid_devicecode_userapp-alerts-on-every-match\">Correction: <code>EntraID_DeviceCode_UserApp</code> alerts on every match<a href=\"https://manual.ingext.io/release/2026-10-23-entra-app-identity#correction-entraid_devicecode_userapp-alerts-on-every-match\" class=\"hash-link\" aria-label=\"Direct link to correction-entraid_devicecode_userapp-alerts-on-every-match\" title=\"Direct link to correction-entraid_devicecode_userapp-alerts-on-every-match\" translate=\"no\">​</a></h3>\n<p>The <a class=\"\" href=\"https://manual.ingext.io/release/2026-10-20-entra-id-detections\">October 18–20 notes</a> said <code>EntraID_DeviceCode_UserApp</code> (102129) alerts only on a user's first device-code sign-in to an application. That was wrong. Every successful device-code sign-in to an application that is not an admin tool alerts at medium. A user's first such sign-in to an application in 30 days scores higher. The rule's own description is corrected in the next release. Its detection logic is unchanged.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"triage-guidance\">Triage guidance<a href=\"https://manual.ingext.io/release/2026-10-23-entra-app-identity#triage-guidance\" class=\"hash-link\" aria-label=\"Direct link to Triage guidance\" title=\"Direct link to Triage guidance\" translate=\"no\">​</a></h3>\n<table><thead><tr><th>Alert</th><th>Check first</th><th>Respond</th></tr></thead><tbody><tr><td><code>EntraID_App_Self_Role_Assigned</code></td><td>The app's name, app ID and owner tenant (is it a vendor's multi-tenant app?), and the role it took. Check the vendor's security advisories.</td><td>Treat it as a compromise unless the vendor confirms the change. Remove the role, disable the service principal and remove its credentials. Then review what the app did after the grant: other role assignments, credentials added to other apps, password resets, mail access.</td></tr><tr><td><code>EntraID_App_Privileged_Role_Assigned</code></td><td>Whether the app is a known access broker or automation (a JIT or PAM product, an identity governance tool), and who received the role.</td><td>If it is not expected, remove the assignment and contain the app as above. If it is an access broker, confirm the grant matches a request.</td></tr><tr><td><code>EntraID_App_Role_Assigned</code></td><td>The role and the recipient, and whether the app manages roles as part of its job.</td><td>Confirm with the app's owner, and remove the assignment if it is not expected.</td></tr><tr><td><code>EntraID_App_Credential_By_App</code></td><td>Which app was keyed, and what permissions that app holds. A secret added to a highly privileged app is the persistence step.</td><td>Remove the new secret or certificate from the target app and contain the acting app. Rotating the acting app's own credential does not remove the one it added elsewhere.</td></tr></tbody></table>\n<p>Rule IDs are the same on every instance. To find these alerts, search behavior events by rule name. Each rule is also listed by name on the <a class=\"\" href=\"https://manual.ingext.io/page-functionality/siem/behavior-rules\">Behavior Rules</a> page.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"references\">References<a href=\"https://manual.ingext.io/release/2026-10-23-entra-app-identity#references\" class=\"hash-link\" aria-label=\"Direct link to References\" title=\"Direct link to References\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\">Microsoft Threat Intelligence, <a href=\"https://www.microsoft.com/en-us/security/blog/2026/10/21/storm-0940-uses-artex-agentic-ai-connectwise-supply-chain-compromise/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\"><em>AI-driven, large-scale nation-state campaign using ARTEX enables supply chain compromise</em></a> (Storm-0940), October 21, 2026.</li>\n<li class=\"\">Huntress, <a href=\"https://www.huntress.com/blog/vendor-credential-enables-unauthorized-access\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\"><em>ConnectWise (SkyKick) Vendor Credentials Abused in M365 Attacks</em></a>, October 16, 2026, updated October 19, 2026.</li>\n</ul>",
            "url": "https://manual.ingext.io/release/2026-10-23-entra-app-identity",
            "title": "Entra ID App Identity Detections",
            "summary": "A detection release for Microsoft Entra ID, published October 23, 2026. Four new behavior rules alert when an app (a service principal acting with no user signed in) assigns directory roles or adds credentials to other apps. An attacker does exactly this with a stolen app certificate or secret, as in the Storm-0940 compromise of ConnectWise's multi-tenant apps that Microsoft reported on October 21. Until now, role assignments and credential changes made by an app were only context, or one step of the EntraIDAppTakeover correlation.",
            "date_modified": "2026-10-23T18:45:00.000Z",
            "author": {
                "name": "Sysadmin",
                "url": "https://github.com/SecurityDo"
            },
            "tags": [
                "release",
                "detections"
            ]
        },
        {
            "id": "https://manual.ingext.io/release/2026-10-23-report-archive",
            "content_html": "<p>A reports release, published October 23, 2026. A scheduled report can now keep every day's result for 12 months. With the new <code>fluency-report-rollup</code> skill, Claude builds a month, a quarter or a trend from those daily results. It runs no long query, is not held to a report's 60-day limit, and states on the page which days it covers.</p>\n<p>Report Archive is available on every instance. For analysts who build reports in Claude Co-Work or Claude Code, it needs two things: the archive turned on for the report, and the <code>fluency-report-rollup</code> skill.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"whats-new\">What's new<a href=\"https://manual.ingext.io/release/2026-10-23-report-archive#whats-new\" class=\"hash-link\" aria-label=\"Direct link to What's new\" title=\"Direct link to What's new\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\">\n<p><strong>A daily archive.</strong> A scheduled report with the archive turned on runs once a day for exactly the previous day, 00:00 to 24:00 in the archive timezone (UTC unless an administrator sets another). Each day's result is kept for 12 months, with its row counts and the version of the report script it ran on.</p>\n</li>\n<li class=\"\">\n<p><strong>Archive tools on the MCP server.</strong> Three new tools on the tenant's <a class=\"\" href=\"https://manual.ingext.io/reference/api/mcp\">MCP server</a> let Claude work with the archive:</p>\n<table><thead><tr><th>Tool</th><th>What it does</th></tr></thead><tbody><tr><td><code>list_report_archive</code></td><td>Lists the archived reports, or for one report, its days with a coverage summary: missing, aborted and running days, and the script versions in the range.</td></tr><tr><td><code>download_report_archive</code></td><td>Downloads one day, or a range of up to 92 days.</td></tr><tr><td><code>backfill_report_archive</code></td><td>Runs the report for past days that are missing, in the background.</td></tr></tbody></table>\n</li>\n<li class=\"\">\n<p><strong>The <code>fluency-report-rollup</code> skill (1.0.0).</strong> It checks coverage, reads the report's script to decide how each table combines, merges the daily results, and hands them to <code>fluency-report</code> to draw the page.</p>\n</li>\n</ul>\n<p>Running a 90-day report directly is slow, and many reports refuse ranges that long. An archived day is a finished result, so a month is 30 small results that already exist, and Claude only has to combine them correctly.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"before-you-start\">Before you start<a href=\"https://manual.ingext.io/release/2026-10-23-report-archive#before-you-start\" class=\"hash-link\" aria-label=\"Direct link to Before you start\" title=\"Direct link to Before you start\" translate=\"no\">​</a></h3>\n<ol>\n<li class=\"\">\n<p><strong>Turn the archive on for the report.</strong> Ask Claude <em>Which reports are archived?</em> If yours is not listed, an Ingext administrator turns the archive on in the report's definition. The report also needs a daily schedule:</p>\n<div class=\"language-json codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#f5f5f5;--prism-background-color:#111111\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-json codeBlock_bY9V thin-scrollbar\" style=\"color:#f5f5f5;background-color:#111111\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#f5f5f5\"><span class=\"token property\">\"scheduleFlag\"</span><span class=\"token operator\" style=\"color:rgb(212, 212, 212)\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\">true</span><span class=\"token punctuation\" style=\"color:rgb(212, 212, 212)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#f5f5f5\"><span class=\"token plain\"></span><span class=\"token property\">\"schedule\"</span><span class=\"token operator\" style=\"color:rgb(212, 212, 212)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(212, 212, 212)\">{</span><span class=\"token plain\"> </span><span class=\"token property\">\"interval\"</span><span class=\"token operator\" style=\"color:rgb(212, 212, 212)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(206, 145, 120)\">\"daily\"</span><span class=\"token punctuation\" style=\"color:rgb(212, 212, 212)\">,</span><span class=\"token plain\"> </span><span class=\"token property\">\"hour\"</span><span class=\"token operator\" style=\"color:rgb(212, 212, 212)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(181, 206, 168)\">3</span><span class=\"token punctuation\" style=\"color:rgb(212, 212, 212)\">,</span><span class=\"token plain\"> </span><span class=\"token property\">\"minute\"</span><span class=\"token operator\" style=\"color:rgb(212, 212, 212)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(181, 206, 168)\">15</span><span class=\"token punctuation\" style=\"color:rgb(212, 212, 212)\">,</span><span class=\"token plain\"> </span><span class=\"token property\">\"timezone\"</span><span class=\"token operator\" style=\"color:rgb(212, 212, 212)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(206, 145, 120)\">\"GMT\"</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(212, 212, 212)\">}</span><span class=\"token punctuation\" style=\"color:rgb(212, 212, 212)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#f5f5f5\"><span class=\"token plain\"></span><span class=\"token property\">\"archive\"</span><span class=\"token operator\" style=\"color:rgb(212, 212, 212)\">:</span><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(212, 212, 212)\">{</span><span class=\"token plain\"> </span><span class=\"token property\">\"enabled\"</span><span class=\"token operator\" style=\"color:rgb(212, 212, 212)\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\">true</span><span class=\"token punctuation\" style=\"color:rgb(212, 212, 212)\">,</span><span class=\"token plain\"> </span><span class=\"token property\">\"timezone\"</span><span class=\"token operator\" style=\"color:rgb(212, 212, 212)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(206, 145, 120)\">\"UTC\"</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(212, 212, 212)\">}</span><br></div></code></pre></div></div>\n<p><code>archive.timezone</code> sets where a day starts and ends; <code>schedule.timezone</code> only sets when the run fires. For a report managed in git, add the <code>archive</code> block to the report's file in the Scripts repo, next to <code>schedule</code>. The report editor on <a class=\"\" href=\"https://manual.ingext.io/reports/scheduling-and-delivery\">Reports → Scheduler</a> does not show this block yet. Days exist from the moment the archive is on. Earlier days can be backfilled while their data is still in the datalake.</p>\n</li>\n<li class=\"\">\n<p><strong>Install the skill.</strong> Install <code>fluency-report-rollup</code> from the <a href=\"https://github.com/SecurityDo/ingext_skills\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">ingext_skills</a> repository; the packaged file is <code>cowork/fluency-report-rollup.skill</code>. It works with <code>fluency-report</code>, which draws the page, so install that too if you don't have it.</p>\n</li>\n</ol>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"how-claude-builds-the-report\">How Claude builds the report<a href=\"https://manual.ingext.io/release/2026-10-23-report-archive#how-claude-builds-the-report\" class=\"hash-link\" aria-label=\"Direct link to How Claude builds the report\" title=\"Direct link to How Claude builds the report\" translate=\"no\">​</a></h3>\n<ol>\n<li class=\"\"><strong>Checks coverage.</strong> Claude lists the archive for your period, with both ends included: \"September\" is September 1 to 30, \"Q3\" is July 1 to September 30, and \"the last 90 days\" is the 90 days ending yesterday. Missing days are named, and Claude offers to backfill them, or builds the report from the days that exist and says so on the page. It never scales a partial month up to a full one.</li>\n<li class=\"\"><strong>Reads the report script.</strong> For every table the report returns, Claude decides how daily results combine (see the merge rules below).</li>\n<li class=\"\"><strong>Downloads, merges and renders.</strong> Up to 92 days arrive in one download; longer periods are split. The merge takes seconds. The page states the period, the timezone of its day boundaries, the coverage, and whether the script changed during the period.</li>\n</ol>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"merge-rules\">Merge rules<a href=\"https://manual.ingext.io/release/2026-10-23-report-archive#merge-rules\" class=\"hash-link\" aria-label=\"Direct link to Merge rules\" title=\"Direct link to Merge rules\" translate=\"no\">​</a></h3>\n<p>Adding up daily results is only right for some kinds of numbers, so the skill decides table by table from the report's script.</p>\n<table><thead><tr><th>The table holds</th><th>How the days are combined</th></tr></thead><tbody><tr><td>Counts and sizes per key</td><td>Summed per key. A key that appears on only some days still counts.</td></tr><tr><td>A top-N list</td><td>Re-ranked from the summed table. Something ranked 11th every day can be first for the month, so daily top-10s are never combined.</td></tr><tr><td>Totals</td><td>Recomputed from the merged table. Six event types every day is six for the month, not 180.</td></tr><tr><td>A time series</td><td>Each hour kept once, then rolled up to days, or to months for a quarter.</td></tr><tr><td>Peaks, lows, latest state</td><td>The maximum, the minimum, or the newest day's value.</td></tr><tr><td>Averages and ratios</td><td>Recomputed from the summed parts when the report returns them; never an average of daily averages.</td></tr></tbody></table>\n<p>Medians, percentiles, and distinct counts that come without a per-key table cannot be rebuilt from daily values. Claude says so and shows them per day, or leaves them out. It does not approximate them.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"worked-example-and-accuracy\">Worked example and accuracy<a href=\"https://manual.ingext.io/release/2026-10-23-report-archive#worked-example-and-accuracy\" class=\"hash-link\" aria-label=\"Direct link to Worked example and accuracy\" title=\"Direct link to Worked example and accuracy\" translate=\"no\">​</a></h3>\n<p><code>System_Event_Ingress_Report</code> shows how much data a tenant ingests, by event type, product and destination, with a time series. It refuses ranges over 60 days, so a quarter can only be assembled from daily results. On a Fluency test tenant, Claude built it for the 30 days from September 23 to October 22, 2026 (UTC): 30 of 30 days, one script version throughout.</p>\n<ul>\n<li class=\"\">14.81 GB ingested in 5.65 million events, across 6 event types: 494 MB a day on average, with the largest day on October 19 (1.27 GB).</li>\n<li class=\"\">By destination: eventwatch 11.10 GB (3,852,231 events), datalake 3.71 GB (1,798,064 events).</li>\n<li class=\"\">Each daily run also returns the hourly bucket that straddles its start. The 30 buckets that belonged to the previous day were left out of the series, so no hour is counted twice.</li>\n</ul>\n<p>We also ran the report directly over the same 30 days and compared every table:</p>\n<table><thead><tr><th>Table</th><th>Assembled vs. direct run</th></tr></thead><tbody><tr><td>Total ingress</td><td>14,811,590,885 vs. 14,811,615,349 bytes (−0.0002%)</td></tr><tr><td>By event type, product, destination</td><td>Same keys; the worst single key differs by 0.015%</td></tr><tr><td>Daily series</td><td>The worst day differs by 0.0006%</td></tr><tr><td>Top event types and products</td><td>Identical order</td></tr></tbody></table>\n<p>The small differences come from how metrics are measured at the edges of a time window, and they shrink as the period grows. The first time you assemble a report, ask Claude to spot-check one number against a direct run over the last 7 days.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"prompts-to-try\">Prompts to try<a href=\"https://manual.ingext.io/release/2026-10-23-report-archive#prompts-to-try\" class=\"hash-link\" aria-label=\"Direct link to Prompts to try\" title=\"Direct link to Prompts to try\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\">Which of my scheduled reports are archived, and how many days does each have?</li>\n<li class=\"\">Build the September 2026 System Event Ingress report from the archive.</li>\n<li class=\"\">Build a Q3 2026 System Event Ingress report with one row per month in the trend.</li>\n<li class=\"\">Compare System Event Ingress month over month for the last three full months, by event type.</li>\n<li class=\"\">Which days of the last 90 are missing from the System Event Ingress archive? Backfill them.</li>\n</ul>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"limits\">Limits<a href=\"https://manual.ingext.io/release/2026-10-23-report-archive#limits\" class=\"hash-link\" aria-label=\"Direct link to Limits\" title=\"Direct link to Limits\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\"><strong>Retention.</strong> 12 months from the day the archive was turned on. Before that, days can be backfilled while the source data is still in the datalake.</li>\n<li class=\"\"><strong>Today is not included.</strong> A day is archived after it ends, at the next scheduled run. \"Last 30 days\" means the 30 days ending yesterday.</li>\n<li class=\"\"><strong>Missing days.</strong> Claude names them and asks whether to backfill. Backfill runs in the background, one day after another, about one report run per day, and skips days already completed. One backfill runs at a time per tenant. A day whose data has aged out of the datalake comes back empty, and Claude flags days far below their neighbours.</li>\n<li class=\"\"><strong>Script changes.</strong> Each day records the script version it ran on. If the version changes inside your period, Claude warns that days before and after may not be comparable. With your agreement it reruns the older days on the current script, which replaces them.</li>\n<li class=\"\"><strong>Timezone.</strong> Days are in the archive timezone, UTC unless an administrator set another. The page always states it.</li>\n</ul>\n<p>See <a class=\"\" href=\"https://manual.ingext.io/reports/scheduling-and-delivery\">Scheduling and Delivery</a> for putting a report on a schedule.</p>",
            "url": "https://manual.ingext.io/release/2026-10-23-report-archive",
            "title": "Report Archive: Monthly and Quarterly Reports from Daily Runs",
            "summary": "A reports release, published October 23, 2026. A scheduled report can now keep every day's result for 12 months. With the new fluency-report-rollup skill, Claude builds a month, a quarter or a trend from those daily results. It runs no long query, is not held to a report's 60-day limit, and states on the page which days it covers.",
            "date_modified": "2026-10-23T13:55:00.000Z",
            "author": {
                "name": "Sysadmin",
                "url": "https://github.com/SecurityDo"
            },
            "tags": [
                "release",
                "reports",
                "ai"
            ]
        },
        {
            "id": "https://manual.ingext.io/release/2026-10-23-teams-helpdesk-impersonation",
            "content_html": "<p>A detection release for the help desk impersonation campaign that Microsoft Threat Intelligence reported on September 2, 2026, published October 23, 2026. The attacker poses as IT support or a colleague in a Teams chat, calls seconds later, and walks the user into a remote-support session or an installer. Two new high-confidence behavior rules cover the first two steps. <code>O365_Teams_OnMicrosoft_Tenant_Chat</code> alerts on the chat, when it comes from a throwaway <code>*.onmicrosoft.com</code> tenant. <code>O365_Endpoint_Download_From_Azure_CloudApp</code> alerts when a browser downloads an installer from the kind of throwaway Azure host these crews use to deliver it.</p>\n<p>No action is needed: the rules sync to every instance automatically.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"rollout-and-requirements\">Rollout and requirements<a href=\"https://manual.ingext.io/release/2026-10-23-teams-helpdesk-impersonation#rollout-and-requirements\" class=\"hash-link\" aria-label=\"Direct link to Rollout and requirements\" title=\"Direct link to Rollout and requirements\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\"><strong>Rollout.</strong> Both rules are published to the default rule set and reach each instance through resource sync within about two hours. No configuration is needed.</li>\n<li class=\"\"><strong>Data sources.</strong> Both rules read the Microsoft 365 unified audit log, collected by <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/o365-activity-api\">Office365 Audit API</a> or <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/o365-audit\">Office 365 Audit</a>.<!-- -->\n<ul>\n<li class=\"\"><code>O365_Teams_OnMicrosoft_Tenant_Chat</code> needs its Teams records (the <code>Audit.General</code> content type).</li>\n<li class=\"\"><code>O365_Endpoint_Download_From_Azure_CloudApp</code> needs browser-download records, which Windows devices write to the same log once they are <a href=\"https://learn.microsoft.com/en-us/purview/device-onboarding-overview\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">onboarded to Microsoft Purview</a>. Devices already onboarded to Defender for Endpoint are in Purview's device list. Turn on device onboarding in the Purview portal under <strong>Settings</strong> → <strong>Device onboarding</strong>.</li>\n</ul>\n</li>\n<li class=\"\"><strong>Timing.</strong> Microsoft typically delivers Teams audit records 60 to 90 minutes after the event, so the chat alert often arrives after the call has ended. Call records arrive hours later still. That is why the rule alerts on the chat, not the call. Use the alert to contain the attack and to reach everyone the attacker contacted.</li>\n<li class=\"\"><strong>Expected volume.</strong> Outside tenants on <code>onmicrosoft.com</code> rarely open chats with staff. Expect an occasional chat alert when a small vendor or contractor whose tenant has no custom domain starts a chat. Close those as expected. Software vendors do not ship installers from <code>*.cloudapp.azure.com</code>, so the download rule should rarely fire on legitimate activity.</li>\n</ul>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"the-attack\">The attack<a href=\"https://manual.ingext.io/release/2026-10-23-teams-helpdesk-impersonation#the-attack\" class=\"hash-link\" aria-label=\"Direct link to The attack\" title=\"Direct link to The attack\" translate=\"no\">​</a></h3>\n<p>The operator works from a Microsoft 365 tenant of their own. Setting one up takes minutes, and a new tenant's domain is on Microsoft's <code>onmicrosoft.com</code> by default. Some attacks open with mail bombing: the user's mailbox is flooded with subscription-confirmation emails, so a help desk offer to fix it is welcome. Posing as IT, the help desk or a colleague, the attacker opens a one-to-one Teams chat and calls within seconds. The name shown on the call can differ from the name on the account.</p>\n<p>During the call, the attacker talks the user through one of these:</p>\n<ul>\n<li class=\"\">approving a remote-control request, reading back a Quick Assist code, or sharing their screen;</li>\n<li class=\"\">opening a link to a fake IT page hosted on cloud storage;</li>\n<li class=\"\">downloading and running an installer. It may come from a <code>*.cloudapp.azure.com</code> host, the default address of an Azure virtual machine, which anyone can create in minutes.</li>\n</ul>\n<p>In the intrusion Microsoft reported, the operator then runs PowerShell, installs an MSI silently from attacker-controlled cloud storage, and stages a portable Node.js runtime with an encrypted JavaScript implant. The implant persists under an <code>EdgeUpdate</code> Run key or Startup shortcut, and its first tasks check the machine's antivirus and display adapter to spot a sandbox. The operator then enumerates the domain and moves over WinRM to file, database and application servers, domain controllers and certificate authorities. Microsoft describes this as activity that can precede ransomware or data theft. The installers are rebuilt often, so published file hashes go out of date quickly. Storm-1811, a Black Basta ransomware actor, has used the same help desk lure over Teams since 2024.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-detections\">New detections<a href=\"https://manual.ingext.io/release/2026-10-23-teams-helpdesk-impersonation#new-detections\" class=\"hash-link\" aria-label=\"Direct link to New detections\" title=\"Direct link to New detections\" translate=\"no\">​</a></h3>\n<table><thead><tr><th>ID</th><th>Rule</th><th>Severity</th><th>Fires when</th></tr></thead><tbody><tr><td>102180</td><td><code>O365_Teams_OnMicrosoft_Tenant_Chat</code></td><td>High confidence</td><td>A user of a <code>*.onmicrosoft.com</code> tenant outside your organization creates a Teams chat with one or more of your users. Lookalike tenants, such as a copy of your own company name on <code>onmicrosoft.com</code>, are matched. The sender's display name does not matter.</td></tr><tr><td>102181</td><td><code>O365_Endpoint_Download_From_Azure_CloudApp</code></td><td>High confidence</td><td>A browser on a managed Windows device downloads an installer, executable, script, shortcut, archive or disk image (for example <code>.msi</code>, <code>.exe</code>, <code>.ps1</code>, <code>.js</code>, <code>.lnk</code>, <code>.zip</code> or <code>.iso</code>) from a <code>*.cloudapp.azure.com</code> host.</td></tr></tbody></table>\n<p><code>O365_Teams_OnMicrosoft_Tenant_Chat</code> does <strong>not</strong> fire for:</p>\n<ul>\n<li class=\"\">guests of your own organization (<code>#EXT#</code> accounts);</li>\n<li class=\"\">partners who sign in with their own custom domain;</li>\n<li class=\"\">personal (consumer) Teams accounts;</li>\n<li class=\"\">chats that your own users start with an outside tenant;</li>\n<li class=\"\">messages, replies or members added in a chat that already exists.</li>\n</ul>\n<p>It is keyed on the <strong>external account</strong>. If one attacker account messages several employees, the alerts land on one entity and Fluency's <a class=\"\" href=\"https://manual.ingext.io/detections/risk-scoring\">risk scoring</a> groups them into one case. An attacker who rotates tenants produces one case per account. Each alert lists the external account and tenant ID, the users in the chat, the participating domains, the chat thread ID and the chat type.</p>\n<p><code>O365_Endpoint_Download_From_Azure_CloudApp</code> does <strong>not</strong> fire for:</p>\n<ul>\n<li class=\"\">documents and other file types, such as PDFs;</li>\n<li class=\"\">other Azure hosting, such as Azure Blob Storage (<code>*.blob.core.windows.net</code>), which delivered the MSI in the intrusion Microsoft reported;</li>\n<li class=\"\">files fetched by PowerShell or any other program that is not a browser;</li>\n<li class=\"\">devices that are not onboarded to Microsoft Purview.</li>\n</ul>\n<p>It is keyed on the <strong>employee</strong> who downloaded the file. Each alert lists the file, its SHA-256 hash, the host it came from, the device, the browser and the client IP.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"coverage-for-the-rest-of-the-attack\">Coverage for the rest of the attack<a href=\"https://manual.ingext.io/release/2026-10-23-teams-helpdesk-impersonation#coverage-for-the-rest-of-the-attack\" class=\"hash-link\" aria-label=\"Direct link to Coverage for the rest of the attack\" title=\"Direct link to Coverage for the rest of the attack\" translate=\"no\">​</a></h3>\n<p>After the call, the attack moves to the endpoint. If you collect <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/ms-defender\">Microsoft Defender XDR</a>, <a class=\"\" href=\"https://manual.ingext.io/integrations/endpoint-management/crowdstrike-falcon\">CrowdStrike Falcon</a> or <a class=\"\" href=\"https://manual.ingext.io/integrations/endpoint-management/sentinelone-api\">SentinelOne</a> alerts, each alert becomes a Fluency behavior on the user and device it names, with the process command line where the vendor provides it. Microsoft lists Defender XDR detections for the implant, the Node.js loader, <code>rundll32</code> launches, Active Directory enumeration and WinRM lateral movement in this campaign. Defender's mail-bombing and Teams-impersonation alerts arrive the same way, and get triaged with everything else instead of waiting in the Defender queue.</p>\n<p>No log shows what was said on a call or what was on a shared screen. Your EDR's process telemetry is what shows which programs ran afterwards.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"triage-guidance\">Triage guidance<a href=\"https://manual.ingext.io/release/2026-10-23-teams-helpdesk-impersonation#triage-guidance\" class=\"hash-link\" aria-label=\"Direct link to Triage guidance\" title=\"Direct link to Triage guidance\" translate=\"no\">​</a></h3>\n<p>Start from the users in the alert, and work through them in this order. A user who called back or accepted the chat request most likely believed the caller. Teams <code>CallParticipantDetail</code> records in the audit log show which calls were answered, once they arrive.</p>\n<table><thead><tr><th>Priority</th><th>Users</th><th>Why</th></tr></thead><tbody><tr><td>1</td><td>Shared their screen or granted remote control, downloaded or ran anything (including an <code>O365_Endpoint_Download_From_Azure_CloudApp</code> alert), or answered and then called back or accepted the chat</td><td>The attacker may have had hands on the computer, or will be back.</td></tr><tr><td>2</td><td>Answered a call</td><td>The attacker may have asked for a password, an MFA approval or a remote session.</td></tr><tr><td>3</td><td>Chat only, no call</td><td>Warn them.</td></tr></tbody></table>\n<p>A clean sign-in history does not clear a user. The attacker works through the employee's own computer during the call, so the sign-ins in the record are the employee's own.</p>\n<ol>\n<li class=\"\"><strong>Contain any priority 1 computer now.</strong> Isolate it, then review it from the start of the call onward. Look for remote-access tools, an MSI installed from a user-writable path, <code>node.exe</code> running from <code>%LocalAppData%</code>, an <code>EdgeUpdate</code> Run key or Startup shortcut, new services and scheduled tasks, credential dumping, and WinRM or other connections to other hosts.</li>\n<li class=\"\"><strong>Secure the account.</strong> Revoke the user's sessions, reset the password, review MFA methods and registered devices, and check sign-ins from the day of the call onward. Rotate the credentials the computer could reach.</li>\n<li class=\"\"><strong>Block what was downloaded.</strong> For an <code>O365_Endpoint_Download_From_Azure_CloudApp</code> alert, check in your EDR whether the file ran, and add its SHA-256 hash and the download host to your EDR's block indicators.</li>\n<li class=\"\"><strong>Interview priority 1 and 2 users.</strong> Ask what the caller wanted, and whether they opened Quick Assist or another remote tool, opened a link, shared their screen, downloaded or ran anything, typed a password or approved an MFA prompt.</li>\n<li class=\"\"><strong>Review priority 1 and 2 computers in your EDR,</strong> from each call's start to two hours after. With Defender XDR, the <code>CallActivityEvents</code> table in Advanced Hunting shows which attacker calls included screen sharing.</li>\n<li class=\"\"><strong>Close the door.</strong> In the Teams admin center, under <strong>Users</strong> → <strong>External access</strong>, choose <strong>Allow only specific external domains</strong> and list the partners you work with. Blocking attacker domains one at a time does not keep up, because a new tenant takes minutes to create. Also turn off <strong>People in my organization can communicate with unmanaged Teams accounts</strong>: personal accounts are the next place an attacker can come from, and <code>O365_Teams_OnMicrosoft_Tenant_Chat</code> does not match them. If you do not use Quick Assist for IT support, remove or block it.</li>\n<li class=\"\"><strong>Tell people.</strong> If the attacker used a real employee's name, tell that employee. Warn staff that IT will not contact them from an outside Teams account or ask for an unscheduled screen share or installer, and that a sudden flood of spam is a common setup for a fake help desk call.</li>\n</ol>\n<p>To find these alerts, search behavior events by rule name. Each rule is also listed by name on the <a class=\"\" href=\"https://manual.ingext.io/page-functionality/siem/behavior-rules\">Behavior Rules</a> page.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"references\">References<a href=\"https://manual.ingext.io/release/2026-10-23-teams-helpdesk-impersonation#references\" class=\"hash-link\" aria-label=\"Direct link to References\" title=\"Direct link to References\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\">Microsoft Threat Intelligence, <a href=\"https://www.microsoft.com/en-us/security/blog/2026/09/02/impersonating-it-support-threat-actors-turn-remote-session-into-enterprise-wide-access/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\"><em>Impersonating IT support: how threat actors turn a remote session into enterprise-wide access</em></a>, September 2, 2026.</li>\n<li class=\"\">Microsoft Threat Intelligence, <a href=\"https://www.microsoft.com/en-us/security/blog/2024/05/15/threat-actors-misusing-quick-assist-in-social-engineering-attacks-leading-to-ransomware/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\"><em>Threat actors misusing Quick Assist in social engineering attacks leading to ransomware</em></a> (Storm-1811), May 15, 2024, updated June 2024.</li>\n<li class=\"\">Microsoft Learn, <a href=\"https://learn.microsoft.com/en-us/microsoftteams/trusted-organizations-external-meetings-chat\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\"><em>Manage external meetings and chat with people and organizations using Microsoft identities</em></a> (Teams external access settings).</li>\n</ul>",
            "url": "https://manual.ingext.io/release/2026-10-23-teams-helpdesk-impersonation",
            "title": "Teams Helpdesk Impersonation Detections",
            "summary": "A detection release for the help desk impersonation campaign that Microsoft Threat Intelligence reported on September 2, 2026, published October 23, 2026. The attacker poses as IT support or a colleague in a Teams chat, calls seconds later, and walks the user into a remote-support session or an installer. Two new high-confidence behavior rules cover the first two steps. O365TeamsOnMicrosoftTenantChat alerts on the chat, when it comes from a throwaway *.onmicrosoft.com tenant. O365EndpointDownloadFromAzure_CloudApp alerts when a browser downloads an installer from the kind of throwaway Azure host these crews use to deliver it.",
            "date_modified": "2026-10-23T00:00:00.000Z",
            "author": {
                "name": "Sysadmin",
                "url": "https://github.com/SecurityDo"
            },
            "tags": [
                "release",
                "detections"
            ]
        },
        {
            "id": "https://manual.ingext.io/release/2026-10-20-entra-id-detections",
            "content_html": "<p>A detection release for Microsoft Entra ID and Microsoft 365, rolled out October 18–20, 2026. It adds 19 alerting behavior rules and 12 context rules covering three campaigns reported by Microsoft Threat Intelligence (Storm-2755's adversary-in-the-middle (AiTM) session theft, Storm-2372's device-code phishing, and Storm-3119's takeover of whole tenants through a registered app) plus detections for persistence, privilege and sign-in abuse. Five older rules are retired or removed.</p>\n<p>No action is needed: the rules sync to every instance automatically.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"rollout-and-requirements\">Rollout and requirements<a href=\"https://manual.ingext.io/release/2026-10-20-entra-id-detections#rollout-and-requirements\" class=\"hash-link\" aria-label=\"Direct link to Rollout and requirements\" title=\"Direct link to Rollout and requirements\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\"><strong>Rollout.</strong> All rules are published to the default rule set and reach each instance through resource sync within about two hours. No configuration is needed.</li>\n<li class=\"\"><strong>Data sources.</strong> The sign-in rules need Entra ID sign-in logs, and the app, role and federation rules need Entra ID audit logs; <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/entraid-audit-eventhubs\">Entra ID Audit via Event Hubs</a> collects both. The <code>Office365_*</code> rules need the Microsoft 365 unified audit log (<a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/o365-activity-api\">Office365 Audit API</a> or <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/o365-audit\">Office 365 Audit</a>). An instance with only the Microsoft 365 audit log still gets the AiTM capture, mail and file activity, broker-phish and inbox-rule detections.</li>\n<li class=\"\"><strong>Expected volume.</strong> The campaign detections are designed to be rare. Expect the medium-severity rules (<code>EntraID_Valid_Password_Blocked</code>, <code>EntraID_DeviceCode_UserApp</code>, <code>EntraID_High_Risk_App_Permission</code>, <code>EntraID_Privileged_Role_Assigned</code>) to fire on planned admin work and on users blocked by your own Conditional Access policies.</li>\n</ul>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"how-the-rules-work\">How the rules work<a href=\"https://manual.ingext.io/release/2026-10-20-entra-id-detections#how-the-rules-work\" class=\"hash-link\" aria-label=\"Direct link to How the rules work\" title=\"Direct link to How the rules work\" translate=\"no\">​</a></h3>\n<p>Each new rule is either a <strong>detection</strong>, which raises a behavior alert at the severity shown, or <strong>context</strong>, which adds an event to the user's timeline without raising an alert. Severity levels and the high-confidence tag are described in <a class=\"\" href=\"https://manual.ingext.io/detections/risk-scoring#severity-categorization\">Risk Scoring</a>.</p>\n<p>Several of the strongest detections are correlations. They follow one session, one user or one app across sign-in and audit records for hours or days, and alert only when the whole pattern appears. This keeps them quiet on normal activity that looks like a single step of an attack.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-detections\">New detections<a href=\"https://manual.ingext.io/release/2026-10-20-entra-id-detections#new-detections\" class=\"hash-link\" aria-label=\"Direct link to New detections\" title=\"Direct link to New detections\" translate=\"no\">​</a></h3>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"storm-2755-adversary-in-the-middle-session-theft\">Storm-2755: adversary-in-the-middle session theft<a href=\"https://manual.ingext.io/release/2026-10-20-entra-id-detections#storm-2755-adversary-in-the-middle-session-theft\" class=\"hash-link\" aria-label=\"Direct link to Storm-2755: adversary-in-the-middle session theft\" title=\"Direct link to Storm-2755: adversary-in-the-middle session theft\" translate=\"no\">​</a></h4>\n<p>Storm-2755 sends victims to a fake Microsoft 365 sign-in page through search ads and SEO poisoning. The page relays the real sign-in, so the victim completes MFA and the attacker keeps the session token. The actor then replays the token, searches for payroll and HR content, hides replies with inbox rules, and in one reported case changed the victim's bank details in the payroll system.</p>\n<p>MFA does not stop this: the stolen token is an already-authenticated session, and the attacker never sees an MFA prompt. The useful signals are the proxied sign-in itself, and the same session ID appearing later from networks the user has never used.</p>\n<table><thead><tr><th>ID</th><th>Rule</th><th>Severity</th><th>Fires when</th></tr></thead><tbody><tr><td>102111</td><td><code>EntraID_AiTM_Capture</code></td><td>High confidence</td><td>An interactive sign-in ends in a specific error code after MFA was met. A phishing proxy relaying the sign-in drops a field Entra ID asks for, and the session it got still works. Users' own sign-ins almost never end this way.</td></tr><tr><td>102105</td><td><code>Office365_AiTM_Capture</code></td><td>High confidence</td><td>The same capture, from the Microsoft 365 unified audit log.</td></tr><tr><td>102113</td><td><code>EntraID_AiTM_Session_Replay</code></td><td>High confidence</td><td>Any later sign-in or token refresh on the captured session ID, from a network the user did not have at the time of capture. The user's own office, home and company proxy are not raised. High confidence for 14 days after the capture, medium from 14 to 90 days.</td></tr><tr><td>102114</td><td><code>EntraID_AiTM_Session_Activity</code></td><td>High confidence</td><td>Exchange, SharePoint or OneDrive activity under the captured session from a new network: the reconnaissance stage, where Storm-2755 searched for payroll and banking content.</td></tr><tr><td>102106</td><td><code>Office365_InboxRule_Odd_Name</code></td><td>High</td><td>An inbox rule is created or renamed with a name made only of punctuation or a single character, which is how BEC actors keep the rule from standing out. Rules with ordinary names are not matched.</td></tr></tbody></table>\n<p>New and changed authentication methods (how the attacker adds their own MFA method) go on the user's timeline as context, so an investigation of these alerts shows them.</p>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"storm-2372-device-code-phishing\">Storm-2372: device-code phishing<a href=\"https://manual.ingext.io/release/2026-10-20-entra-id-detections#storm-2372-device-code-phishing\" class=\"hash-link\" aria-label=\"Direct link to Storm-2372: device-code phishing\" title=\"Direct link to Storm-2372: device-code phishing\" translate=\"no\">​</a></h4>\n<p>Storm-2372 builds rapport with a target over WhatsApp, Signal or Teams, then sends a fake Teams meeting invitation whose \"meeting ID\" is a device code. When the user enters it at microsoft.com/devicelogin, the attacker's device receives the user's tokens. Since February 2025 the actor has used the Microsoft Authentication Broker client ID, which lets it register a device in Entra ID and keep access.</p>\n<p>The user signs in to a real Microsoft page and completes MFA, and Teams Rooms devices, desk phones and admin tools use the same flow legitimately. The rules separate the two by what happens next: whether the approved session turns up from another network or country.</p>\n<table><thead><tr><th>ID</th><th>Rule</th><th>Severity</th><th>Fires when</th></tr></thead><tbody><tr><td>102129</td><td><code>EntraID_DeviceCode_UserApp</code></td><td>Medium</td><td>Every successful device-code sign-in to an application that is not an admin tool (the broker, Office, Teams, Outlook). A user's first one to an application in 30 days scores higher. Azure CLI, Azure PowerShell and the Graph command-line tools are not matched.</td></tr><tr><td>102115</td><td><code>EntraID_DeviceCode_Phish</code></td><td>High confidence</td><td>A session approved with a device code signs in or refreshes its token from a new network, in a new country, within an hour.</td></tr><tr><td>102109</td><td><code>Office365_Broker_Phish</code></td><td>High confidence</td><td>A broker-approved session signs in or refreshes its token from a network it had not used: high confidence within an hour when the country is also new, medium otherwise and for up to 14 days. Also raised when a device registered to the user within 10 minutes of the approval then signs in from a new network.</td></tr></tbody></table>\n<p>A Teams room or phone set up with a code signs in from its own network in the same country, so it does not raise the phish alerts.</p>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"storm-3119-tenant-takeover-through-a-registered-app\">Storm-3119: tenant takeover through a registered app<a href=\"https://manual.ingext.io/release/2026-10-20-entra-id-detections#storm-3119-tenant-takeover-through-a-registered-app\" class=\"hash-link\" aria-label=\"Direct link to Storm-3119: tenant takeover through a registered app\" title=\"Direct link to Storm-3119: tenant takeover through a registered app\" translate=\"no\">​</a></h4>\n<p>Storm-3119 (YAM Store) is an access broker that resells hijacked Microsoft 365 tenants to phishing operators. With a compromised Global Administrator it provisions an app (the PnP Management Shell service principal), grants it broad Microsoft Graph and SharePoint permissions such as <code>AppCatalog.ReadWrite.All</code>, and adds a client secret. From then on the app works with no user signed in: it resets passwords without forcing a change, assigns licenses and grants privileges. Microsoft and Health-ISAC seized the group's domains on October 14, 2026.</p>\n<p>The app's client secret is a separate credential, so resetting the admin's password and revoking their sessions leaves the app working. Each step on its own also looks like ordinary admin work, which is why this detection follows one app through all of them.</p>\n<table><thead><tr><th>ID</th><th>Rule</th><th>Severity</th><th>Fires when</th></tr></thead><tbody><tr><td>102157</td><td><code>EntraID_App_Takeover</code></td><td>Critical, High or Medium</td><td>Within 72 hours: <strong>critical</strong> when an app holding a high-risk permission acts on users, roles or licenses; <strong>high</strong> when a new or newly keyed app does; <strong>medium</strong> when an app gets a high-risk permission and a new secret. Each level alerts once per app, keyed on the admin who set the app up. Released October 19.</td></tr><tr><td>102118</td><td><code>EntraID_High_Risk_App_Permission</code></td><td>Medium</td><td>An app is granted a high-risk Graph or Exchange permission. On October 19 the list gained <code>User.ReadWrite.All</code>, <code>User-PasswordProfile.ReadWrite.All</code> and <code>AppCatalog.ReadWrite.All</code>.</td></tr></tbody></table>\n<p>If you set up PnP or other automation apps yourself, expect a medium <code>EntraID_App_Takeover</code> alert that you can close as expected.</p>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"persistence-privilege-and-sign-in\">Persistence, privilege and sign-in<a href=\"https://manual.ingext.io/release/2026-10-20-entra-id-detections#persistence-privilege-and-sign-in\" class=\"hash-link\" aria-label=\"Direct link to Persistence, privilege and sign-in\" title=\"Direct link to Persistence, privilege and sign-in\" translate=\"no\">​</a></h4>\n<p>These cover techniques that the campaigns above, and others such as Midnight Blizzard, use once they have a foothold.</p>\n<table><thead><tr><th>ID</th><th>Rule</th><th>Severity</th><th>Fires when</th></tr></thead><tbody><tr><td>102120</td><td><code>EntraID_Federation_Changed</code></td><td>High</td><td>A domain is set to federated, or its federation settings change. A rogue trust lets an attacker sign in as any user of the domain.</td></tr><tr><td>102121</td><td><code>EntraID_Elevated_Access</code></td><td>High</td><td>A Global Administrator elevates to User Access Administrator over all Azure subscriptions.</td></tr><tr><td>102117</td><td><code>EntraID_FIC_Changed</code></td><td>Medium</td><td>A federated identity credential is added to or removed from an app. Tokens from that issuer then sign in as the app without a secret, and secret rotation does not remove them.</td></tr><tr><td>102119</td><td><code>EntraID_Privileged_Role_Assigned</code></td><td>Medium</td><td>A user, group or app is given a privileged Entra ID role or the Azure Owner, User Access Administrator or RBAC Administrator role: directly, through PIM, or as eligible.</td></tr><tr><td>102128</td><td><code>EntraID_High_Risk_SignIn</code></td><td>High</td><td>Entra ID Protection rates a sign-in high risk at sign-in time.</td></tr><tr><td>102125</td><td><code>EntraID_MFA_Fatigue</code></td><td>High</td><td>More than 2 MFA denials or timeouts for one user in an hour (push bombing).</td></tr><tr><td>102126</td><td><code>EntraID_MFA_Fraud_Reported</code></td><td>High</td><td>A user reports an MFA prompt as fraud.</td></tr><tr><td>102124</td><td><code>EntraID_Brute_Force_User</code></td><td>Medium</td><td>More than 15 failed interactive sign-ins for one user in an hour, from any number of IPs. Catches botnets that send one attempt per IP.</td></tr><tr><td>102127</td><td><code>EntraID_Valid_Password_Blocked</code></td><td>Medium</td><td>Conditional Access blocks a sign-in right after the correct password was entered: whoever made the attempt knows the password. Users on unmanaged devices or in blocked countries also trigger it.</td></tr></tbody></table>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"context-rules\">Context rules<a href=\"https://manual.ingext.io/release/2026-10-20-entra-id-detections#context-rules\" class=\"hash-link\" aria-label=\"Direct link to Context rules\" title=\"Direct link to Context rules\" translate=\"no\">​</a></h3>\n<p>These add events to the timeline, or feed the correlations above, without raising alerts. Some are used only inside a correlation and do not appear as events on their own.</p>\n<table><thead><tr><th>ID</th><th>Rule</th><th>Records</th></tr></thead><tbody><tr><td>102131</td><td><code>EntraID_App_Created</code></td><td>An app registration or service principal created (managed identities and Microsoft's own apps excluded). Feeds <code>EntraID_App_Takeover</code>.</td></tr><tr><td>102130</td><td><code>EntraID_App_Credential_Change</code></td><td>A secret or certificate added to or removed from an app. Feeds <code>EntraID_App_Takeover</code>.</td></tr><tr><td>102139</td><td><code>EntraID_Admin_Password_Reset</code></td><td>A password reset by an admin or an app. Feeds <code>EntraID_App_Takeover</code>.</td></tr><tr><td>102134</td><td><code>EntraID_Role_Member_Added</code></td><td>A non-privileged role assignment. Feeds <code>EntraID_App_Takeover</code>.</td></tr><tr><td>102156</td><td><code>EntraID_App_License_Change</code></td><td>A license change made by an app. Feeds <code>EntraID_App_Takeover</code>.</td></tr><tr><td>102116</td><td><code>EntraID_DeviceCode_Consent</code></td><td>A user entered a device code. Recorded for every application. Feeds <code>EntraID_DeviceCode_Phish</code> and <code>Office365_Broker_Phish</code>.</td></tr><tr><td>102110</td><td><code>Office365_Broker_Consent</code></td><td>A broker sign-in approved on Microsoft's \"Are you trying to sign in?\" page. Feeds <code>Office365_Broker_Phish</code>.</td></tr><tr><td>102108</td><td><code>Office365_Device_Registration</code></td><td>A device registered to a user. Feeds <code>Office365_Broker_Phish</code>.</td></tr><tr><td>102112</td><td><code>EntraID_AiTM_Session</code></td><td>Sign-in session lines used to learn each user's networks. Used only inside the AiTM correlation.</td></tr><tr><td>102107</td><td><code>Office365_AiTM_Session</code></td><td>Mail and file activity with its session. Used only inside the AiTM correlation.</td></tr><tr><td>102102</td><td><code>EntraID_User_Add_Authentication_Method</code></td><td>An authentication method registered. <strong>Changed from a high alert to context:</strong> a passkey rollout raised one alert per user.</td></tr><tr><td>102103</td><td><code>EntraID_User_Update_Authentication_Method</code></td><td>An authentication method changed. <strong>Changed from a high alert to context</strong>, for the same reason.</td></tr></tbody></table>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"retired-and-removed\">Retired and removed<a href=\"https://manual.ingext.io/release/2026-10-20-entra-id-detections#retired-and-removed\" class=\"hash-link\" aria-label=\"Direct link to Retired and removed\" title=\"Direct link to Retired and removed\" translate=\"no\">​</a></h3>\n<p>A rule taken out of the release is deleted from each instance at its next sync.</p>\n<table><thead><tr><th>ID</th><th>Rule</th><th>Status</th><th>Why, and what covers it now</th></tr></thead><tbody><tr><td>101907</td><td><code>AzureAD_SFA_Login_Success</code></td><td>Retired</td><td>Older log format. Replaced by <code>EntraID_SFA_Login_Success</code> (102104).</td></tr><tr><td>101984</td><td><code>AzureAD_User_Add_Authentication_Method</code></td><td>Retired</td><td>Duplicated the new rule. Replaced by <code>EntraID_User_Add_Authentication_Method</code> (102102).</td></tr><tr><td>102095</td><td><code>AzureAD_User_Update_Authentication_Method</code></td><td>Retired</td><td>Duplicated the new rule. Replaced by <code>EntraID_User_Update_Authentication_Method</code> (102103).</td></tr><tr><td>102122</td><td><code>EntraID_Attack_Tool_UserAgent</code></td><td>Removed</td><td>A list of tool user agents was noisy and hard to validate: legitimate clients send library and headless-browser user agents too. The user agent stays on every sign-in alert.</td></tr><tr><td>102123</td><td><code>EntraID_Password_Spray_IP</code></td><td>Removed</td><td>Failures per source IP move to a daily password-spray report. <code>EntraID_Brute_Force_User</code> stays.</td></tr></tbody></table>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"triage-guidance\">Triage guidance<a href=\"https://manual.ingext.io/release/2026-10-20-entra-id-detections#triage-guidance\" class=\"hash-link\" aria-label=\"Direct link to Triage guidance\" title=\"Direct link to Triage guidance\" translate=\"no\">​</a></h3>\n<table><thead><tr><th>Alert</th><th>Check first</th><th>Respond</th></tr></thead><tbody><tr><td><code>EntraID_AiTM_Capture</code>, <code>Office365_AiTM_Capture</code></td><td>The URL the user clicked (often a search ad or an email link), the sign-in's IP and ASN, and whether the detected OS matches the user agent (a mismatch is common for a proxy).</td><td>Revoke the user's sessions now, before a replay. Reset the password, and review MFA methods and inbox rules.</td></tr><tr><td><code>EntraID_AiTM_Session_Replay</code>, <code>EntraID_AiTM_Session_Activity</code></td><td>The new networks and countries, the apps used, and which mail or files were read.</td><td>Revoke sessions and refresh tokens, remove attacker MFA methods and inbox rules, and check payroll and banking changes.</td></tr><tr><td><code>Office365_Broker_Phish</code>, <code>EntraID_DeviceCode_Phish</code></td><td>Ask the user whether they entered a code, and from what message. Check for a device registered right after the approval.</td><td>Revoke sessions, delete the attacker's registered device, and block the device-code flow with Conditional Access where it is not needed.</td></tr><tr><td><code>EntraID_App_Takeover</code></td><td>The app's name and owner, who granted its permissions and added its secret, and which users it changed.</td><td>Contain the app first: disable it and remove its secrets and role assignments. Then secure the admin account. A password reset alone leaves the app's secret working.</td></tr><tr><td><code>EntraID_Federation_Changed</code>, <code>EntraID_FIC_Changed</code></td><td>Whether the change was planned. For a federated credential, the issuer and subject, and whether the issuer is outside the tenant.</td><td>Revert an unplanned trust or credential, then review sign-ins through it.</td></tr></tbody></table>\n<p>Rule IDs are the same on every instance. To find these alerts, search behavior events by rule name; each rule is also listed by name on the <a class=\"\" href=\"https://manual.ingext.io/page-functionality/siem/behavior-rules\">Behavior Rules</a> page.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"references\">References<a href=\"https://manual.ingext.io/release/2026-10-20-entra-id-detections#references\" class=\"hash-link\" aria-label=\"Direct link to References\" title=\"Direct link to References\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\">Microsoft Threat Intelligence, <a href=\"https://www.microsoft.com/en-us/security/blog/2026/04/09/investigating-storm-2755-payroll-pirate-attacks-targeting-canadian-employees/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\"><em>Investigating Storm-2755: \"Payroll pirate\" attacks targeting Canadian employees</em></a>, April 9, 2026.</li>\n<li class=\"\">Microsoft Threat Intelligence, <a href=\"https://www.microsoft.com/en-us/security/blog/2025/02/13/storm-2372-conducts-device-code-phishing-campaign/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\"><em>Storm-2372 conducts device code phishing campaign</em></a>, February 13, 2025, updated 2026.</li>\n<li class=\"\">Microsoft Threat Intelligence, <a href=\"https://www.microsoft.com/en-us/security/blog/2026/10/14/the-hidden-network-inside-the-phishing-infrastructure-ecosystem-powering-global-cybercrime/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\"><em>The hidden network: Inside the phishing infrastructure ecosystem powering global cybercrime</em></a> (Storm-3119, YAM Store), October 14, 2026.</li>\n</ul>",
            "url": "https://manual.ingext.io/release/2026-10-20-entra-id-detections",
            "title": "Entra ID Detection Update",
            "summary": "A detection release for Microsoft Entra ID and Microsoft 365, rolled out October 18–20, 2026. It adds 19 alerting behavior rules and 12 context rules covering three campaigns reported by Microsoft Threat Intelligence (Storm-2755's adversary-in-the-middle (AiTM) session theft, Storm-2372's device-code phishing, and Storm-3119's takeover of whole tenants through a registered app) plus detections for persistence, privilege and sign-in abuse. Five older rules are retired or removed.",
            "date_modified": "2026-10-20T00:00:00.000Z",
            "author": {
                "name": "Sysadmin",
                "url": "https://github.com/SecurityDo"
            },
            "tags": [
                "release",
                "detections"
            ]
        },
        {
            "id": "https://manual.ingext.io/release/2026-10-13-platform-update",
            "content_html": "<p>The v2 interface is available on every instance, and every escalated case now carries an AI investigation report. Detections gain parser rules, and Entra ID audit and sign-in logs, including non-interactive sign-ins, can be collected through Azure Event Hubs.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"changes\">Changes<a href=\"https://manual.ingext.io/release/2026-10-13-platform-update#changes\" class=\"hash-link\" aria-label=\"Direct link to Changes\" title=\"Direct link to Changes\" translate=\"no\">​</a></h3>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"v2-interface\">v2 interface<a href=\"https://manual.ingext.io/release/2026-10-13-platform-update#v2-interface\" class=\"hash-link\" aria-label=\"Direct link to v2 interface\" title=\"Direct link to v2 interface\" translate=\"no\">​</a></h4>\n<ul>\n<li class=\"\">The v2 interface is available to all tenants. Add <code>/v2</code> after your instance's address, for example <code>https://&lt;companyname&gt;.app.ingext.io/v2</code>. The current interface stays at the same address.</li>\n</ul>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"ai-investigation-reports\">AI investigation reports<a href=\"https://manual.ingext.io/release/2026-10-13-platform-update#ai-investigation-reports\" class=\"hash-link\" aria-label=\"Direct link to AI investigation reports\" title=\"Direct link to AI investigation reports\" translate=\"no\">​</a></h4>\n<ul>\n<li class=\"\">Every escalated case has an AI investigation report attached. See <a class=\"\" href=\"https://manual.ingext.io/ai-features/workflows\">Investigation Workflows</a>.</li>\n</ul>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"parser-rules\">Parser rules<a href=\"https://manual.ingext.io/release/2026-10-13-platform-update#parser-rules\" class=\"hash-link\" aria-label=\"Direct link to Parser rules\" title=\"Direct link to Parser rules\" translate=\"no\">​</a></h4>\n<p>Fluency now supports <strong>parser rules</strong> alongside EventWatch rules. A parser rule looks like an EventWatch rule without the event selector: instead of selecting events from the whole stream, it receives the events a parser hands to it on a named channel.</p>\n<ul>\n<li class=\"\">A parser passes an event to every parser rule on a channel with <code>Platform_Channel</code>, for example <code>Platform_Channel(\"Office365Exchange\", {obj})</code>.</li>\n<li class=\"\">The <code>fpl_rule</code> processor on that channel does the matching and captures the attributes, and a match goes straight to the correlation service, bypassing EventWatch.</li>\n<li class=\"\">Rules can be added to a channel without changing the parser that transforms the events.</li>\n</ul>\n<p>See <a class=\"\" href=\"https://manual.ingext.io/detections/\">Detections</a>.</p>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"entra-id-audit-through-azure-event-hubs\">Entra ID audit through Azure Event Hubs<a href=\"https://manual.ingext.io/release/2026-10-13-platform-update#entra-id-audit-through-azure-event-hubs\" class=\"hash-link\" aria-label=\"Direct link to Entra ID audit through Azure Event Hubs\" title=\"Direct link to Entra ID audit through Azure Event Hubs\" translate=\"no\">​</a></h4>\n<ul>\n<li class=\"\">A new opt-in application, <strong>Azure Directory Audit (Event Hub)</strong>, collects Entra ID audit and sign-in logs through an Azure Event Hub. It includes the non-interactive and service principal sign-ins that the Graph-based feed does not collect.</li>\n<li class=\"\">Expect several times the volume of the current feed. Microsoft charges for the Event Hubs namespace.</li>\n</ul>\n<p>See <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/entraid-audit-eventhubs\">Entra ID Audit via Event Hubs</a>.</p>",
            "url": "https://manual.ingext.io/release/2026-10-13-platform-update",
            "title": "October 2026 Platform Update",
            "summary": "The v2 interface is available on every instance, and every escalated case now carries an AI investigation report. Detections gain parser rules, and Entra ID audit and sign-in logs, including non-interactive sign-ins, can be collected through Azure Event Hubs.",
            "date_modified": "2026-10-13T00:00:00.000Z",
            "author": {
                "name": "Sysadmin",
                "url": "https://github.com/SecurityDo"
            },
            "tags": [
                "release",
                "platform"
            ]
        },
        {
            "id": "https://manual.ingext.io/release/v2.6.50",
            "content_html": "<p>A milestone release. EventWatch now runs under the job manager, which extends exactly-once processing through rule evaluation and lets the processing pipeline scale past 1 TB per day. The release also adds KQL search history, a <code>send_email</code> MCP tool, and SentinelOne, CrowdStrike Falcon, LDAP, Duo and Abnormal Security applications.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"changes\">Changes<a href=\"https://manual.ingext.io/release/v2.6.50#changes\" class=\"hash-link\" aria-label=\"Direct link to Changes\" title=\"Direct link to Changes\" translate=\"no\">​</a></h3>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"processing\">Processing<a href=\"https://manual.ingext.io/release/v2.6.50#processing\" class=\"hash-link\" aria-label=\"Direct link to Processing\" title=\"Direct link to Processing\" translate=\"no\">​</a></h4>\n<ul>\n<li class=\"\"><strong>EventWatch job manager.</strong> EventWatch runs under the job manager, so every event is evaluated exactly once, and the pipeline scales to more than 1 TB per day.</li>\n<li class=\"\">Fixed an out-of-memory failure when the data lake merges large indexes.</li>\n<li class=\"\">Fixed a syslog reader bug.</li>\n</ul>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"kql-search-history\">KQL search history<a href=\"https://manual.ingext.io/release/v2.6.50#kql-search-history\" class=\"hash-link\" aria-label=\"Direct link to KQL search history\" title=\"Direct link to KQL search history\" translate=\"no\">​</a></h4>\n<ul>\n<li class=\"\">Every KQL search is saved for the whole account, and its results can be reopened from <strong>Data Lake → KQL Search History</strong> without running the query again. See <a class=\"\" href=\"https://manual.ingext.io/page-functionality/data-lake/kql-search-history\">KQL Search History</a>.</li>\n</ul>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"mcp\">MCP<a href=\"https://manual.ingext.io/release/v2.6.50#mcp\" class=\"hash-link\" aria-label=\"Direct link to MCP\" title=\"Direct link to MCP\" translate=\"no\">​</a></h4>\n<ul>\n<li class=\"\">New tool <a class=\"\" href=\"https://manual.ingext.io/reference/api/mcp-tools#send_email\"><code>send_email</code></a> sends email through the instance's notification endpoints. See <a class=\"\" href=\"https://manual.ingext.io/reference/api/mcp\">MCP Server</a>.</li>\n</ul>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-applications\">New applications<a href=\"https://manual.ingext.io/release/v2.6.50#new-applications\" class=\"hash-link\" aria-label=\"Direct link to New applications\" title=\"Direct link to New applications\" translate=\"no\">​</a></h4>\n<ul>\n<li class=\"\"><a class=\"\" href=\"https://manual.ingext.io/integrations/endpoint-management/sentinelone-api\">SentinelOne</a></li>\n<li class=\"\"><a class=\"\" href=\"https://manual.ingext.io/integrations/endpoint-management/crowdstrike-falcon\">CrowdStrike Falcon</a></li>\n<li class=\"\"><a class=\"\" href=\"https://manual.ingext.io/data-collection/ldap-integration\">LDAP</a></li>\n<li class=\"\"><a class=\"\" href=\"https://manual.ingext.io/integrations/business-software/cisco-duo\">Duo</a></li>\n<li class=\"\"><a class=\"\" href=\"https://manual.ingext.io/page-functionality/platform/applications/install-from-template#abnormal-security\">Abnormal Security</a></li>\n</ul>",
            "url": "https://manual.ingext.io/release/v2.6.50",
            "title": "Platform Update v2.6.50",
            "summary": "A milestone release. EventWatch now runs under the job manager, which extends exactly-once processing through rule evaluation and lets the processing pipeline scale past 1 TB per day. The release also adds KQL search history, a send_email MCP tool, and SentinelOne, CrowdStrike Falcon, LDAP, Duo and Abnormal Security applications.",
            "date_modified": "2026-07-24T00:00:00.000Z",
            "author": {
                "name": "Sysadmin",
                "url": "https://github.com/SecurityDo"
            },
            "tags": [
                "release",
                "platform"
            ]
        },
        {
            "id": "https://manual.ingext.io/release/2026-06-30-kql-data-types",
            "content_html": "<p>Five more data sources can be queried with KQL as typed tables: Zscaler, Cisco Meraki, F5 BIG-IP LTM, Palo Alto Networks Cortex alerts and incidents, and Qualys, each released with sample queries. Windows audit events, whose schema shipped in v2.6.16, gain sample queries too.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-data-types\">New data types<a href=\"https://manual.ingext.io/release/2026-06-30-kql-data-types#new-data-types\" class=\"hash-link\" aria-label=\"Direct link to New data types\" title=\"Direct link to New data types\" translate=\"no\">​</a></h3>\n<table><thead><tr><th>Data type</th><th>Source</th></tr></thead><tbody><tr><td><code>Zscaler</code></td><td><a class=\"\" href=\"https://manual.ingext.io/integrations/cloud-networking/zscaler\">Zscaler</a></td></tr><tr><td><code>Meraki</code></td><td><a class=\"\" href=\"https://manual.ingext.io/integrations/on-prem-syslog/cisco-meraki\">Cisco Meraki</a></td></tr><tr><td><code>F5BigIPLTM</code></td><td>F5 BIG-IP Local Traffic Manager</td></tr><tr><td><code>CortexAlert</code>, <code>CortexIncident</code></td><td><a class=\"\" href=\"https://manual.ingext.io/integrations/endpoint-management/paloalto-cortex-xdr\">Palo Alto Networks Cortex XDR</a></td></tr><tr><td><code>Qualys</code></td><td><a class=\"\" href=\"https://manual.ingext.io/page-functionality/platform/applications/install-from-template#qualys\">Qualys</a></td></tr></tbody></table>\n<p>They join the FortiGate traffic and event tables and the <code>Office365</code>, <code>WindowsAudit</code>, <code>GSuite</code> and <code>CloudTrail</code> schemas added in <a class=\"\" href=\"https://manual.ingext.io/release/v2.6.16\">v2.6.16</a>. Sample queries for <code>WindowsAudit</code>, covering event logs from <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/windows-server/\">Windows servers</a>, ship with this release.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"writing-queries\">Writing queries<a href=\"https://manual.ingext.io/release/2026-06-30-kql-data-types#writing-queries\" class=\"hash-link\" aria-label=\"Direct link to Writing queries\" title=\"Direct link to Writing queries\" translate=\"no\">​</a></h3>\n<p>The record's time is the <code>timestamp</code> column, so a time filter is written <code>where timestamp &gt; ago(1d)</code>. Columns from the Azure Monitor tables, such as <code>TimeGenerated</code>, do not exist here.</p>\n<div class=\"language-kql codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#f5f5f5;--prism-background-color:#111111\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-kql codeBlock_bY9V thin-scrollbar\" style=\"color:#f5f5f5;background-color:#111111\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#f5f5f5\"><span class=\"token plain\">WindowsAudit</span><br></div><div class=\"token-line\" style=\"color:#f5f5f5\"><span class=\"token plain\">| where timestamp &gt; ago(1d)</span><br></div><div class=\"token-line\" style=\"color:#f5f5f5\"><span class=\"token plain\">| summarize Events = count() by EventID</span><br></div><div class=\"token-line\" style=\"color:#f5f5f5\"><span class=\"token plain\">| order by Events desc</span><br></div></code></pre></div></div>\n<p>See <a class=\"\" href=\"https://manual.ingext.io/reference/kql/\">KQL</a> for the data model and query cost.</p>",
            "url": "https://manual.ingext.io/release/2026-06-30-kql-data-types",
            "title": "New KQL Data Types",
            "summary": "Five more data sources can be queried with KQL as typed tables: Zscaler, Cisco Meraki, F5 BIG-IP LTM, Palo Alto Networks Cortex alerts and incidents, and Qualys, each released with sample queries. Windows audit events, whose schema shipped in v2.6.16, gain sample queries too.",
            "date_modified": "2026-06-30T00:00:00.000Z",
            "author": {
                "name": "Sysadmin",
                "url": "https://github.com/SecurityDo"
            },
            "tags": [
                "release",
                "kql"
            ]
        },
        {
            "id": "https://manual.ingext.io/release/v2.6.28",
            "content_html": "<p>The Microsoft 365 applications can be set up with an app registration you create yourself, instead of through admin consent. Workday, Abnormal Security, Azure Event Hubs and Qualys move to the new platform, and resource polling for Office 365 and SentinelOne runs as a separate job.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"changes\">Changes<a href=\"https://manual.ingext.io/release/v2.6.28#changes\" class=\"hash-link\" aria-label=\"Direct link to Changes\" title=\"Direct link to Changes\" translate=\"no\">​</a></h3>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"manual-setup-for-the-microsoft-365-applications\">Manual setup for the Microsoft 365 applications<a href=\"https://manual.ingext.io/release/v2.6.28#manual-setup-for-the-microsoft-365-applications\" class=\"hash-link\" aria-label=\"Direct link to Manual setup for the Microsoft 365 applications\" title=\"Direct link to Manual setup for the Microsoft 365 applications\" translate=\"no\">​</a></h4>\n<p>The <strong>Office365</strong>, <strong>Office365 Resource Watch</strong> and <strong>Azure Directory Audit</strong> templates support manual configuration as well as admin consent:</p>\n<ol>\n<li class=\"\">Go to <strong>Platform → Applications → Install Application from Template</strong> and open the template.</li>\n<li class=\"\">Under <strong>Parameters</strong>, clear <strong>Enable Admin Consent Mode?</strong>.</li>\n<li class=\"\">Enter the <strong>Azure Tenant ID</strong>, <strong>Azure ClientID</strong> and <strong>Azure ClientSecret</strong> of your app registration.</li>\n</ol>\n<p>One app registration that holds the permissions of all three applications can serve all three, using the same client ID and secret.</p>\n<p>Manual setup suits a tenant where the consent flow is blocked, for example by browser protection, or where policy requires an app registration you own. Admin consent remains the default.</p>\n<p>See <a class=\"\" href=\"https://manual.ingext.io/page-functionality/platform/applications/install-from-template\">Install Application from Template</a>, <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/o365-activity-api\">Office 365 Activity API</a>, <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/o365-resourcewatch\">Office 365 Resource Watch</a> and <a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/azuread-audit\">Azure AD audit</a>.</p>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"applications-on-the-new-platform\">Applications on the new platform<a href=\"https://manual.ingext.io/release/v2.6.28#applications-on-the-new-platform\" class=\"hash-link\" aria-label=\"Direct link to Applications on the new platform\" title=\"Direct link to Applications on the new platform\" translate=\"no\">​</a></h4>\n<p>These applications are now available on the new platform:</p>\n<ul>\n<li class=\"\"><a class=\"\" href=\"https://manual.ingext.io/integrations/business-software/workday\">Workday</a></li>\n<li class=\"\"><a class=\"\" href=\"https://manual.ingext.io/page-functionality/platform/applications/install-from-template#abnormal-security\">Abnormal Security</a></li>\n<li class=\"\"><a class=\"\" href=\"https://manual.ingext.io/integrations/microsoft/azure-event-hubs\">Azure Event Hubs</a></li>\n<li class=\"\"><a class=\"\" href=\"https://manual.ingext.io/page-functionality/platform/applications/install-from-template#qualys\">Qualys</a></li>\n</ul>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"resource-polling-as-jobs\">Resource polling as jobs<a href=\"https://manual.ingext.io/release/v2.6.28#resource-polling-as-jobs\" class=\"hash-link\" aria-label=\"Direct link to Resource polling as jobs\" title=\"Direct link to Resource polling as jobs\" translate=\"no\">​</a></h4>\n<ul>\n<li class=\"\">Selected Resource Watch plugins run as jobs on a separate worker, apart from the instance's other integrations. Office365 Resource Watch and SentinelOne run this way.</li>\n</ul>",
            "url": "https://manual.ingext.io/release/v2.6.28",
            "title": "Platform Update v2.6.28",
            "summary": "The Microsoft 365 applications can be set up with an app registration you create yourself, instead of through admin consent. Workday, Abnormal Security, Azure Event Hubs and Qualys move to the new platform, and resource polling for Office 365 and SentinelOne runs as a separate job.",
            "date_modified": "2026-06-28T00:00:00.000Z",
            "author": {
                "name": "Sysadmin",
                "url": "https://github.com/SecurityDo"
            },
            "tags": [
                "release",
                "platform",
                "applications"
            ]
        },
        {
            "id": "https://manual.ingext.io/release/2026-06-18-ingext-skills",
            "content_html": "<p>The first versioned release of Ingext Skills adds two skills that turn natural-language questions into validated, ready-to-run queries, with no query language required: <code>ingext-kql</code> for events in the data lake, and <code>ingext-promql</code> for platform health. Ten skills ship in this release, and all of them are open source.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"ingext-kql-investigate-events-in-the-data-lake\">ingext-kql: investigate events in the data lake<a href=\"https://manual.ingext.io/release/2026-06-18-ingext-skills#ingext-kql-investigate-events-in-the-data-lake\" class=\"hash-link\" aria-label=\"Direct link to ingext-kql: investigate events in the data lake\" title=\"Direct link to ingext-kql: investigate events in the data lake\" translate=\"no\">​</a></h3>\n<p>Ask a question about your logs and get back a correct KQL query against sign-ins, audit logs, file activity and network traffic. For example:</p>\n<ul>\n<li class=\"\">\"Top source IPs by denied FortiGate traffic in the last 24 hours\"</li>\n<li class=\"\">\"Sign-ins by country and client app: how many succeeded and how many failed?\"</li>\n<li class=\"\">\"Users with the most failed logins this week, and where from\"</li>\n<li class=\"\">\"Devices that haven't signed in for 90 days or more\"</li>\n<li class=\"\">\"Directory and role changes made by a given user\"</li>\n</ul>\n<p>Queries are checked against the table schemas and validated before you run them.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"ingext-promql-measure-platform-health\">ingext-promql: measure platform health<a href=\"https://manual.ingext.io/release/2026-06-18-ingext-skills#ingext-promql-measure-platform-health\" class=\"hash-link\" aria-label=\"Direct link to ingext-promql: measure platform health\" title=\"Direct link to ingext-promql: measure platform health\" translate=\"no\">​</a></h3>\n<p>Ask about throughput, volume and reliability across the platform. For example:</p>\n<ul>\n<li class=\"\">\"Events per second by component right now\"</li>\n<li class=\"\">\"Top source apps by ingest volume this hour\"</li>\n<li class=\"\">\"Which processors are throwing errors?\"</li>\n<li class=\"\">\"Data-lake ingest rate by index\"</li>\n<li class=\"\">\"Current queue depth by service\"</li>\n</ul>\n<p>Answers come only from the known metrics catalog, so the skill does not guess at metric names.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"getting-the-skills\">Getting the skills<a href=\"https://manual.ingext.io/release/2026-06-18-ingext-skills#getting-the-skills\" class=\"hash-link\" aria-label=\"Direct link to Getting the skills\" title=\"Direct link to Getting the skills\" translate=\"no\">​</a></h3>\n<p>The skills, release notes and sources are in the <a href=\"https://github.com/SecurityDo/ingext_skills\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">ingext_skills</a> repository. Each skill carries a version number; to check whether an installed skill is current, compare it with the released version in the repository. In Claude, installed skills are listed under <strong>Customize → Skills</strong>.</p>\n<p>The skills work through the platform's MCP server. See <a class=\"\" href=\"https://manual.ingext.io/reference/api/mcp\">MCP Server</a>.</p>",
            "url": "https://manual.ingext.io/release/2026-06-18-ingext-skills",
            "title": "Ingext Skills: Ask Your Data in Plain English",
            "summary": "The first versioned release of Ingext Skills adds two skills that turn natural-language questions into validated, ready-to-run queries, with no query language required: ingext-kql for events in the data lake, and ingext-promql for platform health. Ten skills ship in this release, and all of them are open source.",
            "date_modified": "2026-06-18T00:00:00.000Z",
            "author": {
                "name": "Sysadmin",
                "url": "https://github.com/SecurityDo"
            },
            "tags": [
                "release",
                "ai"
            ]
        }
    ]
}