Skip to content

[Contextual Security] add relationship node type for entity graph#249479

Merged
alexreal1314 merged 15 commits intoelastic:mainfrom
alexreal1314:247768-relationship-edge-type
Feb 1, 2026
Merged

[Contextual Security] add relationship node type for entity graph#249479
alexreal1314 merged 15 commits intoelastic:mainfrom
alexreal1314:247768-relationship-edge-type

Conversation

@alexreal1314
Copy link
Copy Markdown
Contributor

@alexreal1314 alexreal1314 commented Jan 18, 2026

Summary

Introduces a new "relationship" node type to the entity graph visualization, enabling the display of relationships between entities (e.g., "Owns", "Has Access") alongside event-based connections.

Key changes

Area Changes
New Component RelationshipNode with distinct dark styling to differentiate from event labels
Graph Layout Updated layout and edge handling to properly position relationship nodes
Utilities Added isConnectorNode for shared label/relationship node logic
Storybook New EventsAndEntityRelationships story demonstrating a realistic AWS scenario

How to test

  1. Deploy a local env using the following command:
    node scripts/es snapshot --license trial -E path.data=../default -E reindex.remote.whitelist=kfir-graph-viz-wip-ba715e.es.eu-west-1.aws.qa.elastic.cloud:443 -E xpack.security.authc.api_key.enabled=true
  2. run yarn storybook cloud_security_posture_grap and check the following stories:
    a. Go to Graph Components -> Graph Layout -> Events and Entity Relationships.
    b. Go to Graph Components -> Relationships Node.

Checklist

Check the PR satisfies following conditions.

Reviewers should verify this PR satisfies this list as well.

  • Any text added follows EUI's writing guidelines, uses sentence case text and includes i18n support
  • Documentation was added for features that require explanation or tutorials
  • Unit or functional tests were updated or added to match the most common scenarios
  • If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the docker list
  • This was checked for breaking HTTP API changes, and any breaking changes have been approved by the breaking-change committee. The release_note:breaking label should be applied in these situations.
  • Flaky Test Runner was used on any tests changed
  • The PR description includes the appropriate Release Notes section, and the correct release_note:* label is applied per the guidelines
  • Review the backport guidelines and apply applicable backport:* labels.

Screenshots

image image image

add RelationshipNode component with dedicated styling

add EventsAndEntityRelationships story demonstrating events and entity relationships

update related schemas and add unit tests for RelationshipNode component

update graph popover story with entity relationship options
@alexreal1314 alexreal1314 changed the title add relationship node type for entity graph [Contextual Security] add relationship node type for entity graph Jan 18, 2026
@alexreal1314 alexreal1314 marked this pull request as ready for review January 18, 2026 13:01
@alexreal1314 alexreal1314 requested a review from a team as a code owner January 18, 2026 13:01
@alexreal1314 alexreal1314 self-assigned this Jan 18, 2026
@alexreal1314 alexreal1314 added the Team:Cloud Security Cloud Security team related label Jan 18, 2026
@elasticmachine
Copy link
Copy Markdown
Contributor

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

@alexreal1314 alexreal1314 added backport:skip This PR does not require backporting release_note:skip Skip the PR/issue when compiling release notes labels Jan 18, 2026
Copy link
Copy Markdown
Contributor

@kfirpeled kfirpeled left a comment

Choose a reason for hiding this comment

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

Some misalignments from the design

Image
  1. We should not show the arrow marker when the edge comes to the relationship
  2. The edge should stretch to the node - see gaps of few pixels
  3. The edge color of relationships has a different color in the design
Image

While the width of the relationships is aligned with the width of events/alerts nodes, the edge curve of relationships is not aligned with the curve of events/alerts.

@alexreal1314 alexreal1314 marked this pull request as draft January 18, 2026 17:40
schema.literal('diamond'),
schema.literal('label'),
schema.literal('group'),
schema.literal('relationship'),
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.

Just a side note, the naming convention here is not aligned with the current design. However, I'm thinking to propose a new change to the existing node's names.

Instead of shape, we will have element type: relationship/entity/event/stack.

So I'm ok with keeping it now as it is.

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.

"relationship" sounds very business-domain specific to me, though I don't have a better suggestion.

On the other hand, I like the idea of future renaming label nodes to event, since we also have labels in each node

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 agree with both comments - right now we are coupling shape with node type. As I see it we should have the following:

  • node.type = element type - as mentioned @kfirpeled relationship/entity/event/stack.
  • one of the node params should be the shape. so we could reuse the component to display similar types - although need to check if its possible without major changes.

this would also require us to return additional property for each node - type.
For now i would leave current behavior and do it in a separate task.

