Commit Graph

338 Commits

Author SHA1 Message Date
f3nris 90c6c80843 feat(harfanglab): instance-level tenant scope (1.8.0)
An instance can carry the tenant of the client it serves, for clients sharing
one multi-tenant manager. endpoint_count uses it, for the count and the fleet
total beside it, when the block leaves its tenant filter empty; a tenant named
on the block still wins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TgjV26rz6VcP262dX4vBrD
2026-10-19 19:23:40 +00:00
f3nris c67343b7cf feat(sentinelone): instance-level account scope (1.20.0)
An instance can carry the account IDs of the client it serves, for clients
sharing one multi-tenant console. count_agents, get_threats, get_alerts and
get_unified_alerts use them when the block leaves its account filter empty;
an account named on the block still wins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TgjV26rz6VcP262dX4vBrD
2026-10-19 19:08:10 +00:00
f3nris 2bc7601177 fix(mail-templates): callout_title points to the badge in the mail language (1.0.4)
Its description gave "⚠ SLA ALERT" as the default, which read as a
value to type: a French mail ended up with an English box title. It now
says to leave the field empty for the badge in the mail language.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJu1jvaug4qY1kMgz8wx41
2026-10-19 09:32:17 +00:00
f3nris 2a74bbc436 feat(mail-templates): markdown inputs in a multi-line field (1.0.3)
description and callout_text declare format: markdown, which Riposte
0.322+ edits in a text area that keeps line breaks; older versions
ignore it and \n still works. README documents format: multiline.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJu1jvaug4qY1kMgz8wx41
2026-10-19 09:17:27 +00:00
f3nris 983414f278 fix(mail-templates): read \n as a line break in one-line inputs (1.0.2)
The playbook editor's input field is a single <input>, which drops the
newlines of a pasted text: the whole description reached the script as
one line starting with ## and rendered as a single heading. description
and callout_text without a real line break now take the two characters
\n as one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJu1jvaug4qY1kMgz8wx41
2026-10-19 09:10:52 +00:00
f3nris 046810c1f6 fix(mail-templates): run under Riposte's exec() runner (1.0.1)
The runner execs a script without __file__ or __name__: the Test button
failed on __file__ and render-mail-template never reached main(). The
test no longer imports the renderer, and the renderer calls main()
unconditionally like the other integrations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJu1jvaug4qY1kMgz8wx41
2026-10-19 08:49:46 +00:00
f3nris dcf257d887 feat(mail-templates): render ACKnowledge SOC emails from markdown (1.0.0)
render-mail-template turns a template, a subject and a markdown
description into the dark ACKnowledge SOC mail (header badge, optional
callout and action button, signature with the logo, SOC or client
footer, fr/en). Nothing is sent: subject, html_body and text_body go to
exchange-send-mail or mail-sender, which embed the data-URI logo.

Eight templates (sla_breach, incident_notification, incident_update,
incident_closure, action_required, escalation, threat_bulletin, info).
The markdown covers GFM tables, code blocks and {{level}} pills; raw
HTML in the inputs is escaped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJu1jvaug4qY1kMgz8wx41
2026-10-19 08:40:32 +00:00
f3nris 5085d96628 feat(webhook-relay): map Rapid7 InsightIDR basic rule alerts (1.1.0)
fetch_rapid7_alerts opens the alert InsightIDR Essential posts as a JSON
string in a single payload field (JSON or form body) and returns one flat
item per relayed message; the correlation id is the dedup key. Own mapper
and alert type, written from a real delivery.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xa1QDbsPTYiVREv2Cvs3Zn
2026-10-19 07:56:45 +00:00
f3nris c358814fe7 feat(microsoft-exchange-mail): send mail from Exchange Online over Graph (1.0.0)
Mail Sender speaks SMTP and Defender for Office 365 only reads and
purges, so nothing in the catalogue could send from an Exchange Online
mailbox with an app registration (tenant ID, client ID, client secret).

send_mail posts to /users/{mailbox}/sendMail: text or HTML, inline
data-URI images as cid attachments, CC/BCC, Reply-To, importance and
saveToSentItems. Over 3 MB of attachments the message goes through a
draft and upload sessions instead, since sendMail caps the request at
4 MB; that path needs Mail.ReadWrite. reply_mail and forward_mail take
the Graph id or the internet Message-ID (resolved with a $filter, which
needs Mail.ReadBasic.All). test_connection reads the token's roles and
fails when Mail.Send is missing, without sending anything.

Exercised against a stubbed Graph: request bodies, the draft path with a
7 MB file in three ranges and no bearer on the upload URL, and Riposte's
ParseManifest. Not yet tried against a real tenant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 03:29:32 +00:00
f3nris 815db080f5 feat(webhook-relay): map relayed messages into OCSF, not only custom fields (1.0.1)
The generic mapper now fills the OCSF fields a relayed message has a
place for: metadata.logged_time, log_provider and log_name, the checks
the delivery passed as metadata.labels (relay:hmac…), and raw_data. The
sender's address goes to unmapped.relay.sender_ip rather than
src_endpoint.ip: it is the vendor's cloud, and as an entity it would
correlate every alert of that vendor. metadata.product.name no longer
holds the source id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xa1QDbsPTYiVREv2Cvs3Zn
2026-10-16 15:48:27 +00:00
f3nris 6b76270cc6 feat(webhook-relay): read the alerts vendors push to riposte-relay (1.0.0)
Riposte accepts no inbound connection, so a vendor that can only push
(Rapid7 InsightIDR Essential basic detection rules) posts to the relay,
and an alert rule on this integration reads one relay source back over
outbound HTTPS.

