Skip to content

[EDR Workflows][Artifacts Regrouping] Re-organize all artifacts to a single page with separate tabs#257001

Merged
parkiino merged 65 commits intoelastic:mainfrom
parkiino:task/regroup-artifacts
Apr 6, 2026
Merged

[EDR Workflows][Artifacts Regrouping] Re-organize all artifacts to a single page with separate tabs#257001
parkiino merged 65 commits intoelastic:mainfrom
parkiino:task/regroup-artifacts

Conversation

@parkiino
Copy link
Copy Markdown
Contributor

@parkiino parkiino commented Mar 10, 2026

Summary

  • Updates the Endpoint Management navigation so that Endpoint Exceptions, Trusted Apps, Trusted Devices, Event Filters, Host Isolation Exceptions and Blocklist are under a single dynamic Artifacts link that points to the artifact tab that is visible to the user.
  • Creates a new artifacts page with individual artifacts as tabs within the page and an updated design where the "Add artifact" button and "3-dot menu" are in line with the search filters
  • The Artifacts link will be visible if the user has permissions for at least one of the individual artifact pages. The specific artifact tabs will only be visible if the user has the correct permissions for that artifact
  • All artifact urls will remain the same and the link to the artifact page is dynamically generated to the first available artifact page.
  • Unit tests

Screenshots

image image image image image image image image image image

@parkiino parkiino added ci:cloud-deploy Create or update a Cloud deployment release_note:skip Skip the PR/issue when compiling release notes Team:Defend Workflows “EDR Workflows” sub-team of Security Solution v9.4.0 labels Mar 20, 2026
@parkiino parkiino marked this pull request as ready for review March 20, 2026 18:03
@parkiino parkiino requested review from a team as code owners March 20, 2026 18:03
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/security-defend-workflows (Team:Defend Workflows)

@parkiino parkiino removed the request for review from ashokaditya March 20, 2026 18:06
@parkiino parkiino requested review from gergoabraham and szwarckonrad and removed request for paul-tavares March 20, 2026 18:08
@parkiino parkiino added the backport:skip This PR does not require backporting label Mar 20, 2026
Copy link
Copy Markdown
Contributor

@denar50 denar50 left a comment

Choose a reason for hiding this comment

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

Code review only. LGTM for files owned by the Detection Engine.

Copy link
Copy Markdown
Contributor

@gergoabraham gergoabraham left a comment

Choose a reason for hiding this comment

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

hey hey, nice work!

tested it out together with #257983, by merging them locally on top of each other, and happy to share, that, apart from a trivial merge conflict, they work together without any issue 👍

also tested your PR on its own, and works nice. 👏 I got one finding: if a user doesn't have any artifact access, the 'Artifacts' link is still shown, both in Classic and Security views

Screen.Recording.2026-04-02.at.13.43.20.mov

canReadTrustedDevices ||
canReadEventFilters ||
canReadHostIsolationExceptions ||
canReadBlocklist;
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.

+1 on making experimentalFeatures a required parameter, it doesn't seem like an optional thing for calculating the links.

core: CoreStart,
plugins: StartPlugins
plugins: StartPlugins,
params?: GetFilteredLinksParams
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 also should be mandatory. and experimentalFeatures up in line 56 as well.

nit: also, GetFilteredLinksParams doesn't seem to be very useful, maybe it'd be enough to simply have experimentalFeatures as the 3rd parameter here. same for getManagementFilteredLinks()

Comment on lines +249 to +254
export interface GetManagementFilteredLinksParams {
experimentalFeatures?: Pick<
ExperimentalFeatures,
'endpointExceptionsMovedUnderManagement' | 'trustedDevices'
>;
}
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: same as in my other comment above: this interface seems superfluous. it's perfectly fine to just pass the experimentalFeatures as the 3rd parameter, without wrapping it inside an interface, or without picking the 2 parameters we actually use.

@parkiino
Copy link
Copy Markdown
Contributor Author

parkiino commented Apr 2, 2026

@parkiino it would be nice to have a bit more details on the PR description. I've pulled the branch locally to test things but I'm failing to see a difference between the endpointExceptionsMovedUnderManagement feature flag on or off. I'm sure I'm doing something wrong but can't figure out why.

The reason I wanted to test things is because I'm not sure I understand why we're making a change to the useHiddenTimelineRoutes hook, so I wanted to make sure this was really necessary...

Thanks!