schema.object({
shape: schema.literal('relationship'),
color: nodeColorSchema,
parentId: schema.maybe(schema.string()),
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.

I'm not sure we would like to stack relationships - worth to double check with design

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.

left a question.

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.

decided to support stacked nodes for relationships as well.

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.

depending on the proposed design - we could add more fields such as count and documentsData as a placeholder to store entities data if we decide to add some popover menu actions later.

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.

@kfirpeled as discussed in the sync - we are going to show relationship nodes in stacked groupes as well.

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.

Since then I think we reverted that decision not to stack.. anyway. Lets leave it here for now

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.

yes, I would leave it for now to see if all cases are covered - if not ill remove it.

label: {
control: { type: 'text' },
},
interactive: {
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.

When interactive is false - the element is still clickable and have an effect.
While It shouldn't be interactive to mouse clicks

Copy link
Copy Markdown
Contributor Author

@alexreal1314 alexreal1314 Jan 18, 2026

Choose a reason for hiding this comment

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

we have the same effect today for every node, its not movable but there is a click effect.

Screen.Recording.2026-01-18.at.22.16.41.mov

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.

Yep, that's a bug.. shouldn't happen

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.

fixed for all node types.

@alexreal1314
Copy link
Copy Markdown
Contributor Author

alexreal1314 commented Jan 18, 2026

Some misalignments from the design

Image 1. We should not show the arrow marker when the edge comes to the relationship 2. The edge should stretch to the node - see gaps of few pixels 3. The edge color of relationships has a different color in the design Image While the width of the relationships is aligned with the width of events/alerts nodes, the edge curve of relationships is not aligned with the curve of events/alerts.

fixed, there is still slight misalignment which happen in a specific case - in the middle child which is an existing issue.

image

ill try to investigate it a bit, but probably will create a separate ticket for that.

@alexreal1314 alexreal1314 marked this pull request as ready for review January 18, 2026 20:12
schema.literal('diamond'),
schema.literal('label'),
schema.literal('group'),
schema.literal('relationship'),
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.

"relationship" sounds very business-domain specific to me, though I don't have a better suggestion.

On the other hand, I like the idea of future renaming label nodes to event, since we also have labels in each node

export const TEST_SUBJ_HANDLE = 'relationship-node-handle';
export const TEST_SUBJ_HOVER_OUTLINE = 'relationship-node-hover-outline';
export const TEST_SUBJ_TOOLTIP = 'relationship-node-tooltip';
export const TEST_SUBJ_LABEL_TEXT = 'relationship-node-text';
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: Move this to the test_ids.ts file? I think we keep these test ids locally for <Ips> and <CountryFlags> but they were the only exceptions and we're doing the same here (very minor comment)

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.

done.

Copy link
Copy Markdown
Contributor

@albertoblaz albertoblaz left a comment

Choose a reason for hiding this comment

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

Question: How does relationship nodes work with grouping? What if we have multiple relationships between 2 grouped entity nodes? Asking because it seems there's no counter value rendered by the RelationshipNode component, and you added for now support for stacked relationships but it's still TBC by design.

@alexreal1314
Copy link
Copy Markdown
Contributor Author

alexreal1314 commented Jan 20, 2026

Question: How does relationship nodes work with grouping? What if we have multiple relationships between 2 grouped entity nodes? Asking because it seems there's no counter value rendered by the RelationshipNode component, and you added for now support for stacked relationships but it's still TBC by design.

We could have such case, I asked here about it.

Copy link
Copy Markdown
Contributor

@albertoblaz albertoblaz left a comment

Choose a reason for hiding this comment

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

LGTM

@alexreal1314
Copy link
Copy Markdown
Contributor Author

alexreal1314 commented Jan 28, 2026

@kfirpeled As i currently work on the graph api to support relationships fetching and I used this branch as the base branch seems like the fields we defined for the relationship node edge are sufficient. If I encounter anything which is missing i'll add them as part of the subsequent PR.

Copy link
Copy Markdown
Contributor

@kfirpeled kfirpeled left a comment

Choose a reason for hiding this comment

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

Missing minimap support

Image

schema.object({
shape: schema.literal('relationship'),
color: nodeColorSchema,
parentId: schema.maybe(schema.string()),
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.

Since then I think we reverted that decision not to stack.. anyway. Lets leave it here for now

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.

💯

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.

💯

label: {
control: { type: 'text' },
},
interactive: {
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.

Yep, that's a bug.. shouldn't happen

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.

Not sure what can be a better name for LabelShape or LabelNodeContainer

it is being used as the label of the edge..

  • Connector is one option you already used, which can be a good fit

Copy link
Copy Markdown
Contributor Author

@alexreal1314 alexreal1314 Jan 31, 2026

Choose a reason for hiding this comment

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

Yes, this is a good option to call it something like ConnectorNode once we do #249479 (comment) to render different types of connector nodes in a single ConnectorNode.

@alexreal1314
Copy link
Copy Markdown
Contributor Author

Missing minimap support

Image

added, thanks.

image

…ctive is false

make the graph component refresh when interactive is toggled to reflect the changes
@elasticmachine
Copy link
Copy Markdown
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #127 / "before all" hook in "{root}"

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
securitySolution 8699 8700 +1

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/cloud-security-posture-graph 58 59 +1

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
securitySolution 10.9MB 10.9MB +2.7KB
Unknown metric groups

API count

id before after diff
@kbn/cloud-security-posture-graph 90 91 +1

History

cc @alexreal1314

@alexreal1314 alexreal1314 merged commit 5103837 into elastic:main Feb 1, 2026
17 checks passed
mbondyra added a commit to mbondyra/kibana that referenced this pull request Feb 2, 2026
…iew_cps

* commit '3cd2ea4a515d8a0aafd32f75dc61f1cff892a4b0':
  Fix Failing test: APM Service overview - header filters (elastic#250355)
  [ES|QL] Small improvements on the editor (elastic#251004)
  [ES|QL] Refactor promql validation (elastic#250996)
  [ES|QL] Update the readme in esql-utils (elastic#251024)
  [ES|QL] Grouping functions as arguments to scalar functions (elastic#251015)
  [ES|QL] focus editor when user uses visor (elastic#251084)
  [Contextual Security] add relationship node type for entity graph (elastic#249479)
  [One Workflow] Fix email connector documentation: to field (elastic#251171)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting ci:build-storybooks release_note:skip Skip the PR/issue when compiling release notes Team:Cloud Security Cloud Security team related v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants