Skip to content

fix: incidentio dedup-key as a min 3 hour window - #3823

Open
Ziinc wants to merge 3 commits into
mainfrom
fix-incidentio-dedup-key
Open

fix: incidentio dedup-key as a min 3 hour window#3823
Ziinc wants to merge 3 commits into
mainfrom
fix-incidentio-dedup-key

Conversation

@Ziinc

@Ziinc Ziinc commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Remove minutely deduplication key in incidentio adaptor
Fixes the issue where an alert constantly pages due to the changing minute

Comment thread lib/logflare/backends/adaptor/incidentio_adaptor.ex Outdated
@Ziinc Ziinc changed the title fix-incidentio-dedup-key fix: incidentio-dedup-key Aug 13, 2026
@Ziinc Ziinc changed the title fix: incidentio-dedup-key fix: incidentio dedup-key as a min 3 hour window Aug 13, 2026

%{
"deduplication_key" => "#{hash}-#{now.minute}",
"deduplication_key" => "#{alert_query_id}-#{alert_name}-#{window}",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Severity: MEDIUM

Raw log and rule-triggered events do not set alert_query_id or title, making this key identical for every batch within a 3-hour window. An attacker who can submit one event can cause Incident.io to deduplicate later security-relevant events instead of paging, hiding incidents for up to three hours.
Helpful? Add 👍 / 👎

💡 Fix Suggestion

Suggestion: When alert_query_id is not present in the config (i.e., for raw log events not triggered by an alert query), the deduplication key collapses to "unknown-unknown-#{window}" for every batch, which allows any ingested event to suppress all subsequent raw-log incident pages for up to 3 hours. The fix is to generate a unique deduplication key (e.g., a UUID) when no alert_query_id is available, so raw log event batches are never deduplicated against each other, while proper alert-query-driven events continue to use the stable "#{alert_query_id}-#{alert_name}-#{window}" key for intentional 3-hour deduplication.

⚠️ Experimental Feature: This code suggestion is automatically generated. Please review carefully.

Suggested change
"deduplication_key" => "#{alert_query_id}-#{alert_name}-#{window}",
"deduplication_key" => if(Map.has_key?(config, :alert_query_id), do: "#{alert_query_id}-#{alert_name}-#{window}", else: Ecto.UUID.generate()),

hash = :erlang.phash2(batch)
alert_name = Map.get(config, :title, "unknown")
alert_query_id = Map.get(config, :alert_query_id, "unknown")
window = div(DateTime.to_unix(DateTime.utc_now()), 3 * 60 * 60)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖

Dividing Unix time into fixed buckets does not guarantee three hours between new keys. Firings immediately before and after a UTC bucket boundary can generate different keys seconds apart. If the requirement is a minimum rolling three-hour interval, persist per-alert expiry state and rotate only after three elapsed hours. Otherwise, document this explicitly as an epoch-aligned three-hour bucket.


%{
"deduplication_key" => "#{hash}-#{now.minute}",
"deduplication_key" => "#{alert_query_id}-#{alert_name}-#{window}",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖

The key now contains the unique alert-query ID, so including the mutable alert_name makes the deduplication identity unstable. Renaming a firing alert changes its key and creates another Incident.io alert within the same window. Use only the immutable query ID and the chosen window identity; retain the name as display data.

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.

2 participants