Skip to content

[Entity Analytics] Update entity maintainers to use new relationship schema (ids object)#262911

Merged
seanrathier merged 24 commits intoelastic:mainfrom
seanrathier:feat/entity-maintainers-relationship-schema-262893
Apr 16, 2026
Merged

[Entity Analytics] Update entity maintainers to use new relationship schema (ids object)#262911
seanrathier merged 24 commits intoelastic:mainfrom
seanrathier:feat/entity-maintainers-relationship-schema-262893

Conversation

@seanrathier
Copy link
Copy Markdown
Contributor

@seanrathier seanrathier commented Apr 13, 2026

Summary

Closes #262893

Updates the communicates_with and accesses entity maintainers to write relationship values as { ids: string[] } objects instead of plain string arrays, aligning with the EntityRelationship schema introduced in #262242.

Both maintainers now carry { ids: string[] } end-to-end through their internal pipelines — from ProcessedEntityRecord through postprocessEsqlResults to buildEntityDoc/updateEntityRelationships.

Changes

communicates_with maintainer

  • types.tsProcessedEntityRecord.communicates_with: string[]{ ids: string[] }
  • postprocess_records.ts — wraps ESQL output in { ids: [...] }
  • run_maintainer.ts — logging updated to use .ids
  • update_entities.tsmergeRecordsByEntityId reads .ids for iteration/deduplication

accesses maintainer

  • types.tsProcessedEntityRecord.accesses_frequently/infrequently: string[]{ ids: string[] }
  • postprocess_records.ts — wraps ESQL output in { ids: [...] } (+ new test file)
  • run_maintainer.ts — logging updated to use .ids
  • update_entities.ts — guards updated to .ids.length > 0 (+ new test file)

How to test

  • Run node scripts/jest x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/maintainers --no-coverage — all 207 tests pass
  • Run node scripts/type_check --project x-pack/solutions/security/plugins/security_solution/tsconfig.json — no errors
  • Trigger a maintainer run and verify entity store documents contain { "ids": [...] } under relationship fields

seanrathier and others added 10 commits April 13, 2026 16:13
Tracks the changes needed in communicates_with and accesses maintainers
to align with the EntityRelationship schema introduced in elastic#262242.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ema update

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s schema

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update ProcessedEntityRecord usage in run_maintainer.test.ts to use
the { ids: string[] } object format matching the updated type definition,
and apply eslint auto-fix formatting to postprocess_records.test.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… to { ids: string[] } schema

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@seanrathier seanrathier requested a review from a team as a code owner April 13, 2026 21:35
@seanrathier seanrathier added Team:SIEM release_note:skip Skip the PR/issue when compiling release notes labels Apr 13, 2026
@seanrathier seanrathier requested a review from CAWilson94 April 13, 2026 21:35
@seanrathier seanrathier added Team:SIEM release_note:skip Skip the PR/issue when compiling release notes labels Apr 13, 2026
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/siem (Team:SIEM)

1 similar comment
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/siem (Team:SIEM)

@seanrathier seanrathier added Team:Cloud Security Cloud Security team related Team:Entity Analytics Security Entity Analytics Team and removed Team:SIEM labels Apr 13, 2026
@seanrathier seanrathier self-assigned this Apr 13, 2026
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/contextual-security-apps (Team:Cloud Security)

@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/security-entity-analytics (Team:Entity Analytics)

@seanrathier seanrathier added backport:version Backport to applied version labels v9.4.0 labels Apr 13, 2026
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented Apr 13, 2026

Approvability

Verdict: Needs human review

Schema change wrapping relationship arrays in { ids: [...] } objects affects runtime data shapes for entity analytics. Author does not own any of the 15 changed files (all owned by @elastic/security-entity-analytics), and two open review comments suggest code improvements. Designated code owners should review this schema migration.

You can customize Macroscope's approvability policy. Learn more.

@seanrathier seanrathier added the ci:cloud-deploy Create or update a Cloud deployment label Apr 13, 2026
@seanrathier seanrathier enabled auto-merge (squash) April 13, 2026 21:45
… write

Fixes elastic#262869

When multiple integrations produce ProcessedEntityRecord objects with
the same entityId, the accesses maintainer previously mapped them 1:1
to bulk update objects. Last-writer-wins meant only one integration's
host IDs survived.

Add mergeRecordsByEntityId to accumulate host IDs across all records
for the same entity before writing. The precedence rule ensures that
if a host appears in accesses_frequently from any integration it is
promoted out of accesses_infrequently.
@seanrathier seanrathier disabled auto-merge April 14, 2026 23:46
@seanrathier seanrathier removed the request for review from CAWilson94 April 15, 2026 14:35
Copy link
Copy Markdown
Contributor

@tiansivive tiansivive left a comment

Choose a reason for hiding this comment

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

Good stuff, just a few suggestions

}

return merged;
}
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.

This works, but I found it harder to follow than it needs to be because the logic is spread across nested loops, branching, and multiple mutation phases. As a reader, I have to mentally track state changes while also figuring out the actual business rules.
I think this would be much cleaner if it were structured more linearly, with explicit steps like filtering valid records, grouping by entityId, merging ids, then applying the precedence rule.

It would make the intent much easier to read at a glance.

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.

