All release notes
Platform
Exposure scoring, M365 drift, and workable investigations
A release about scores and signals that were being computed and then not read. Risk scoring gains an exposure model built on real reachability and a single scoring standard for findings that carry no CVE, Microsoft 365 gains Secure Score in context, posture drift and time-boxed exceptions, and Investigations becomes a case an analyst can work rather than read. Note the Changed section: several parts of this release alter how open risks are ranked and counted the moment you upgrade.
New
- Attack-path exposure model: risk scoring used to ask whether a device was listening on a frightening port number and add flat points for the answer. That question cannot separate a service bound to loopback from one facing the internet. The model now asks three separable questions: which way the attack comes in (derived from the CVSS vector, so a browser RCE and a listening network service are no longer treated as the same thing), whether an attacker can actually reach it (a reachability tier built from socket bind addresses, firewall profile state, inbound-allow rules, adapter addressing and the site's declared network posture), and whether your controls block that specific path (disk encryption stops laptop theft and does nothing for a network RCE). Exposure and controls are now multiplicative rather than additive, so a fully hardened host can no longer rank structurally above a bare one. Where a risk affects several devices, the worst affected device now drives the score.
- Network posture per site: the operator-declared perimeter that an endpoint agent structurally cannot observe now caps the reachability tier for every device at that site. New views show, per device, how many listening sockets are genuinely reachable, and per risk, why the score is what it is, replacing a list of anonymous point values.
- A single scoring standard for risks with no CVE: custom-rule and Microsoft 365 posture risks previously scored 0.0 regardless of the severity their producer declared, so a posture finding rated high sorted below a CVE rated low. The producer now declares a severity band, scoring ranks within that band, and context can move a score at most one band. Evidence class is its own axis: behaviour we observed outranks something inferred from an absence of data. Certificate risks are re-scored on every probe and take their urgency from the time remaining, instead of holding the score they were given on the day they were raised for two months while the certificate marched toward expiry.
- Confidence gate for CVE correlation: correlation findings are sorted into three tiers by how certain the match is. Confident enough is auto-accepted, borderline is shown and flagged for adjudication, and too uncertain is downgraded to informational and hidden from the default queue. The cuts are calibrated against the full production finding set and are configurable. A CVE known to be actively exploited is never hidden: a suppressed false positive costs an analyst nothing, while a suppressed known-exploited CVE is the one failure you cannot recover from. Version comparisons across incompatible numbering schemes, such as a Windows feature-release tag against a detailed build number, now decline to answer instead of returning a confident wrong answer.
- Microsoft 365 Secure Score in context: alongside the percentage, the platform now keeps the history, Microsoft's own comparatives (all tenants, comparable seat count, industry) and the per-control scores, including the maximum available, the remediation text and a deep link into the right admin blade. A bare 47% is unactionable; 47% against an industry average of 52% with 141 points still on the table is a conversation with a client. Recommendations are ranked by the points still available, which is effort-to-impact order. They are deliberately not labelled as a remediation action: Secuno holds read-only access to Microsoft 365, and a button promising to fix the tenant that in fact opens a documentation page is a promise the product cannot keep.
- Posture drift in Microsoft 365: findings answer what is wrong right now, drift answers what changed since the last scan. That is the question a managed provider is actually asked, and the one a point-in-time score cannot express, because a tenant can hold a flat Secure Score while an admin is added, a Conditional Access policy is switched off and a new OAuth grant appears. Coverage includes privileged accounts (including an admin losing MFA with the roster otherwise unchanged), Conditional Access, tenant-wide switches, MFA coverage, OAuth grants and Secure Score movement. Only regressions alert, one notification per scan rather than one per change, and a tenant that simply stays broken cannot re-notify. Every comparison is conditional on the underlying data having been readable in that run, so an expired permission is never read as every admin having been removed.
- Time-boxed finding exceptions: both an expiry and a reason are required. An exception with no expiry is a permanent mute, and one with no reason is unreviewable six months later. The dialog offers presets rather than an empty date field, so a review date is the default behaviour instead of something the analyst has to remember, and a lapsed exception quietly puts the finding back where it belongs. Also added: licence coverage per tenant, and a posture breakdown by domain so the page answers where to start rather than only how bad it is overall.
- Microsoft 365 scan coverage now says why, not just what: a scan reported which datasets were refused and never why. On a tenant below the premium identity plan that is a permanent, expected plan limit, not a fault the customer can fix. Per-dataset status, the underlying error and a classified reason are now recorded, both on the connection and per scan run, so it stays answerable when a dataset started failing. Plan limits no longer raise a standing amber banner on every tenant without a premium licence, because that trains people to ignore the banner that does matter.
- Investigations as a workable case: a per-step playbook checklist with a note recording what was actually carried out, replacing a read-only numbered list in which the next responder had no way to tell what had already been done. Findings and correlated change events are merged into one chronological attack chain instead of two disconnected lists describing the same actions. Response actions are now available from inside the case, deliberately limited to four verbs on this investigation's device and always mirrored into the activity trail, so an analyst watching files being encrypted does not have to leave the investigation to intervene.
- Investigations, continued: similar prior cases of the same signal type for this client and how they were resolved, previous and next navigation across open investigations for clearing a morning's queue, case metrics shown as durations rather than raw timestamps (time to acknowledge measures the first human touch, not the moment of detection), an observables panel that pulls indicators out of the evidence so nobody has to read a JSON blob to find a hash, preset dismissal reasons in place of a free-text box that in practice produced fp, test and blanks, and a printable case report that keeps the colour of severity labels.
- Agent management console: what was a single 1,400-line page is now a section with persistent navigation and its own pages for overview, deployment, enrollment tokens and the release manifest. The overview shows fleet counters, availability and the spread of agent versions.
- Device page: file drops now have their own tab where everything is retained. Previously the investigation was the storage, so the filter deciding which drops opened a case also decided what the platform remembered. Added alongside it is a patch status tab that joins Windows updates and third-party application updates server-side, fetching outstanding rows separately so a machine with a thousand applied updates cannot push its three failed ones out of view.
- Software inventory search: per-field filters (name, version) with an explicit AND/OR choice. AND narrows (Chrome, but only version 120), OR widens (anything called Chrome, plus anything on 120). Those are genuinely different questions once you are hunting a bad build across a fleet, so the choice belongs to the operator.
- Truncated lists now say so: several views carry a hard cap, but the cap was silent. At 501 devices the interface rendered 500 managed devices as if that were the answer. It now reads 500 of 12,431. A number that is quietly wrong is more damaging than a missing one, because it makes every other number on the page suspect once somebody spots it.
Improved
- Risk enrichment for findings with no CVE: agent-change, Microsoft 365 posture, custom-rule and manual risks are the majority of what an operator opens, and they were the only ones with no explanation at all, because enrichment required a CVE. They now get the same explanation through the same panel. Enrichment also ran only when a risk was created, so risks that already existed stayed blank permanently; those are now backfilled gradually.
- Role permissions in the interface come from one central definition rather than hundreds of hardcoded role checks spread across the codebase, where the same role name meant different things on different screens and several screens denied an administrator something they could do elsewhere. The definition is locked by tests, so a later edit that widens a role fails loudly instead of shipping quietly. It answers whether a role may do something at all; scoping to a specific client stays server-side, because anything the browser decides is advisory.
- Shared interface primitives and colour tokens: cards, stat strips and detail headers existed in more than a dozen slightly different variants. They are now shared components, the palette is reduced to five ramps with each step labelled for the duty it is allowed to do, and a contrast check runs as part of the build so an accessibility problem surfaces in CI rather than at a customer.
- Error handling that degrades instead of collapsing: individual panels now catch their own failures, so a broken panel falls back to a placeholder while the rest of the page stays usable. That is the difference between that panel is broken and the console is down. Error pages deliberately show nothing but a reference code: a stack trace from a security console can leak internal structure and the user cannot act on it, while the reference is exactly what support needs.
Fixed
- Device public IP address: every device record was storing an internal address instead of the device's real public address, and that field is what threat-intelligence IP matching reads. The address is now resolved in one place and an internal address is refused rather than written. See the Changed section: the poisoned values are cleared. The address remains informational, for display, geolocation and context, and is not used as a basis for access decisions.
- Availability: an unexpected failure inside rate limiting could terminate the backend process, and with it the service for every customer at once. The limit is now enforced by writing a response and returning, and unexpected failures are routed through normal error handling.
- Network isolation was a one-way latch: a host that was isolated and later released kept reporting itself as contained forever, which is a dangerous thing to tell someone responding to an incident. The status from the isolation record is now authoritative.
- Telemetry counters showed one cycle instead of a history: a device that fell back to a recovery path forty times in a day read as 1, and a problem from last week was indistinguishable from one happening now. Counters are now summed, with a start time and the moment they were last reported.
- Device risk counts disagreed with themselves: the per-device count and the open-risks stat card were computed independently and only the card filtered by status, so a device whose risks had all been mitigated still advertised 3 risks in red. Both now read one definition of open.
- The patch dashboard counted rows as devices: devices affected counted one row per missing patch per device, so a fleet of two machines reported 23 devices affected, which is exactly what the caption above it promises it is not. It is now distinct devices.
- The port half of the fleet baseline had never received a value, through the same field-name bug that affected the exposure weights. Loopback-bound listeners are additionally excluded: a service bound only to the machine itself is not a fleet-visible service and should not raise a rare-port deviation.
- Microsoft 365: a freshly granted permission was invisible for up to an hour. A token carries its granted rights fixed at the moment it is issued and was reused for a full hour, so Graph kept reporting the permission as missing after an administrator had correctly granted it, and re-running the scan did not help. The token is now dropped and re-acquired once as soon as Graph refuses access.
- Microsoft 365: a dataset we were not allowed to read was presented as a fact. MFA status and last sign-in were written unconditionally, so a missing permission was shown to the customer as an account that had never signed in. Only metrics whose source was readable are overwritten now.
- Microsoft 365: severity changes were reported on every single scan, because a finding's severity was compared against the linked risk's severity rather than against the finding's own previous severity.
- A model timeout was recorded as an analytical verdict: no answer and an empty answer were indistinguishable, so a CVE whose analysis never ran was permanently recorded as insufficient data, which is a conclusion for an analysis that never happened. The two cases are now separated, and a CVE whose analysis keeps failing moves to an explicit state after a bounded number of attempts rather than being retried forever or silently counted as analysed.
- The enrichment caller gave up before the work it had asked for finished: a slow but successful enrichment was discarded by its caller and re-done on every scoring run. The two timeouts are now aligned and documented as an ordering constraint.
- A fleet-wide rescore would have wiped every stored AI assessment, because the scoring write replaced the whole metadata column rather than merging into it. Harmless while scoring only ran at creation, but this release runs exactly that rescore.
- A downgrade applied by the correlation confidence gate was overwritten within milliseconds by re-deriving severity from the score. A finding the gate hides is not a severity judgement about the CVE but a statement that we do not believe the match, so it is now left alone.
- Severity label colours could render as invisible white text on no background, because the style generator was not scanning a directory holding lookup tables and a missing class fails silently.
Security
- Windows agent detection accuracy: a family of false positives around routine administration and maintenance has been fixed at the source rather than filtered downstream. Among them, legitimate 32-bit system binaries were being reported as masquerading, and a memory finding on an unchanged process was re-reported as a new finding on every cycle. Memory-scan findings are now reported on first sighting and on material change, and rest on stronger evidence with no reduction in coverage.
- An investigation that was opened on the number of signals rather than their severity could raise a high-severity case from correctly processed and correctly de-escalated alerts. The investigation's severity now follows the worst remaining alert.
Changed
- Open risk counts will drop. The CVE correlation confidence gate hides findings whose match confidence is too low from the default queue, and existing rows are included when you upgrade. The findings are not deleted and remain retrievable.
- The risk queue re-ranks wholesale. Custom-rule and Microsoft 365 posture risks receive a real score for the first time and move from 0.0 into the middle of their declared band, and every CVE-linked risk is re-scored against real reachability. A site with no declared network posture takes the default rather than the most permissive reading. Review the network posture on your sites after this release.
- Public IP and the associated geolocation data are cleared on devices where an internal address had been recorded. Those devices report a correct address on their next heartbeat.
- Fleet-wide AI reprocessing no longer runs during the day. It held a large share of the available compute around the clock and, because of how it was scheduled, never finished two thirds of its cycles. Anything relying on rules being produced within minutes will now wait for the overnight run.