Repository navigation
AiSOC v22.2.0 — eight connectors were silently losing data, and one of them had never ingested a single event #1728
beenuar
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
AiSOC v22.2.0 is out. This one is about collection integrity: eight connectors were losing data on every deployment, silently, and a single shape explains all of them. If you run Microsoft Entra, Defender, Sentinel, Google Workspace, Google Cloud Audit, Security Command Center or Wiz, this release changes what reaches your queue.
ghcr.io/beenuar/aisoc-*:v22.2.0— all 16,linux/amd64+linux/arm64oci://ghcr.io/beenuar/charts/aisocat7.17.0The one thing worth understanding
A connector builds its poll window from the clock —
[now - interval, now]— so consecutive windows abut exactly. That is efficient, and it has a consequence that is easy to miss: nothing is ever re-read. Whatever a vendor does not hand over on the first attempt is gone permanently. Checkpointing cannot save it, because a checkpoint de-duplicates rows the vendor already returned and never widens a later request.Three different things break that window, and they need three different fixes:
Truncation. The vendor caps a page and offers a continuation nobody follows. Entra directory audits and risky sign-ins, Defender, Sentinel, Google Cloud Audit, Security Command Center, Workspace and Wiz all read the first page and stopped. Several of those queries are ordered newest-first, so what truncation discarded was the beginning of whatever burst overflowed the window — the part an investigation actually needs.
Availability delay. Google withholds a Reports API log event until it has published it, and documents that lag per application across three orders of magnitude. Admin and Login events are "a couple of minutes"; Token events are "a couple of hours" — roughly twenty-four times the 300-second default interval. No poll ever overlapped the published part of that timeline, so Google Workspace OAuth token grants and revocations had never once been ingested, on any deployment. Not a fraction of that feed: all of it.
A read that did not finish, reported as a quiet estate. Cloud Logging returns a
nextPageTokenwith an empty page to mean "still searching". A connector that stopped at the first empty response returned zero events from a window that was full of them.Every window now ends where the vendor has actually published, and continuations go through one shared helper with three properties that are each a defect somebody has shipped: a partial read is kept rather than discarded when a later page fails, a page cap is announced when it binds instead of silently cutting the result, and the continuation link is requested verbatim — Microsoft Graph states outright that a
$skiptokenmust not be extracted and reused.It is a CI gate now, not a review question. Six of these shipped inside two days, which is the point at which a pattern stops being individual mistakes. Every connector that issues an HTTP request must either follow a continuation or carry a written reason citing what the vendor's own documentation says it returns. There is deliberately no silent third state: "I could not find a page cap" and "this vendor returns the whole window" are different statements and only the second is a reason. 58 connectors still carry neither, each named in the gate's output on every run — and a change that cites the vendor contract for any one of them is exactly the contribution we are looking for.
Entra alerts were naming the wrong person
When somebody acts through a Microsoft first-party client, Graph puts the client in
initiatedBy.user.displayName. So an "Add member to group" alert readaffected_users: ["Microsoft Teams Services"]and named neither the member added nor the group, and a device update carried no host at all. Six causes across four layers, where fixing any one of them reaches nothing — the promoter builds an alert's user from the OCSF actor and its host from the device, so a target sitting anywhere else reached no column, no entity and no correlation key.Alerts now carry the user, group or device that changed alongside the actor that changed it, and a device change correlates per device rather than collapsing every device event in the tenant onto the client that performed them. Thanks to @gdncomm-dika-wibowo for the report, which included the measured shape of ten real alerts.
Fusion recovers from a lost broker on its own
Reporting a failure and healing from it are separate properties, and only the first was in place.
/readyzhas answered 503 naming the detached subscription for a while; what was missing was the coming back. The worker now supervises itself — and the interesting part is what it doesn't retry. A transient fault backs off and recovers. A permanent one — a refused credential, a missing ACL, an unsupported SASL mechanism — stops and names the operator action, because a loop retrying a misconfiguration every 60 seconds turns it into churn that reads as ordinary noise. A healthy worker is untouched: it attaches, builds exactly one consumer, and is never restarted.Thanks to @alexmateescu for the analysis and the original patch.
Two gates told the truth about themselves
Both of these were green and both were wrong about what they had checked, which is the failure mode the gates exist to catch.
The cancelled-run gate printed a five-week graded window on a fetch that reaches 8.8 hours — coverage overstated by about 100x. It was going green by forgetting: a cancelled run ages out of reach within a day, so the gate reported clean because the evidence had scrolled past. It now derives the window from the oldest run it actually fetched and prints the horizon every run.
The grading-integrity job's 15-minute timeout sat about 3% above its own measured worst case. That matters more than it sounds, because GitHub reports a job killed by
timeout-minutesascancelledrather thanfailed— so the gate beside it then correctly reported a commit that nothing had graded. The budget is now derived from 31 measured runs, and rate limits are waited out within a bounded budget instead of failing the board.Also: the Agentmetry connector page said its live leg was "not verified" after @blitzcrieg1, Agentmetry's maintainer, had actually verified it. It now records that run with its date, versions and result — and says plainly that no CI job repeats it. The claim-matrix row stayed
GATEDrather than being promoted, because a human running something once is not a gate.By the numbers
9 defects fixed in v22.2.0, and 40 across the last three releases — 9 here, 16 in v22.1.0, 15 in v22.0.0, counting distinct product or CI defects named in each release's Fixed and Security sections, with dependency-version advisories excluded.
Re-derived from the tree for this release rather than quoted from memory: 91 connectors, 2,966 executable detection rules of 7,407 on disk plus 76 windowed, and a claim-to-gate matrix at 400 rows — 391 GATED, 9 PARTIAL, 0 NO GATE. Those detection figures are three different measurements and every surface now says which one it renders.
Upgrading
No breaking changes. Both
stablechannels advance with this release — v22.2.0 shares v22.1.0's major, so no guard is crossed and nothing needs a manual promotion.One thing to know if you run the affected connectors: the windows that were missed are gone and cannot be backfilled — the vendor APIs are queried by time range, and those ranges were read once. Collection is correct from the upgrade forward. If you have an investigation that depended on Google Workspace token events, or on the earliest events of a burst in Entra, Defender or Sentinel, treat the historical record as incomplete rather than empty.
The five advisories published against v22.1.0 are unchanged and still name
22.1.0as patched, which is accurate — those fixes shipped there.Full notes: CHANGELOG · Architecture · Technical Guide (PDF)
All reactions