feat(rapid7-insightidr): evidence rows for the table field (v1.11.0)

The Markdown summary reads as a page. It cannot be sorted or filtered, and an
investigation aggregating several alerts, each with several evidences, is
exactly where those are wanted: "Multiple User Accounts Were Disabled" is a
question about which accounts, and the answer is a column.

So one row per evidence, across every alert, into custom:rapid7_evidence. The
table field reads an array of objects as it stands, so nothing is reshaped on
the mapper side. It sits beside the summary rather than replacing it — one is
read, the other is queried.

Two decisions worth stating.

Each row carries its alert's name first. An investigation aggregates several,
and a row that does not say where it came from cannot be acted on.

Column order is load-bearing, because it is the only ordering signal the field
has: it takes the union of keys in order of first appearance, so whatever the
first row names first is what an analyst sees without scrolling. Known keys
lead — action, result, the source and target pairs, the host, the addresses —
and the rest follow alphabetically.

Width is capped at 30 columns, decided by how many rows carry each key rather
than by which appeared first: an investigation mixing rule types has a sparse
union, and a column present on one row out of eighty would otherwise push out
one present on all of them. Exercised on a 187-column case — the five keys
common to every row all survived, and the count is reported as
evidence_columns_dropped rather than the loss being silent.

Verified against the account-disabled investigation: two evidences become two
rows of twenty columns, `alert` first, the two disabled accounts in
target_account — checked through the table field's own reader, not just the
generator.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-09 11:57:10 +02:00
parent b26257aaeb
commit 9081bc66fa
3 changed files with 81 additions and 2 deletions
@@ -44,6 +44,11 @@ field_mappings:
# what no OCSF mapping can, because the layout's field picker only offers paths
# from the OCSF catalogue and this vocabulary is open-ended.
"custom:rapid7_summary": "summary_markdown"
# One row per evidence, across every alert. Declare a custom field named
# rapid7_evidence of type table: it reads an array of objects as it stands, so
# nothing is reshaped here. It sits beside the Markdown summary rather than
# replacing it — the summary reads as a page, this one sorts and filters.
"custom:rapid7_evidence": "evidence_rows"
ocsf:
# ── Finding: the investigation ────────────────────────────────────
- { source_path: "rrn", ocsf_field: "finding_info.uid" }