Hi @PhilippeOberti, the endpointExceptionsMovedUnderManagement feature flag controls the visibility of the Endpoint Exceptions tab, since it was previously in the Detections page and not in the endpoint management section. As long as you're using a superuser role or a role that has Endpoint Exceptions privileges + the experimental flag turned on, the endpoint exceptions tab should show on the new artifact page.

The useHiddenTimelineRoutes hook changes are separate from the flag. The change to the hook was necessary because we previously hid the timeline on the individual artifact pages, but now that we have combined all the artifacts onto one page with different tabs, we needed a way to still hide the timeline on those tabs.

Let me know if that makes sense or if there were any other questions.

Copy link
Copy Markdown
Contributor

@szwarckonrad szwarckonrad left a comment

Choose a reason for hiding this comment

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

Good job on this one, thanks for addressing all the review comments! The RBAC-aware artifact link resolution, telemetry preservation, and the cleanup of old container files all look solid. 👍

A few minor non-blocking observations for your consideration (can be addressed in a follow-up if you'd like):

  1. getActiveTabFromPathname hardcoded fallback — the function still falls back to AdministrationSubTab.trustedApps when the pathname doesn't match any tab. It would be slightly more defensive to fall back to visibleTabs[0] instead, so it always lands on a tab the user can actually see.

  2. getFirstAllowedArtifactPath final fallback — when no artifact is accessible, the function returns getTrustedAppsListPath(). This should be unreachable since canReadAnyArtifact would be false and the link excluded, but a small comment documenting that assumption would help future readers.

  3. Redundant condition in canReadAnyArtifact(showHostIsolationExceptions && canReadHostIsolationExceptions) — the && canReadHostIsolationExceptions is redundant since showHostIsolationExceptions already factors in canReadHostIsolationExceptions. Not wrong, just unnecessary.

@elasticmachine
Copy link
Copy Markdown
Contributor

elasticmachine commented Apr 6, 2026

💛 Build succeeded, but was flaky

Failed CI Steps

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
securitySolution 9344 9335 -9

Async chunks

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

id before after diff
securitySolution 11.7MB 11.7MB +227.0B
streamsApp 1.9MB 1.9MB +24.0B
total +251.0B

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
elasticAssistant 272.5KB 272.5KB +24.0B
securitySolution 129.1KB 129.1KB +6.0B
securitySolutionEss 36.6KB 36.7KB +160.0B
securitySolutionServerless 48.6KB 48.7KB +135.0B
total +325.0B
Unknown metric groups

async chunk count

id before after diff
securitySolution 96 97 +1

History

core: CoreStart,
plugins: StartPlugins
plugins: StartPlugins,
experimentalFeatures: ExperimentalFeatures
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.

probably want to coordinate with @ashokaditya , he's making very similar changes to this exact function for this same reason https://github.com/elastic/kibana/pull/260429/files#diff-d7b43749c559b9c4036c0e2cc6d922ea086a41ed1ea89097fb37b5372166b9e6R58 experimentalFeatures is an optional param in that branch, so whoever ends up merging 2nd should be careful.

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.

Sorry I just approved the PR! Thanks for pointing this out @kqualters-elastic I missed that

Copy link
Copy Markdown
Contributor

@PhilippeOberti PhilippeOberti left a comment

Choose a reason for hiding this comment

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

LGTM and thanks for the explanation on the Timeline hook!

@parkiino parkiino merged commit 9d02ae2 into elastic:main Apr 6, 2026
18 checks passed
szwarckonrad added a commit that referenced this pull request Apr 7, 2026
…#261845)

The artifacts regrouping PR (#257001) reorganized all endpoint artifacts
into a unified page with tabs. This changed the page structure so that
`header-page-title` now belongs to the unified "Artifacts" page and is
always present, regardless of whether individual tabs have entries.

Previously, `trusted_apps_list.ts` was skipped (flaky). Our PR #261180
unskipped it after fixing the underlying flakiness — but by that point
the regrouping had already landed, making the `header-page-title`
assertions invalid. The test immediately started failing on merge.

`artifact_entries_list.ts` has the same `header-page-title` assertions
for all artifact types (trusted apps, event filters, blocklist, host
isolation exceptions) — these would fail for the same reason once hit.

**Fix:** Replace `missingOrFail('header-page-title')` with
`existOrFail('*-emptyState')` in both test files. The empty state test
subject is the correct indicator that a tab has no entries.

Closes #261827
Closes #261829
Closes #261833
Closes #261849
Closes #261850
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:cloud-deploy Create or update a Cloud deployment release_note:skip Skip the PR/issue when compiling release notes Team:Defend Workflows “EDR Workflows” sub-team of Security Solution v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants