Skip to content

fix: resolve case alert attachments via ids-query search (rolled-over alias) - #56

Merged
davethegut merged 1 commit into
mainfrom
fix/case-alerts-rollover-alias
Jul 8, 2026
Merged

fix: resolve case alert attachments via ids-query search (rolled-over alias)#56
davethegut merged 1 commit into
mainfrom
fix/case-alerts-rollover-alias

Conversation

@maxcold

@maxcold maxcold commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes #55. On any cluster whose security alerts index has rolled over (which ILM does on every long-lived cluster), three case flows degraded silently:

  1. Case detail → Attached alerts rendered every alert as Unknown rule / Low
  2. create-case with alertIds / approve-discoveries reported success but attached 0 alerts
  3. Users then attached alerts from Kibana instead — and those also rendered unresolved

Root cause: attachment enrichment used GET /{index}/_doc/{id} and the attach lookup used _mget against the .alerts-security.alerts-default alias. Both are single-index operations, so once the alias points at 2+ backing indices ES rejects every call with alias [...] has more than one index associated with it, can't execute a single index op — and both call sites swallowed the error.

Fix: replace both with a single _search + ids query (searchAlertsByIds) over the attachments' recorded indices. A search fans out across all backing indices, accepts alias and concrete index names alike, and batches up to 20 per-alert GETs into one request. Failed lookups are now logged via the injectable stderr Logger (same pattern as telemetryService) instead of vanishing.

Changes

  • src/elastic/client/casesClient.tssearchAlertsByIds(indices, ids) replaces getAlertDocument + mgetAlerts; size clamped to the max_result_window default (10 000)
  • src/elastic/service/casesService.tsgetCaseAlerts enriches via one batched search over the deduplicated recorded indices; attachAlertsByIds dedups ids and uses the same search; both log lookup failures via injected logger (default createStderrLogger(["cases"]))
  • Tests updated: exact search request shape, batch enrichment, index dedup, id dedup, search-failure fallback + logging, empty-attachments short-circuit

Behavioral notes

  • _search is near-realtime where GET/_mget were realtime — negligible here since Kibana writes alerts with refresh and both flows operate on minutes-old alerts
  • Multi-index expansion is a set union, so passing alias + backing index never duplicates hits
  • New attachments still record the concrete _index from the search hit — stored attachment shape unchanged

Test plan

  • npx vitest run — 409/409 passing; typecheck and lint clean
  • Reproduced on a local cluster: generated detection alerts, forced _rollover on .alerts-security.alerts-default (alias → 000001+000002), created a case with 3 attached alerts → app showed Unknown rule / Low; with this fix the same case shows real rule names and severities (verified in Claude Desktop via MCPB build)
  • Verified the ids-query search returns full docs through the rolled-over alias on the customer-reported cluster as well

GET _doc/{id} and _mget are single-index operations: they fail with
'alias has more than one index associated with it' once ILM rolls the
alerts alias over, so on any long-lived cluster attachment enrichment
rendered every alert as 'Unknown rule' and attachAlertsByIds silently
attached 0 alerts.

Replace both lookups with one _search + ids query over the recorded
indices (works through multi-backing-index aliases, and batches up to
20 per-alert GETs into a single request). Failed lookups are now logged
via the injectable stderr Logger instead of being swallowed. Alert ids
are deduplicated before the lookup and the search size is clamped to
the max_result_window default.

Fixes #55
@maxcold
maxcold requested review from davethegut and niros1 July 8, 2026 13:34

@davethegut davethegut left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested and works! lgtm

@davethegut
davethegut merged commit 6c6f285 into main Jul 8, 2026
2 checks passed
@opauloh opauloh mentioned this pull request Jul 8, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Case alert attachments show 'Unknown rule' and alert attach silently attaches 0 on clusters with a rolled-over alerts index

3 participants