This is a bit nicer, and the comments do help, but I think the main readability issue is still the structure rather than the lack of explanation. It still relies on branching, nested iteration, and mutation across multiple phases, so I still have to trace the control flow pretty closely to understand it.
I was hoping for something where the steps are more directly reflected in the shape of the code, instead of needing comments to explain the flow.
Extracting to small named utility functions and then doing one chain of array methods like .map/.filter/.reduce or a similarly styled loop would help a lot

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I took a bit more time on this, I think this should satisfy your concerns.
I tried to find more common ground between the maintainers for a shared function but it was minimal.

This code will likely no longer exist in 9.5

- Restructure mergeRecordsByEntityId into explicit linear steps (filter,
  group, merge, precedence) to improve readability
- Replace `as Entity` coercion with `satisfies Entity` for stronger type
  safety

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@seanrathier seanrathier requested a review from tiansivive April 15, 2026 15:41
for (const t of r.communicates_with.ids) existing.targets.add(t);
} else {
merged.set(r.entityId, {
entityType: r.entityType,
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.

Nit: Not directly part of this PR, but I noticed an inconsistency between the two update_entities files:

  • In communicates_with/update_entities, entityType is typed as string (from MergedEntity)
  • In accesses/update_entities, EntityType is the Zod-derived enum from @kbn/entity-store/common

Unless MergedEntity.entityType intentionally needs to accept unknown values from raw data, it would be more consistent for both to use the EntityType enum, and runtime validation too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for noticing that! I didn't have an agent review pass on the last commit.

Copy link
Copy Markdown
Contributor

@CAWilson94 CAWilson94 left a comment

Choose a reason for hiding this comment

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

Desk Tested - working as described. Added one nit, otherwise LGTM with changes added 🚀

seanrathier and others added 3 commits April 16, 2026 14:29
Threads EntityType (the enum) through ProcessedEntityRecord.entityType,
postProcessEsqlResults, and MergedEntity instead of widening to string.
Removes the as BulkObject['type'] coercion and switches as Entity to
satisfies Entity for consistency with the accesses maintainer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…e steps

Extract a shared generic groupByEntityId utility and restructure both
accesses and communicates_with update_entities into explicit named
functions (filterValid / seed / merge / applyPrecedence) composed in a
clear pipeline, removing the need for inline comments to explain control
flow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@seanrathier seanrathier requested a review from CAWilson94 April 16, 2026 19:09
Copy link
Copy Markdown
Contributor

@tiansivive tiansivive left a comment

Choose a reason for hiding this comment

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

Thanks for addressing everything

@seanrathier seanrathier enabled auto-merge (squash) April 16, 2026 19:16
@elasticmachine
Copy link
Copy Markdown
Contributor

⏳ Build in-progress

History

cc @seanrathier

@seanrathier seanrathier merged commit 33ee38a into elastic:main Apr 16, 2026
14 checks passed
@kibanamachine
Copy link
Copy Markdown
Contributor

Starting backport for target branches: 9.4

https://github.com/elastic/kibana/actions/runs/24534917239

@kibanamachine
Copy link
Copy Markdown
Contributor

💚 All backports created successfully

Status Branch Result
9.4

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

kibanamachine added a commit that referenced this pull request Apr 16, 2026
…nship schema (ids object) (#262911) (#263917)

# Backport

This will backport the following commits from `main` to `9.4`:
- [[Entity Analytics] Update entity maintainers to use new relationship
schema (ids object)
(#262911)](#262911)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT
[{"author":{"name":"seanrathier","email":"sean.rathier@gmail.com"},"sourceCommit":{"committedDate":"2026-04-16T21:27:50Z","message":"[Entity
Analytics] Update entity maintainers to use new relationship schema (ids
object)
(#262911)","sha":"33ee38aa5ceacecdec388067c718661cbcaa6387","branchLabelMapping":{"^v9.5.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Cloud
Security","ci:cloud-deploy","Team:Entity
Analytics","backport:version","v9.4.0","v9.5.0"],"title":"[Entity
Analytics] Update entity maintainers to use new relationship schema (ids
object)","number":262911,"url":"https://github.com/elastic/kibana/pull/262911","mergeCommit":{"message":"[Entity
Analytics] Update entity maintainers to use new relationship schema (ids
object)
(#262911)","sha":"33ee38aa5ceacecdec388067c718661cbcaa6387"}},"sourceBranch":"main","suggestedTargetBranches":["9.4"],"targetPullRequestStates":[{"branch":"9.4","label":"v9.4.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.5.0","branchLabelMappingKey":"^v9.5.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/262911","number":262911,"mergeCommit":{"message":"[Entity
Analytics] Update entity maintainers to use new relationship schema (ids
object) (#262911)","sha":"33ee38aa5ceacecdec388067c718661cbcaa6387"}}]}]
BACKPORT-->

Co-authored-by: seanrathier <sean.rathier@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:version Backport to applied version labels ci:cloud-deploy Create or update a Cloud deployment release_note:skip Skip the PR/issue when compiling release notes Team:Cloud Security Cloud Security team related Team:Entity Analytics Security Entity Analytics Team v9.4.0 v9.5.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Entity Analytics] Update entity maintainers to use new relationship schema (ids object)

5 participants