From 6bc34664b955362cdbf2a002399a80d9d07eafa3 Mon Sep 17 00:00:00 2001 From: Konstantin Serebryakov <97249355+KonstantinSerebryakov@users.noreply.github.com> Date: Wed, 7 Oct 2026 20:40:29 +0300 Subject: [PATCH 1/2] fix(webhooks): enforce multiaccount transition ancestry --- .../multiaccount-changed-event.schema.json | 28 +++++++++++++++++++ dist/schemas/webhook-event.schema.json | 28 +++++++++++++++++++ dist/shieldlabs-api.json | 28 +++++++++++++++++++ dist/shieldlabs-api.yaml | 16 +++++++++++ .../schemas/MultiaccountChangedData.yaml | 12 ++++++++ test/multiaccount-webhook.test.mjs | 11 ++++++++ 6 files changed, 123 insertions(+) diff --git a/dist/schemas/multiaccount-changed-event.schema.json b/dist/schemas/multiaccount-changed-event.schema.json index 21dd85a..15bea8b 100644 --- a/dist/schemas/multiaccount-changed-event.schema.json +++ b/dist/schemas/multiaccount-changed-event.schema.json @@ -198,6 +198,34 @@ } }, "allOf": [ + { + "if": { + "properties": { + "action": { + "const": "detected" + } + }, + "required": [ + "action" + ] + }, + "then": { + "additionalProperties": true, + "properties": { + "previous_revision": { + "type": "null" + } + } + }, + "else": { + "additionalProperties": true, + "properties": { + "previous_revision": { + "type": "string" + } + } + } + }, { "if": { "properties": { diff --git a/dist/schemas/webhook-event.schema.json b/dist/schemas/webhook-event.schema.json index d9b7de1..6859253 100644 --- a/dist/schemas/webhook-event.schema.json +++ b/dist/schemas/webhook-event.schema.json @@ -1027,6 +1027,34 @@ } }, "allOf": [ + { + "if": { + "properties": { + "action": { + "const": "detected" + } + }, + "required": [ + "action" + ] + }, + "then": { + "additionalProperties": true, + "properties": { + "previous_revision": { + "type": "null" + } + } + }, + "else": { + "additionalProperties": true, + "properties": { + "previous_revision": { + "type": "string" + } + } + } + }, { "if": { "properties": { diff --git a/dist/shieldlabs-api.json b/dist/shieldlabs-api.json index 177a510..c35080f 100644 --- a/dist/shieldlabs-api.json +++ b/dist/shieldlabs-api.json @@ -2186,6 +2186,34 @@ } }, "allOf": [ + { + "if": { + "properties": { + "action": { + "const": "detected" + } + }, + "required": [ + "action" + ] + }, + "then": { + "additionalProperties": true, + "properties": { + "previous_revision": { + "type": "null" + } + } + }, + "else": { + "additionalProperties": true, + "properties": { + "previous_revision": { + "type": "string" + } + } + } + }, { "if": { "properties": { diff --git a/dist/shieldlabs-api.yaml b/dist/shieldlabs-api.yaml index 9cbe011..80c75d1 100644 --- a/dist/shieldlabs-api.yaml +++ b/dist/shieldlabs-api.yaml @@ -1906,6 +1906,22 @@ components: type: boolean description: Whether the detector's underlying detailed evidence was truncated. Group membership remains complete. allOf: + - if: + properties: + action: + const: detected + required: + - action + then: + additionalProperties: true + properties: + previous_revision: + type: 'null' + else: + additionalProperties: true + properties: + previous_revision: + type: string - if: properties: action: diff --git a/spec/components/schemas/MultiaccountChangedData.yaml b/spec/components/schemas/MultiaccountChangedData.yaml index 3cb4bdf..186112b 100644 --- a/spec/components/schemas/MultiaccountChangedData.yaml +++ b/spec/components/schemas/MultiaccountChangedData.yaml @@ -83,6 +83,18 @@ properties: type: boolean description: Whether the detector's underlying detailed evidence was truncated. Group membership remains complete. allOf: + - if: + properties: + action: {const: detected} + required: [action] + then: + additionalProperties: true + properties: + previous_revision: {type: 'null'} + else: + additionalProperties: true + properties: + previous_revision: {type: string} - if: properties: action: {const: resolved} diff --git a/test/multiaccount-webhook.test.mjs b/test/multiaccount-webhook.test.mjs index 5f83084..6977a40 100644 --- a/test/multiaccount-webhook.test.mjs +++ b/test/multiaccount-webhook.test.mjs @@ -27,3 +27,14 @@ test('known multi-account events cannot bypass result validation',()=>{ const bad=structuredClone(e);mutate(bad);assert.equal(union(bad),false); } }); +test('transition ancestry distinguishes a new episode from an existing group',()=>{ + for (const action of ['detected','updated','resolved']) { + const event=JSON.parse(readFileSync(new URL('./fixtures/webhook-multiaccount-'+action+'.json',import.meta.url))); + event.data.previous_revision=action==='detected'?'1':null; + assert.equal(validate(event),false,action+' accepted invalid transition ancestry'); + assert.equal(union(event),false,action+' bypassed union validation'); + } + const baseline=JSON.parse(readFileSync(new URL('./fixtures/webhook-multiaccount-resolved.json',import.meta.url))); + baseline.data.previous_revision='0'; + assert.ok(validate(baseline),JSON.stringify(validate.errors)); +}); From 29ca11c05f6520038df600c3564c088ffd6d8e2e Mon Sep 17 00:00:00 2001 From: Konstantin Serebryakov <97249355+KonstantinSerebryakov@users.noreply.github.com> Date: Wed, 7 Oct 2026 21:07:57 +0300 Subject: [PATCH 2/2] feat(webhooks): define persistent cluster identity and membership deltas --- .../multiaccount-changed-event.schema.json | 22 +++++++- dist/schemas/webhook-event.schema.json | 22 +++++++- dist/shieldlabs-api.json | 50 ++++++++++++++++--- dist/shieldlabs-api.yaml | 46 +++++++++++++---- .../examples/MultiaccountDetected.yaml | 9 +++- .../examples/MultiaccountResolved.yaml | 9 +++- .../examples/MultiaccountUpdated.yaml | 6 ++- .../schemas/MultiaccountChangedData.yaml | 14 +++++- spec/webhooks/multiaccount-changed.yaml | 4 +- .../webhook-multiaccount-detected.json | 10 +++- .../webhook-multiaccount-resolved.json | 10 +++- .../webhook-multiaccount-updated.json | 6 ++- 12 files changed, 173 insertions(+), 35 deletions(-) diff --git a/dist/schemas/multiaccount-changed-event.schema.json b/dist/schemas/multiaccount-changed-event.schema.json index 15bea8b..e13f05c 100644 --- a/dist/schemas/multiaccount-changed-event.schema.json +++ b/dist/schemas/multiaccount-changed-event.schema.json @@ -51,6 +51,8 @@ "revision", "previous_revision", "user_hids", + "added_user_hids", + "removed_user_hids", "users_count", "members_complete", "evaluated_at", @@ -95,7 +97,7 @@ "cluster_id": { "type": "string", "format": "uuid", - "description": "ID of the exact sorted user set within this site. A membership change resolves the old group and detects a new group." + "description": "Persistent site-qualified group identity. Unambiguous expansion or contraction preserves this ID; ambiguous split/merge starts new identities." }, "revision": { "type": "string", @@ -128,6 +130,24 @@ } } }, + "added_user_hids": { + "type": "array", + "uniqueItems": true, + "description": "Sorted members added since the previous transition; all current members for detected.", + "items": { + "type": "string", + "minLength": 1 + } + }, + "removed_user_hids": { + "type": "array", + "uniqueItems": true, + "description": "Sorted members removed since the previous transition; all previous members for resolved.", + "items": { + "type": "string", + "minLength": 1 + } + }, "users_count": { "type": "integer", "minimum": 3, diff --git a/dist/schemas/webhook-event.schema.json b/dist/schemas/webhook-event.schema.json index 6859253..d085438 100644 --- a/dist/schemas/webhook-event.schema.json +++ b/dist/schemas/webhook-event.schema.json @@ -880,6 +880,8 @@ "revision", "previous_revision", "user_hids", + "added_user_hids", + "removed_user_hids", "users_count", "members_complete", "evaluated_at", @@ -924,7 +926,7 @@ "cluster_id": { "type": "string", "format": "uuid", - "description": "ID of the exact sorted user set within this site. A membership change resolves the old group and detects a new group." + "description": "Persistent site-qualified group identity. Unambiguous expansion or contraction preserves this ID; ambiguous split/merge starts new identities." }, "revision": { "type": "string", @@ -957,6 +959,24 @@ } } }, + "added_user_hids": { + "type": "array", + "uniqueItems": true, + "description": "Sorted members added since the previous transition; all current members for detected.", + "items": { + "type": "string", + "minLength": 1 + } + }, + "removed_user_hids": { + "type": "array", + "uniqueItems": true, + "description": "Sorted members removed since the previous transition; all previous members for resolved.", + "items": { + "type": "string", + "minLength": 1 + } + }, "users_count": { "type": "integer", "minimum": 3, diff --git a/dist/shieldlabs-api.json b/dist/shieldlabs-api.json index c35080f..1a95ca7 100644 --- a/dist/shieldlabs-api.json +++ b/dist/shieldlabs-api.json @@ -439,7 +439,7 @@ "Webhooks" ], "summary": "A multi-account group changed", - "description": "Opt-in notification when a complete background detector publication detects, updates, or\nresolves an exact group of accounts. Enable `multiaccount: true` on the webhook endpoint.\nThe default is false; existing identification.scored subscriptions are preserved.\n\nA repeated build with unchanged membership, level, and rules does not produce a new event.\nA membership change produces resolved for the previous exact group and detected for the new\nexact group. Resolved means the group is no longer supported by the current complete source\ncut, including evidence expiry; it does not certify that its accounts are safe.\n\nDelivery is at least once, with no global ordering guarantee. Save event_id atomically with\nyour business operation. Within a site, publication epoch, and cluster_id, compare revision\nas an integer and ignore older transitions. Verify HMAC-SHA256 over the raw received bytes;\nX-Shield-Event-Id is a convenience header, and the signed body is authoritative.\n\nThis event has no request_id or risk_score. Its source identifies the published group result;\nit does not mutate an earlier identification.scored body or an already pinned Console view.", + "description": "Opt-in notification when a complete background detector publication detects, updates, or\nresolves an exact group of accounts. Enable `multiaccount: true` on the webhook endpoint.\nThe default is false; existing identification.scored subscriptions are preserved.\n\nA repeated build with unchanged membership, level, and rules does not produce a new event.\nAn unambiguous membership expansion or contraction preserves cluster_id and produces updated.\nAmbiguous splits or merges resolve replaced groups and detect new identities. Resolved means the group is no longer supported by the current complete source\ncut, including evidence expiry; it does not certify that its accounts are safe.\n\nDelivery is at least once, with no global ordering guarantee. Save event_id atomically with\nyour business operation. Within a site, publication epoch, and cluster_id, compare revision\nas an integer and ignore older transitions. Verify HMAC-SHA256 over the raw received bytes;\nX-Shield-Event-Id is a convenience header, and the signed body is authoritative.\n\nThis event has no request_id or risk_score. Its source identifies the published group result;\nit does not mutate an earlier identification.scored body or an already pinned Console view.", "security": [], "parameters": [ { @@ -2039,6 +2039,8 @@ "revision", "previous_revision", "user_hids", + "added_user_hids", + "removed_user_hids", "users_count", "members_complete", "evaluated_at", @@ -2083,7 +2085,7 @@ "cluster_id": { "type": "string", "format": "uuid", - "description": "ID of the exact sorted user set within this site. A membership change resolves the old group and detects a new group." + "description": "Persistent site-qualified group identity. Unambiguous expansion or contraction preserves this ID; ambiguous split/merge starts new identities." }, "revision": { "type": "string", @@ -2116,6 +2118,24 @@ } } }, + "added_user_hids": { + "type": "array", + "uniqueItems": true, + "description": "Sorted members added since the previous transition; all current members for detected.", + "items": { + "type": "string", + "minLength": 1 + } + }, + "removed_user_hids": { + "type": "array", + "uniqueItems": true, + "description": "Sorted members removed since the previous transition; all previous members for resolved.", + "items": { + "type": "string", + "minLength": 1 + } + }, "users_count": { "type": "integer", "minimum": 3, @@ -3464,7 +3484,7 @@ "summary": "Multi-account group detected", "description": "Generated by the Core event marshaler for a synthetic three-account group.", "value": { - "event_id": "ad5efdbb113f50d1207c3a3b1d03e54ee60dfb9a", + "event_id": "7795f86574643ece49997885d0a0a3e5768dcb74", "site_id": 319, "event_type": "hre.multi_account.changed", "schema_version": "2026-10-07", @@ -3476,9 +3496,15 @@ "status": "evaluated", "detected": true, "level": "medium", - "cluster_id": "4293f02e-7cf0-5cda-9150-b5b8c4ee685d", + "cluster_id": "abc35eb1-2cd7-5c28-a805-f3b7c1682a2f", "revision": "7412", "previous_revision": null, + "added_user_hids": [ + "account_a", + "account_b", + "account_c" + ], + "removed_user_hids": [], "user_hids": [ "account_a", "account_b", @@ -3509,7 +3535,7 @@ "summary": "Multi-account group updated", "description": "Generated by the Core event marshaler for a synthetic three-account group.", "value": { - "event_id": "27225e88895f45c6f96562578308d3afea9d4ea2", + "event_id": "2feaa43f05ad19dadd78c85c465c8b4d101f9e2f", "site_id": 319, "event_type": "hre.multi_account.changed", "schema_version": "2026-10-07", @@ -3521,9 +3547,11 @@ "status": "evaluated", "detected": true, "level": "high", - "cluster_id": "4293f02e-7cf0-5cda-9150-b5b8c4ee685d", + "cluster_id": "abc35eb1-2cd7-5c28-a805-f3b7c1682a2f", "revision": "7414", "previous_revision": "7412", + "added_user_hids": [], + "removed_user_hids": [], "user_hids": [ "account_a", "account_b", @@ -3554,7 +3582,7 @@ "summary": "Multi-account group resolved", "description": "Generated by the Core event marshaler for a synthetic three-account group.", "value": { - "event_id": "0e703af70ff450065df0457d71789d32df4de079", + "event_id": "1f12f427edb3e4b74df2c0c958db49186ef0a7b9", "site_id": 319, "event_type": "hre.multi_account.changed", "schema_version": "2026-10-07", @@ -3566,9 +3594,15 @@ "status": "evaluated", "detected": false, "level": null, - "cluster_id": "4293f02e-7cf0-5cda-9150-b5b8c4ee685d", + "cluster_id": "abc35eb1-2cd7-5c28-a805-f3b7c1682a2f", "revision": "7415", "previous_revision": "7412", + "added_user_hids": [], + "removed_user_hids": [ + "account_a", + "account_b", + "account_c" + ], "user_hids": [ "account_a", "account_b", diff --git a/dist/shieldlabs-api.yaml b/dist/shieldlabs-api.yaml index 80c75d1..09dcf54 100644 --- a/dist/shieldlabs-api.yaml +++ b/dist/shieldlabs-api.yaml @@ -478,8 +478,8 @@ webhooks: The default is false; existing identification.scored subscriptions are preserved. A repeated build with unchanged membership, level, and rules does not produce a new event. - A membership change produces resolved for the previous exact group and detected for the new - exact group. Resolved means the group is no longer supported by the current complete source + An unambiguous membership expansion or contraction preserves cluster_id and produces updated. + Ambiguous splits or merges resolve replaced groups and detect new identities. Resolved means the group is no longer supported by the current complete source cut, including evidence expiry; it does not certify that its accounts are safe. Delivery is at least once, with no global ordering guarantee. Save event_id atomically with @@ -1796,6 +1796,8 @@ components: - revision - previous_revision - user_hids + - added_user_hids + - removed_user_hids - users_count - members_complete - evaluated_at @@ -1830,7 +1832,7 @@ components: cluster_id: type: string format: uuid - description: ID of the exact sorted user set within this site. A membership change resolves the old group and detects a new group. + description: Persistent site-qualified group identity. Unambiguous expansion or contraction preserves this ID; ambiguous split/merge starts new identities. revision: type: string pattern: ^[1-9][0-9]{0,19}$ @@ -1855,6 +1857,20 @@ components: - '-1' - fail - 00000000-0000-0000-0000-000000000000 + added_user_hids: + type: array + uniqueItems: true + description: Sorted members added since the previous transition; all current members for detected. + items: + type: string + minLength: 1 + removed_user_hids: + type: array + uniqueItems: true + description: Sorted members removed since the previous transition; all previous members for resolved. + items: + type: string + minLength: 1 users_count: type: integer minimum: 3 @@ -2944,7 +2960,7 @@ components: summary: Multi-account group detected description: Generated by the Core event marshaler for a synthetic three-account group. value: - event_id: ad5efdbb113f50d1207c3a3b1d03e54ee60dfb9a + event_id: 7795f86574643ece49997885d0a0a3e5768dcb74 site_id: 319 event_type: hre.multi_account.changed schema_version: '2026-10-07' @@ -2956,9 +2972,14 @@ components: status: evaluated detected: true level: medium - cluster_id: 4293f02e-7cf0-5cda-9150-b5b8c4ee685d + cluster_id: abc35eb1-2cd7-5c28-a805-f3b7c1682a2f revision: '7412' previous_revision: null + added_user_hids: + - account_a + - account_b + - account_c + removed_user_hids: [] user_hids: - account_a - account_b @@ -2981,7 +3002,7 @@ components: summary: Multi-account group updated description: Generated by the Core event marshaler for a synthetic three-account group. value: - event_id: 27225e88895f45c6f96562578308d3afea9d4ea2 + event_id: 2feaa43f05ad19dadd78c85c465c8b4d101f9e2f site_id: 319 event_type: hre.multi_account.changed schema_version: '2026-10-07' @@ -2993,9 +3014,11 @@ components: status: evaluated detected: true level: high - cluster_id: 4293f02e-7cf0-5cda-9150-b5b8c4ee685d + cluster_id: abc35eb1-2cd7-5c28-a805-f3b7c1682a2f revision: '7414' previous_revision: '7412' + added_user_hids: [] + removed_user_hids: [] user_hids: - account_a - account_b @@ -3018,7 +3041,7 @@ components: summary: Multi-account group resolved description: Generated by the Core event marshaler for a synthetic three-account group. value: - event_id: 0e703af70ff450065df0457d71789d32df4de079 + event_id: 1f12f427edb3e4b74df2c0c958db49186ef0a7b9 site_id: 319 event_type: hre.multi_account.changed schema_version: '2026-10-07' @@ -3030,9 +3053,14 @@ components: status: evaluated detected: false level: null - cluster_id: 4293f02e-7cf0-5cda-9150-b5b8c4ee685d + cluster_id: abc35eb1-2cd7-5c28-a805-f3b7c1682a2f revision: '7415' previous_revision: '7412' + added_user_hids: [] + removed_user_hids: + - account_a + - account_b + - account_c user_hids: - account_a - account_b diff --git a/spec/components/examples/MultiaccountDetected.yaml b/spec/components/examples/MultiaccountDetected.yaml index 7647c25..635319e 100644 --- a/spec/components/examples/MultiaccountDetected.yaml +++ b/spec/components/examples/MultiaccountDetected.yaml @@ -2,7 +2,7 @@ summary: "Multi-account group detected" description: "Generated by the Core event marshaler for a synthetic three-account group." value: - event_id: "ad5efdbb113f50d1207c3a3b1d03e54ee60dfb9a" + event_id: "7795f86574643ece49997885d0a0a3e5768dcb74" site_id: 319 event_type: "hre.multi_account.changed" schema_version: "2026-10-07" @@ -14,9 +14,14 @@ value: status: "evaluated" detected: true level: "medium" - cluster_id: "4293f02e-7cf0-5cda-9150-b5b8c4ee685d" + cluster_id: "abc35eb1-2cd7-5c28-a805-f3b7c1682a2f" revision: "7412" previous_revision: null + added_user_hids: + - "account_a" + - "account_b" + - "account_c" + removed_user_hids: [] user_hids: - "account_a" - "account_b" diff --git a/spec/components/examples/MultiaccountResolved.yaml b/spec/components/examples/MultiaccountResolved.yaml index b1b8fce..5524f64 100644 --- a/spec/components/examples/MultiaccountResolved.yaml +++ b/spec/components/examples/MultiaccountResolved.yaml @@ -2,7 +2,7 @@ summary: "Multi-account group resolved" description: "Generated by the Core event marshaler for a synthetic three-account group." value: - event_id: "0e703af70ff450065df0457d71789d32df4de079" + event_id: "1f12f427edb3e4b74df2c0c958db49186ef0a7b9" site_id: 319 event_type: "hre.multi_account.changed" schema_version: "2026-10-07" @@ -14,9 +14,14 @@ value: status: "evaluated" detected: false level: null - cluster_id: "4293f02e-7cf0-5cda-9150-b5b8c4ee685d" + cluster_id: "abc35eb1-2cd7-5c28-a805-f3b7c1682a2f" revision: "7415" previous_revision: "7412" + added_user_hids: [] + removed_user_hids: + - "account_a" + - "account_b" + - "account_c" user_hids: - "account_a" - "account_b" diff --git a/spec/components/examples/MultiaccountUpdated.yaml b/spec/components/examples/MultiaccountUpdated.yaml index f813223..9d0642f 100644 --- a/spec/components/examples/MultiaccountUpdated.yaml +++ b/spec/components/examples/MultiaccountUpdated.yaml @@ -2,7 +2,7 @@ summary: "Multi-account group updated" description: "Generated by the Core event marshaler for a synthetic three-account group." value: - event_id: "27225e88895f45c6f96562578308d3afea9d4ea2" + event_id: "2feaa43f05ad19dadd78c85c465c8b4d101f9e2f" site_id: 319 event_type: "hre.multi_account.changed" schema_version: "2026-10-07" @@ -14,9 +14,11 @@ value: status: "evaluated" detected: true level: "high" - cluster_id: "4293f02e-7cf0-5cda-9150-b5b8c4ee685d" + cluster_id: "abc35eb1-2cd7-5c28-a805-f3b7c1682a2f" revision: "7414" previous_revision: "7412" + added_user_hids: [] + removed_user_hids: [] user_hids: - "account_a" - "account_b" diff --git a/spec/components/schemas/MultiaccountChangedData.yaml b/spec/components/schemas/MultiaccountChangedData.yaml index 186112b..9282fe1 100644 --- a/spec/components/schemas/MultiaccountChangedData.yaml +++ b/spec/components/schemas/MultiaccountChangedData.yaml @@ -1,6 +1,6 @@ type: object additionalProperties: false -required: [kind, domain, action, status, detected, level, cluster_id, revision, previous_revision, user_hids, users_count, members_complete, evaluated_at, rules_version, source, evidence_summary] +required: [kind, domain, action, status, detected, level, cluster_id, revision, previous_revision, user_hids, added_user_hids, removed_user_hids, users_count, members_complete, evaluated_at, rules_version, source, evidence_summary] properties: kind: const: multi_account @@ -21,7 +21,7 @@ properties: cluster_id: type: string format: uuid - description: ID of the exact sorted user set within this site. A membership change resolves the old group and detects a new group. + description: Persistent site-qualified group identity. Unambiguous expansion or contraction preserves this ID; ambiguous split/merge starts new identities. revision: type: string pattern: '^[1-9][0-9]{0,19}$' @@ -40,6 +40,16 @@ properties: minLength: 1 not: enum: [anonymous, '-1', fail, '00000000-0000-0000-0000-000000000000'] + added_user_hids: + type: array + uniqueItems: true + description: Sorted members added since the previous transition; all current members for detected. + items: {type: string, minLength: 1} + removed_user_hids: + type: array + uniqueItems: true + description: Sorted members removed since the previous transition; all previous members for resolved. + items: {type: string, minLength: 1} users_count: type: integer minimum: 3 diff --git a/spec/webhooks/multiaccount-changed.yaml b/spec/webhooks/multiaccount-changed.yaml index 2dfc54d..588424f 100644 --- a/spec/webhooks/multiaccount-changed.yaml +++ b/spec/webhooks/multiaccount-changed.yaml @@ -8,8 +8,8 @@ post: The default is false; existing identification.scored subscriptions are preserved. A repeated build with unchanged membership, level, and rules does not produce a new event. - A membership change produces resolved for the previous exact group and detected for the new - exact group. Resolved means the group is no longer supported by the current complete source + An unambiguous membership expansion or contraction preserves cluster_id and produces updated. + Ambiguous splits or merges resolve replaced groups and detect new identities. Resolved means the group is no longer supported by the current complete source cut, including evidence expiry; it does not certify that its accounts are safe. Delivery is at least once, with no global ordering guarantee. Save event_id atomically with diff --git a/test/fixtures/webhook-multiaccount-detected.json b/test/fixtures/webhook-multiaccount-detected.json index 3f4c68d..c217f3d 100644 --- a/test/fixtures/webhook-multiaccount-detected.json +++ b/test/fixtures/webhook-multiaccount-detected.json @@ -1,5 +1,5 @@ { - "event_id": "ad5efdbb113f50d1207c3a3b1d03e54ee60dfb9a", + "event_id": "7795f86574643ece49997885d0a0a3e5768dcb74", "site_id": 319, "event_type": "hre.multi_account.changed", "schema_version": "2026-10-07", @@ -11,9 +11,15 @@ "status": "evaluated", "detected": true, "level": "medium", - "cluster_id": "4293f02e-7cf0-5cda-9150-b5b8c4ee685d", + "cluster_id": "abc35eb1-2cd7-5c28-a805-f3b7c1682a2f", "revision": "7412", "previous_revision": null, + "added_user_hids": [ + "account_a", + "account_b", + "account_c" + ], + "removed_user_hids": [], "user_hids": [ "account_a", "account_b", diff --git a/test/fixtures/webhook-multiaccount-resolved.json b/test/fixtures/webhook-multiaccount-resolved.json index 9627904..159b126 100644 --- a/test/fixtures/webhook-multiaccount-resolved.json +++ b/test/fixtures/webhook-multiaccount-resolved.json @@ -1,5 +1,5 @@ { - "event_id": "0e703af70ff450065df0457d71789d32df4de079", + "event_id": "1f12f427edb3e4b74df2c0c958db49186ef0a7b9", "site_id": 319, "event_type": "hre.multi_account.changed", "schema_version": "2026-10-07", @@ -11,9 +11,15 @@ "status": "evaluated", "detected": false, "level": null, - "cluster_id": "4293f02e-7cf0-5cda-9150-b5b8c4ee685d", + "cluster_id": "abc35eb1-2cd7-5c28-a805-f3b7c1682a2f", "revision": "7415", "previous_revision": "7412", + "added_user_hids": [], + "removed_user_hids": [ + "account_a", + "account_b", + "account_c" + ], "user_hids": [ "account_a", "account_b", diff --git a/test/fixtures/webhook-multiaccount-updated.json b/test/fixtures/webhook-multiaccount-updated.json index df380db..a822219 100644 --- a/test/fixtures/webhook-multiaccount-updated.json +++ b/test/fixtures/webhook-multiaccount-updated.json @@ -1,5 +1,5 @@ { - "event_id": "27225e88895f45c6f96562578308d3afea9d4ea2", + "event_id": "2feaa43f05ad19dadd78c85c465c8b4d101f9e2f", "site_id": 319, "event_type": "hre.multi_account.changed", "schema_version": "2026-10-07", @@ -11,9 +11,11 @@ "status": "evaluated", "detected": true, "level": "high", - "cluster_id": "4293f02e-7cf0-5cda-9150-b5b8c4ee685d", + "cluster_id": "abc35eb1-2cd7-5c28-a805-f3b7c1682a2f", "revision": "7414", "previous_revision": "7412", + "added_user_hids": [], + "removed_user_hids": [], "user_hids": [ "account_a", "account_b",