fd4b1b18f7
The package could already write to a unified alert — update its status and its analyst verdict — but never read one. The only fetch was get_alerts, which reads /cloud-detection/alerts: a different object, covering only the detections the STAR and custom rules raise. Everything SentinelOne surfaces through the console-wide alert model — cloud, identity, third-party — had no way into an incident. get_unified_alerts reads the unifiedalerts GraphQL endpoint, alongside the two mutations already pointed at it. Notes on the shape it returns: - edges/node is flattened to a plain data[]. The envelope carries no id of its own, so a rule dedup'ing on a top-level id would key every alert on nothing; flattened, the ingest block matches the REST commands in this package (results_path: data, dedup_key: id). - Sorted ascending, so a run truncated by the limit leaves the watermark on the oldest unseen alert instead of skipping everything behind the newest. - created_after is normalised from ISO8601, epoch seconds or epoch milliseconds: the scheduler injects the watermark raw, in whichever of the three formats the rule was configured with. The script builds the GraphQL filter itself, so the incremental input stays a plain timestamp. - A GraphQL error arrives as HTTP 200 with an errors array. Left unread, an unusable query would look like an endless run of empty, successful fetches. The mapper covers 74 fields. Its severity branch ends on the raw value rather than a number, so an alert with no severity — or a level SentinelOne adds later — falls through to the rule's default instead of being asserted Informational on data that never said so. A UAM alert also carries fields with no honest OCSF home (assignee, ticketId, the kubernetes controllers); they are fetched and left in the raw payload rather than forced into an unrelated field. The package default ingestion still points at get_threats: the new command is opt-in from the Collect editor, so no existing instance changes what it collects. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>