fetch_messages takes the rule's watermark as `since` and walks every
page within the run, since the next watermark is this run's instant. A
window holding more than `limit` fails the run instead of truncating, so
the watermark stays put. relay_status and test_connection tell a 404
from the proxy (this Riposte's address is not listed) from a refused
token. The generic mapper keeps the raw body, the sender's address and
the checks the delivery passed (custom:webhook_verified).

Tested against a local relay: 2503 messages over three pages, a
millisecond watermark, the limit, unknown source and bad token.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xa1QDbsPTYiVREv2Cvs3Zn
2026-10-16 11:23:03 +00:00
f3nris ff461464fd fix(crowdstrike): resolve_detection fails when Falcon changed nothing (1.6.3)
The alerts PATCH answers 200 to a refused update (errors, resources_affected
0) and the command reported it as a success. It now exits in error with
Falcon's reasons and the ids sent; an empty update is refused up front.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VBnLYwQbUCaf5vpv77N14Q
2026-10-15 12:08:05 +00:00
f3nris 88407dd1b4 feat(sekoia-xdr): list_alerts attaches each alert's events (1.3.0)
An alert only summarises its detection; addresses, user, process and
command line live in the events tagged with its short id. with_events
runs one event search per alert (alert_short_ids, first_seen_at - 1 min
to now, as Sekoia's XSOAR integration does), in parallel within the
60 s command budget, and nests the dotted ECS names. A search not done
in time leaves events_pending + events_job_uuid: the alert still goes
out, as the rule's watermark would not offer it again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VBnLYwQbUCaf5vpv77N14Q
2026-10-15 10:10:56 +00:00
f3nris 8eed7ed9fb fix(crowdstrike): NG-SIEM detections are filed under thirdparty (1.6.2)
On a real tenant the Unified Detections raised from ingested FortiGate
logs are product 'thirdparty'; 'ngsiem' matched nothing. The command now
reads thirdparty and ngsiem by default (products input), and its mapper
is rewritten from real payloads: source product/vendor, matched host,
connection endpoints and ports, vendor signature id, Falcon priority,
console link, and a description built from what fired on which connection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VBnLYwQbUCaf5vpv77N14Q
2026-10-15 08:32:36 +00:00
f3nris f34c87f0c8 fix(crowdstrike): say what an empty alert search matched (1.6.1)
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>
2026-10-15 08:09:39 +00:00
f3nris 0444e120fa feat(crowdstrike): search Next-Gen SIEM detections (1.6.0)
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>
2026-10-15 07:53:05 +00:00
f3nris 585c06385c fix(harfanglab): retry transient API errors (1.7.3)
HarfangLab answers a 500 now and then on a call that passes when sent
again. Each script's request() now retries up to three times (1, 2, 4 s):
GET on 429/500/502/503/504, writes only on 429/502/503 so an isolation,
a kill or a job is never sent twice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 07:28:03 +00:00
f3nris 725e6921f4 feat(jira): watch_issues reports what changed on a set of tickets (1.4.0)
Given up to 50 keys and an instant, returns the issues updated since with
their status, new comments (author id, plain-text body, own comments
flagged) and status transitions, plus the instance's own account. JQL dates
are converted to the account's time zone; malformed keys are never queried;
a deleted key falls back to per-key reads instead of failing the batch.

get_comments gains order, start_at and author_id, and decodes HTML entities.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 15:59:42 +00:00
f3nris e973ccb673 feat(cortex-xdr): endpoint_count counts agents below a target build (1.10.0)
agent_version_lt, compared number by number in the script, as the
endpoints API does not filter on the agent version either. Folded into
the unpushed 1.10.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LaiNEwG2W5Y9fMo4qXcesr
2026-10-13 08:49:29 +00:00
f3nris 62157e5dee feat(cortex-xdr): endpoint_count counts by operational status (1.10.0)
The endpoints API has no filter on operational_status, so the endpoints
the other filters match are read 100 at a time and counted by the script.
Lets an agent reporting playbook count the agents in error, as
SentinelOne's operationalStatesNin does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LaiNEwG2W5Y9fMo4qXcesr
2026-10-13 08:43:18 +00:00
Claude 91855fce4f fix(sentinelone): count the host's other alerts from what was read (1.19.1)
A real run answered one other alert and named none: the count came
from the console's total minus the alert itself, and that total did
not hold the alert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-12 11:37:19 +00:00
Claude 6f51520fb5 feat(sentinelone): investigate_alert, one call for an agent (1.19.0)
Wraith spent ten calls on a real unified alert and still lost the host:
it took the UAM asset id for an agent id and the raw agent list ran past
what a tool result carries. investigate_alert reads the alert, its
detail, the host's agent (by id or UUID, then name), the other alerts
and threats on that host around the detection, and the file SHA1's
reputation, blocklist and fleet-wide threats, summarised in one answer.
The operator sheet now starts with it (budget 8).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-12 11:27:36 +00:00
f3nris 80de5399a6 rapid7-insightidr 1.14.9: a user_authentications answer that fits
Riposte gives a tool result 8000 characters; two full summaries ran to 11903
and were cut at 3903, the asset list half gone. The answer now keeps only the
fields an authentication question is answered from (destination and source
asset and address, domain, result, logon type, service) and lists up to 40
new destination assets in full: about 2.5 KB for 1000 events.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-12 08:14:10 +00:00
f3nris fb560cc937 rapid7-insightidr 1.14.8: user_authentications counts the user's own logons
The keyword search matches the account name anywhere in a line, so it brought
other accounts' logons: on a real run the only "new" event reported was
another user's failed password. Only events whose account/user field is the
user (DOMAIN\\user and user@domain normalized) are summarized now, with
keyword_matches and user_matches both reported. A first authentication is
recognized as Rapid7 flags it, a boolean new_authentication field, as well as
the word. The event limit cannot be set below 10000 (the agent passed 1000).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-12 07:53:57 +00:00
f3nris 3bfcebdf21 rapid7-insightidr 1.14.7: user_authentications, one call for a UBA alert
A new read command answers what a behaviour authentication alert asks —
which assets the user authenticated to around the alert, and which were new —
in one call: it resolves the Asset Authentication log set, builds the
keyword query and the 24 h window itself, and summarizes all events and,
apart, those marked new_authentication. Across real runs gpt-oss mangled log
set ids, computed the window a day off, put a filter inside the LEQL (HTTP
400) and read ten lines out of a thousand; this leaves it nothing to get
wrong. Static calls it first for such alerts; list_investigation_alerts
points to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-12 07:45:31 +00:00
f3nris ae1effafcd rapid7-insightidr 1.14.6: narrow a log result by field, no query syntax
query_log_set takes only="field=value[, …]", applied to the events' fields
after the search (case ignored), and says how many matched before it. Static
runs a second summary of the same query restricted to what the alert is about
— for a "new assets" alert, the new authentications — and names their
destination assets: the first real run summarized 978 events but left the 64
new ones mixed in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-12 07:27:36 +00:00
f3nris 889cf660f6 rapid7-insightidr 1.14.5: query_log_set can summarize; Static always does
summarize=true returns, over every matching event, each field's most frequent
values with counts, the first and last event time and five samples, instead of
the raw events. On a real run Static got 1000 raw events, could read about
ten, and reported the hosts and accounts of those ten; 300 events now fit in
about 1.5 KB. Static passes summarize always and quotes the returned window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-12 07:18:09 +00:00
f3nris 847f31ce17 zscaler 1.1.2: withdraw the Relay operator
It could only read a sandbox report by MD5 — no web logs — so it added noise to
the crew lead's routing without answering an investigation question. Riposte
retires the installed agent on the next update of the integration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-12 07:12:54 +00:00
f3nris 3e39f17bfe rapid7-insightidr 1.14.4: keep UBA alerts in the full investigation feed
get_investigations_full dropped every alert without an RRN, so a behaviour
(UBA) investigation arrived with alerts: [] and alert_count: 0 and its
reading worked from a title alone. Those alerts are now kept under
alerts_without_rrn as the investigation endpoint returns them, counted in
alert_count, rendered in summary_markdown with where their evidence lives,
and lift first_alert_type / first_alert_source / first_alert_id when they are
all the investigation has.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-12 07:02:12 +00:00
f3nris 9605e1f0dc feat(agents): operator sheets for 33 integrations (lot 4)
EDR: Wraith (SentinelOne), Talon (CrowdStrike), Nyx (HarfangLab), Bastion
(Defender), Synapse (Cortex XDR), Kestrel (Sophos). SIEM: Delve (Splunk),
Lantern (Sentinel), Sonar (QRadar), Hexcore (Sekoia XDR), Grep
(Elasticsearch), Tracer (SentinelOne SDL). Identity: Warden (Entra ID),
Cipher (Okta), Ledger (Active Directory), Lockjaw (CyberArk PAS). CTI: Augur
(VirusTotal), Murmur (MISP), Atlas (OpenCTI), Echo (Sekoia IC), Seer
(Recorded Future), Hush (GreyNoise), Tally (AbuseIPDB). Sandbox: Scalpel (Joe),
Gauntlet (ANY.RUN), Prism (VMRay). Email: Hook (Proofpoint TAP), Drift
(Mimecast), Riptide (Vade). Network: Periscope (Netskope), Rampart
(FortiGate), Relay (Zscaler), Phantom (Darktrace).

Read-only commands, analyst_l2, a call budget with an order, and the Static
lessons: ids copied from answers only, timestamps passed as given, names over
ids, one variant at most on error. Each sheet passes Riposte's validator;
none is field-tested yet. Each integration gets a patch bump.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-11 23:00:15 +00:00
f3nris 2245d5500e rapid7-insightidr 1.14.3: the log window is computed from the alert's time
query_log_set takes anchor_time with hours_before / minutes_after and computes
the window itself, and returns it as text: on a real run the agent computed
"24 hours before 2026-10-11T00:04Z" as ending on the 10th and reported a
day-old window. Static passes the alert's first seen time instead of dates,
and lists domain controllers apart from the new assets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-11 22:38:42 +00:00
f3nris 4bd468e671 rapid7-insightidr 1.14.2: query a log set by name; Static widens UBA windows
query_log_set accepts log_set_name and resolves the id itself (exact name, or
the one set whose name contains it; otherwise refused with the existing
names): on a real run the model mangled a 36-character id it copied. Static
queries by name, retries a 0-event keyword search case-insensitively, takes
the 24 hours before a behaviour alert (they aggregate hours of activity), and
always looks for the user's other investigations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-11 22:32:22 +00:00
f3nris c3b15d1faf rapid7-insightidr 1.14.1: mark UBA alerts in the data, give Static a budget
list_investigation_alerts now marks each alert with alert_rrn, evidence_api
and next: a behaviour alert with no RRN says, in the output the agent reads,
that the Alert Triage commands answer 404 for it and that its evidence is in
the authentication logs. Static still called them when only its instructions
said so. Its sheet gets 14 calls spent in a stated order, authentication log
sets for lateral-movement alerts (never file access), and a window built from
first and last seen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-11 22:20:58 +00:00
f3nris c5da537434 rapid7-insightidr 1.14.0: ship Static, the InsightIDR operator agent
agents/operator.yaml: read-only commands, analyst_l2 ceiling, and the procedure
learned on a real UBA alert (start from the investigation's alerts, plain-UUID
alerts have no Alert Triage evidence, LEQL keyword search in parentheses,
search_investigation takes start_time/end_time). README documents agents/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RhL2gy6Sx6Y3FEsyBE3mZ
2026-10-11 21:07:52 +00:00
f3nris 4a339fda24 rapid7-insightidr 1.13.2: trim pasted log and log set IDs, explain the 404
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012bH7kirDAfMjDLj8AYRrNU
2026-10-11 15:37:49 +00:00
f3nris b9e796e927 rapid7-insightidr 1.13.1: accept an InsightIDR Essential key in test_connection
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:13:22 +00:00
f3nris 856dd2321d feat(crtsh): Cert Spotter fallback and a 60 s time budget (1.1.0)
crt.sh often answers 502 for minutes at a time. When it is down,
sub-domain and exact searches are now answered by SSLMate Cert Spotter,
which reads the same CT logs; its rows are reshaped into crt.sh's so the
output keeps its shape, plus 'source' and 'complete'. starts_with has no
fallback (Cert Spotter cannot search by prefix).

Riposte kills an integration script at 60 s, and the old retry loop
(4 x 120 s) could never finish. Every call now takes its timeout from a
55 s budget, with 15 s kept for the fallback; only 5xx are retried.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmWT9wtWHGtZpMS64Hp4q5
2026-10-10 21:12:15 +00:00
f3nris 94142f4739 docs(ioc-sources): suggest summary lines for Riposte context enrichment rules
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmWT9wtWHGtZpMS64Hp4q5
2026-10-09 22:53:04 +00:00
f3nris d2742ec6fb feat: CIRCL hashlookup, RDAP and crt.sh — free IOC lookups, no API key
Three keyless sources for the questions an analyst asks first:

- circl-hashlookup 1.0.0: is this hash known software (NSRL, distro
  packages, Windows updates)? `score` 0 for a known file, 100 when CIRCL
  flags it KnownMalicious, so an enrichment rule with benign 0 marks it
  benign; an unknown hash is an HTTP 404, read as "no record". Single and
  bulk lookups; base_url for a self-hosted instance.
- rdap 1.0.0: who registered a domain, IP block or AS, and when — with
  age_days for the phishing question. Authoritative server from the IANA
  bootstrap, rdap.org as fallback; a host name walks up to its registered
  domain; GDPR placeholders are not reported as registrants; a TLD with no
  RDAP (.ch) is an error, not a fake "unregistered".
- crtsh 1.0.0: Certificate Transparency — sub-domains with first/last seen,
  issuers, recent certificates, and a starts_with mode for look-alikes of a
  brand (crt.sh no longer searches with a leading wildcard). Retries the
  502/503/504 its shared front throws under load.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AmWT9wtWHGtZpMS64Hp4q5
2026-10-09 22:33:42 +00:00
f3nris 5cf870309f feat(harfanglab): describe an incident with the rule's message (1.7.1)
The get_security_events and get_alerts mappers set an incident's
description to alert_type alone — "sigma", "yara" — which says nothing
an analyst can act on. It now takes msg, the rule's own account of what
it detects and what to check, and falls back to the alert type only on
alerts that carry no message. Folded into the unreleased 1.7.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXFMuDDLohs4qnL12mBJoP
2026-10-07 19:11:35 +00:00
f3nris 45df291eeb fix(harfanglab): drop the 50 KB filters catalogue from list outputs (1.7.1)
HarfangLab's alert and threat list endpoints echo, on every call, the
catalogue of every filterable field — about 50 KB, unrelated to the
results. get_security_events, get_alerts and get_threats now drop it
before printing, so a fetch carries the alerts and little else.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXFMuDDLohs4qnL12mBJoP
2026-10-07 12:42:32 +00:00
f3nris db9a45c9bc docs(mappers): MTTD is not retired, only re-anchored
The previous commit said MTTD was retired. Migration 0256 did retire it,
but 0257 restored it at once: what stays is its anchor, the moment
Riposte records the alert. The OCSF `time` field is still not read to
date detection — that part was right.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 09:58:20 +00:00
f3nris ece2c41340 docs(mappers): time no longer dates detection
Eight mappers (Cortex XDR, CrowdStrike, Rapid7) still called the OCSF
`time` field "the MTTD anchor" that Riposte reads to stamp detected_at.
Riposte retired MTTD in migration 0256 and stamps detection at
ingestion for every alert; the mappings stay, as the alert's own record
of when the source saw the event. Comments only: no mapping changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 09:56:50 +00:00
f3nris ea04ea586c fix(sekoia-xdr): mapper reviewed on a real alert (1.2.0)
- incident source is 'Sekoia XDR'; Sekoia's `source` (the alert's source
  address) goes to src_endpoint.ip/.hostname, `target` to dst_endpoint;
- description: the alert's sentence with {rule:<uuid>} replaced by the rule
  name; the rule documentation (`details`) moves to analytic.desc;
- every TTP mapped into attacks; kill_chain_short_id no longer written as
  an ATT&CK tactic uid;
- OCSF times in epoch ms; finding_info.types, analytic.category,
  metadata.product added.

Checked with Riposte's mapper preview on the alert and a variant (IPv4
source, named target, one TTP): no expression error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 09:13:03 +00:00
f3nris d831d0973a feat(harfanglab): fetch a threat's security events (1.7.0)
Since HarfangLab merged alerts and security events, a threat's events
are the alerts whose threat_key is the threat id — the filter the
vendor's XSOAR integration uses. get_alerts could filter on it but
stops at one page of 100; the new threat_security_events command pages
through up to max_results and returns the threat's total with a
truncated flag.

threat_status, threat_level and alert_tag offer their status and level
as drop-downs, and threat_status now reads as the place to close a
threat or mark it a false positive, HarfangLab's only verdict.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 07:35:31 +00:00
f3nris 91f6b8158b fix(cortex-xdr): give a full incident its own title (1.9.0)
Title and description both read the incident's description, so every
ticket showed the same sentence twice. The title is now the rule that
fired, with "(+N other alerts)" when several are folded in, or the
incident's console name; the description adds what each distinct rule
means.

network_artifacts[0] no longer overwrites the alert's own flow: the
artifacts are the fallback, and the destination country comes from the
artifact matching the alert's remote IP. Also maps the rule description
and id, and the XDR assignee.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 14:25:32 +00:00
f3nris 0f5f4a900e feat(crowdstrike): set a detection's verdict (1.5.0)
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
2026-10-02 14:25:22 +00:00
f3nris 820bab8e5c feat(jira): pick the project, issue type and priority from the site (1.3.0)
create_issue and edit_issue declare options_from on project_key,
issue_type_name and priority, and link_issues on link_type, so the
playbook editor lists the Jira site's own values. Three read commands
feed them: list_projects, list_issue_types (per project) and
list_priorities. The README documents enum and options_from.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WhDQSYZd1mFtRsXK4ixtyB
2026-10-02 10:16:41 +00:00
f3nris 41aa6723c5 feat(cortex-xdr): list the incident statuses and severities as enums (1.8.0)
cortex-xdr-update-incident declares the API's nine status values and
the four severities, so the playbook editor offers them in a drop-down
and the command bar refuses a misspelt one. resolved_other joins the
list; resolved_auto leaves it, Cortex XDR setting it itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WhDQSYZd1mFtRsXK4ixtyB
2026-10-02 07:50:12 +00:00
f3nris 89ffbc3c7c feat(sentinelone): list the UAM alert statuses as an enum (1.18.0)
sentinelone-update-uam-alert-status declares NEW, IN_PROGRESS and
RESOLVED, folded into the unreleased 1.18.0, whose changelog entry
the previous commit left out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Azv82i33uiPff2PFj2PLi7
2026-10-01 20:26:45 +00:00