From b027dd5e6c337a541bddfd7058a6ef23034a81c3 Mon Sep 17 00:00:00 2001 From: kaushik-kumaran Date: Sat, 18 Jul 2026 17:34:09 -0500 Subject: [PATCH 1/2] Preserve SOG correlation IDs --- agent/src/webhook.py | 1 + agent/src/world_model.py | 4 ++++ agent/tests/test_world_model.py | 9 +++++++++ 3 files changed, 14 insertions(+) diff --git a/agent/src/webhook.py b/agent/src/webhook.py index 0a0a8dd..b87874c 100644 --- a/agent/src/webhook.py +++ b/agent/src/webhook.py @@ -219,6 +219,7 @@ async def process_alert(payload: dict) -> None: tags=payload.get("tags", []), hostname=payload.get("hostname"), assessment=assessment_dict, + correlation_id=payload.get("correlation_id") or raw_fields.get("sentinel.correlation_id"), ) # Upgrade entity security posture if reasoning found HIGH/CRITICAL and not FP diff --git a/agent/src/world_model.py b/agent/src/world_model.py index a536916..56cfaf3 100644 --- a/agent/src/world_model.py +++ b/agent/src/world_model.py @@ -118,6 +118,7 @@ async def post_finding( tags: list, hostname: str | None = None, assessment: dict | None = None, + correlation_id: str | None = None, ) -> dict[str, Any]: finding_event_id = event_id(dedup_key, alert_time) affected_entity_id = entity_id(raw_fields, hostname) @@ -130,6 +131,7 @@ async def post_finding( "priority": priority, "tags": tags, "raw_fields": raw_fields, + "provenance": "observed", } if assessment: payload["assessment"] = assessment @@ -144,6 +146,8 @@ async def post_finding( } if affected_entity_id: body["entity_id"] = affected_entity_id + if correlation_id: + body["correlation_id"] = correlation_id result = await _request("POST", "/findings", body, timeout=8.0) log_method = log.warning if result["status"] == "failed" else log.debug diff --git a/agent/tests/test_world_model.py b/agent/tests/test_world_model.py index ea008e8..51eb838 100644 --- a/agent/tests/test_world_model.py +++ b/agent/tests/test_world_model.py @@ -102,6 +102,15 @@ async def test_post_finding_uses_world_model_contract(): assert body["severity"] == "critical" assert body["payload"]["finding_type"] == "falco_alert" assert body["payload"]["description"] == "Unexpected shell spawned" + assert body["payload"]["provenance"] == "observed" + + +@pytest.mark.asyncio +async def test_post_finding_preserves_explicit_correlation_id(): + FakeClient.responses = [response(200, {"status": "accepted"})] + await world_model.post_finding(**finding_args(correlation_id="case-argus-phoenix-1")) + body = FakeClient.requests[0][2] + assert body["correlation_id"] == "case-argus-phoenix-1" @pytest.mark.asyncio From 37110d955b8cb94f56cda1da24f2d6f958eb80a3 Mon Sep 17 00:00:00 2001 From: kaushik-kumaran Date: Sat, 18 Jul 2026 17:36:17 -0500 Subject: [PATCH 2/2] Label replayed Argus evidence honestly --- agent/src/webhook.py | 2 ++ agent/src/world_model.py | 5 ++++- agent/tests/test_world_model.py | 9 +++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/agent/src/webhook.py b/agent/src/webhook.py index b87874c..1eb5617 100644 --- a/agent/src/webhook.py +++ b/agent/src/webhook.py @@ -220,6 +220,8 @@ async def process_alert(payload: dict) -> None: hostname=payload.get("hostname"), assessment=assessment_dict, correlation_id=payload.get("correlation_id") or raw_fields.get("sentinel.correlation_id"), + provenance=payload.get("provenance", "replayed" if payload.get("replayed") else "observed"), + replayed=bool(payload.get("replayed")), ) # Upgrade entity security posture if reasoning found HIGH/CRITICAL and not FP diff --git a/agent/src/world_model.py b/agent/src/world_model.py index 56cfaf3..6d5ca19 100644 --- a/agent/src/world_model.py +++ b/agent/src/world_model.py @@ -119,6 +119,8 @@ async def post_finding( hostname: str | None = None, assessment: dict | None = None, correlation_id: str | None = None, + provenance: str = "observed", + replayed: bool = False, ) -> dict[str, Any]: finding_event_id = event_id(dedup_key, alert_time) affected_entity_id = entity_id(raw_fields, hostname) @@ -131,7 +133,7 @@ async def post_finding( "priority": priority, "tags": tags, "raw_fields": raw_fields, - "provenance": "observed", + "provenance": provenance, } if assessment: payload["assessment"] = assessment @@ -142,6 +144,7 @@ async def post_finding( "source": "argus", "timestamp": alert_time, "severity": severity, + "replayed": replayed, "payload": payload, } if affected_entity_id: diff --git a/agent/tests/test_world_model.py b/agent/tests/test_world_model.py index 51eb838..ea3b26d 100644 --- a/agent/tests/test_world_model.py +++ b/agent/tests/test_world_model.py @@ -113,6 +113,15 @@ async def test_post_finding_preserves_explicit_correlation_id(): assert body["correlation_id"] == "case-argus-phoenix-1" +@pytest.mark.asyncio +async def test_replay_provenance_cannot_masquerade_as_observed(): + FakeClient.responses = [response(200, {"status": "accepted"})] + await world_model.post_finding(**finding_args(provenance="replayed", replayed=True)) + body = FakeClient.requests[0][2] + assert body["replayed"] is True + assert body["payload"]["provenance"] == "replayed" + + @pytest.mark.asyncio async def test_duplicate_is_successful_idempotent_outcome(): FakeClient.responses = [response(200, {"status": "duplicate"})]