All release notes
Platform
Patching that lands, and a real detection uplink
A release focused on making patching actually land and on giving the Windows agent a real detection uplink. Adds sign-in country policy and impossible-travel detection for Microsoft 365, moves patch and third-party package installation off PowerShell so it works on heavily hardened endpoints, and bounds install attempts so a stuck installation is visible instead of repeating forever.
New
- Sign-in country policy per Microsoft 365 tenant: each connected tenant declares the countries its users are expected to sign in from, and sign-ins originating anywhere else are raised as posture findings. It is deliberately per tenant rather than one platform-wide default, because a customer with a Dutch back office and an Indian development team configures both instead of inheriting a default that fits neither. A tenant with no list configured is not fenced at all: an empty list means not configured, never block everything. Each finding carries the observed country, the signing-in principal and the application involved, so nobody has to go digging in the Entra sign-in logs first.
- Impossible-travel detection for Microsoft 365 sign-ins: successive interactive sign-ins for the same principal from different locations are checked against whether a person could physically have made the trip. The feasibility floor accounts for both short movements over the ground and long flights including a fixed allowance for airport overhead, so a pair of sign-ins between Amsterdam and Singapore is not flagged merely for being fast. Sign-ins whose location cannot be resolved, or resolves only coarsely, are skipped rather than guessed at.
- Detection uplink for the Windows agent: the agent previously had only an inventory heartbeat and now gains a full channel for detection work. Urgent findings are reported immediately instead of waiting for the next 30-minute cycle. Process events are recorded as an ancestry chain rather than isolated executions, which is what makes attribution and correlation possible downstream. Policy is distributed per client instead of being compiled into the binary, and local rule sets are cryptographically signed with verification that fails closed: a build with no key compiled in accepts no rule set at all, because an unsigned rule path would amount to a remote execution channel into every agent in the fleet.
- Report-only mode for the agent: a device can run during onboarding in a mode where the agent records what it would have done without carrying it out, so there is visibility into what would have been blocked before anything actually is. Indicators can be blocked across clients, and lifting a block is an explicit, audited action rather than a silent consequence of an indicator ageing out.
- New Agent page showing per-device agent health, policy status and pending decisions. Device records additionally carry tamper protection status, isolation, telemetry health, local rules and whether the watchdog is installed.
- Investigations correlate signals: related signals are gathered into a single working record instead of presenting each detection on its own. A signal that recurs after an investigation was closed opens a new one rather than silently reviving the old record, so the timeline does not lie about when it started. The correlation window deliberately does not slide: a sliding window can be held open indefinitely by a low-and-slow signal, and that is precisely the case where an accurate start time matters most. Analyst observations can be attached independently of the signals that opened the case and survive a rescore.
- Attempt accounting and telemetry for patch and package delivery: failed installations are now bounded and visible instead of retried forever. Third-party packages carry two separate budgets, because a single flat cap would be wrong: a per-user package on a laptop sitting at the login screen fails for a reason that disappears the moment somebody logs in. Those attempts count as deferred rather than failed, but are still bounded, because a departed employee's profile defers forever and a row that defers forever is indistinguishable from one that is working.
- Also new: a device statistics endpoint, and an action to undo the decline of a Defender definition update. Declining was previously final and the update simply disappeared from the queue.
Improved
- Windows update and third-party package installation no longer run through PowerShell. Both paths invoked PowerShell with an execution-policy bypass, which is exactly what Constrained Language Mode, WDAC and AppLocker exist to block. The result was that patching failed silently on the most carefully configured machines, and raised alerts in whatever other security software the customer was running. Windows updates are now driven through the native Windows Update interface, in a separate process so a wedged update service can never freeze the agent itself. The post-install verification pass is preserved: Windows reports a definition update as succeeded before Defender has actually applied the signatures, so a re-check downgrades succeeded but still missing back to failed.
- Winget is now resolved directly rather than through the system search paths, where it was structurally unfindable under the service account, preferring an architecture match and then the highest version, and re-resolving when the Store updates the package into a new directory.
- Reading available package updates now works on non-English Windows installations and on package names containing non-Latin characters. The column locator matched the literal English headers, so a non-English install silently reported zero available updates, and columns were sliced by bytes rather than characters, so a single unusual character in a package name shifted every subsequent column.
- Windows updates now honour maintenance windows. These previously gated third-party packages but not Windows updates, meaning the more disruptive of the two was the unrestricted one. See the Changed section.
- All active user sessions are now visible. Previously only the console session, or the first active one, was examined, so on a terminal server or a machine using fast user switching only one user was ever in view, silently. The scan unions results across every session and reports when coverage was partial, with a time budget per package so a host with ten sessions cannot starve the regular collection cycle.
Fixed
- Per-user packages were reported as upgraded without being upgraded. Installation ran under the service account first, and for a package living in a user profile that does not upgrade that user's copy: a second copy could be installed under the service account, reporting success, while the vulnerable copy stayed in place. The agent reported success, the next inventory saw the package again, and with no attempt cap that cycle repeated every fifteen minutes indefinitely. A package's scope is now derived by looking in both security contexts, and assigned only when both were reachable. If one was not, the agent reports unknown rather than guessing, and installation then follows the scope.
- One device-level problem marked every patch in the batch as failed: a missing helper component, a hung update service or an agent without the necessary rights was flattened into every update in this batch failed. Because the attempt counter increments at dispatch, three of those in a row permanently parked patches that had never been attempted once. Such a failure is now reported as what it is, the cycle stops rather than manufacturing verdicts about individual updates it does not have, and the attempt is refunded.
- A transient registry read failure produced a storm of false persistence alerts: a failed first read was treated as an empty baseline, so the next change notification emitted every existing value as newly added, each at critical severity and each reported immediately. A failed read now keeps the previous baseline. Additionally, only text values were being read and everything else collapsed to an empty string, which made a numeric value flipping between 0 and 1 invisible.
- The Microsoft 365 posture module was silently producing wrong results. A check whose data could not be retrieved now reports as unknown rather than as a pass; previously a permissions gap looked like a clean tenant. Certificate authentication failed because the thumbprint was computed over the wrong component. A batch of false positives across named locations, privileged role enumeration, default user permissions and application assignments has been corrected.
- Fleet-wide backfill of patch rows removed: rows were created for devices that had never reported the patch as missing, and those rows then entered the install queue as real work. The rows already created are cleaned up.
- A device's compliance score was uncapped and could report above 100.
Security
- Process memory scanning no longer trusts a process based on its name. Trust now requires a signed executable living outside user-writable storage. Anything failing that test is scanned whatever it calls itself, and the refusal to grant an exemption is logged.
- The agent no longer reports its own maintenance work as a detection. Attribution is based on process ancestry, and attributed events keep their full record at a reduced severity rather than being suppressed. Nothing is dropped. Findings involving credential theft, disabling recovery, defence evasion and masquerading are never de-escalated, and neither is persistence placed in the startup folder.
- Disconnecting a Microsoft 365 tenant now genuinely removes its stored credentials. A storage-layer fault meant they were left in place on disconnect. If you have previously disconnected a tenant, revoke the corresponding application credential in Entra to be certain.
- Errors raised while acquiring tokens are scrubbed before logging; they previously carried authentication material.
Changed
- Windows updates are now restricted to configured maintenance windows. Tenants with existing maintenance windows will find Windows update installation newly bound to them. This is the intended outcome, but it changes when patching happens and not only whether it is allowed. There is deliberately no exception for critical updates: if one is wanted, it should be explicit policy.
- Patch installation no longer enables System Restore. The old path silently switched System Restore back on for machines where it had been deliberately turned off. The new path only attempts to create a restore point.