search_detections and search_ngsiem_detections now return a query block
(FQL sent, Falcon's total, errors) next to resources, so an empty run can
be told apart from a wrong region or an API client that sees no alerts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NG-SIEM correlation rules file their detections in the unified Alerts
API under product 'ngsiem'. search_detections defaults to epp/ldt and
maps device/process/file blocks those detections do not carry.
New search_ngsiem_detections command (product clause always kept, filter
ANDed, created_from watermark), its own first-cut mapper on the fields
every unified alert carries, and a CrowdStrike NG-SIEM Detection type.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Falcon records a verdict as a tag — true_positive, false_positive or
ignored, which the console's Resolution column reads — and update_status
only takes new, in_progress, reopened and closed, so resolve_detection
had no way to record one. Its new verdict input adds the tag after
removing the other two, add_tag never replacing one; status and verdict
are drop-downs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WhDQSYZd1mFtRsXK4ixtyB
The device query already answers with meta.pagination.total — the number
of devices matching the filter, independent of the page asked for — so
device_count asks for a one-ID page and reads it, where search-device
resolves every matching device in full through
/devices/entities/devices/v2 to reach the same figure, and only filters
on four properties.
Filters cover sixteen device FQL properties (hostname, device id, local
and external IP, platform, OS version, role, containment status, sensor
version, AD domain/OU/site, serial, tags, host groups, RFM), add
first_seen/last_seen bounds, and keep a raw FQL escape hatch.
Two details the reference client leaves to chance are handled here.
Several values on one property become an OR group, parenthesised so it
binds before the '+' that ANDs it to the other clauses. And values are
quoted with the single quote escaped, so a hostname carrying an
apostrophe cannot end the literal early and change what is counted.
devices/v1 stops reporting a total on an estate it cannot page to the
end of, so a missing total falls back to the scroll query, which has no
such ceiling.
The estate `total` comes back next to `count` so the figure reads as a
proportion, and a filter too broad to mean anything shows as matching
everything rather than passing for an answer.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
search_detections had one input for everything, `filter`, so an alert rule
configured for incremental fetch had nowhere to put its watermark but
there — where it REPLACED the FQL with a bare timestamp instead of
narrowing it. The API rejects that outright (HTTP 400, "invalid query
filter in request"), and even had it not, the product/type scoping would
have been silently discarded with it. The only working configuration left
was a full fetch on every run.
created_from is that missing input, following the shape get_alerts already
uses on sentinelone: a timestamp of its own, declared as the command's
incremental_field so the alert-rule editor offers it. The script folds it
into the FQL as created_timestamp, which is where this API expresses a time
bound. filter now carries the scoping only — the two no longer compete.
Surrounding quotes on the value are stripped: FQL wants them, and an
operator filling the first-fetch date by hand may reasonably include them.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two silent defects in the search_detections OCSF mapper.
Severity was a four-branch ternary that resolved to nothing, so every
ingested alert kept the alert rule's default severity instead of Falcon's
— a Low arrived as Medium and a Critical arrived as Medium too. It is now
a plain path to severity_name, whose words the ingestion engine reads
natively. (The ternary form is also repaired upstream, but a plain path is
simpler to read and to correct.)
No entry fed the OCSF `time` field, which is the only field the engine
reads to stamp detected_at. Incidents were anchored at ingestion instead
of at detection, so MTTD measured the collection delay as zero — over a
day on a slow poll. finding_info.created_time carries the same instant but
is read by nothing.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
cortex-xdr, crowdstrike, harfanglab and splunk now ship an `ingestion` block
(fetch command + bundled mapper + default incident type) and a bundled default
incident type under incident-types/, so the instance Collect section is pre-filled
on first configuration and the default type is created on install.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>